diff --git a/README.md b/README.md index 64ea83a37c6f8..793180dc80b7b 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,30 @@ void __builtin_ssr_read(uint32_t DM, uint32_t dim, void* data); */ void __builtin_ssr_write(uint32_t DM, uint32_t dim, void* data); +/** + * @brief Start an SSR read transfer. `DM` and `dim` must be constant. This method + * lowers to a single `scfgwi` instruction as opposed to the non-immediate version which + * does address calculation first. + * @details Bound and stride can be configured using the respective methods + * + * @param DM data mover ID + * @param dim Number of dimensions minus one + * @param data pointer to data + */ +void __builtin_ssr_read_imm(uint32_t DM, uint32_t dim, void* data); + +/** + * @brief Start an SSR write transfer. `DM` and `dim` must be constant. This method + * lowers to a single `scfgwi` instruction as opposed to the non-immediate version which + * does address calculation first. + * @details Bound and stride can be configured using the respective methods + * + * @param DM data mover ID + * @param dim Number of dimensions minus one + * @param data pointer to data + */ +void __builtin_ssr_write_imm(uint32_t DM, uint32_t dim, void* data); + /** * @brief Configure repetition value * @details A value of 0 loads each datum once diff --git a/clang/include/clang/Basic/BuiltinsRISCV.def b/clang/include/clang/Basic/BuiltinsRISCV.def index dd4681a0e4156..9f4e00599d9ea 100644 --- a/clang/include/clang/Basic/BuiltinsRISCV.def +++ b/clang/include/clang/Basic/BuiltinsRISCV.def @@ -30,6 +30,8 @@ SSR_BUILTIN(setup_1d_r, "vUiULiULiULiv*", "n", "xssr") SSR_BUILTIN(setup_1d_w, "vUiULiULiULiv*", "n", "xssr") SSR_BUILTIN(read, "vUiUiv*", "n", "xssr") SSR_BUILTIN(write, "vUiUiv*", "n", "xssr") +SSR_BUILTIN(read_imm, "vUiUiv*", "n", "xssr") +SSR_BUILTIN(write_imm, "vUiUiv*", "n", "xssr") SSR_BUILTIN(setup_bound_stride_1d, "vUiULiULi", "n", "xssr") SSR_BUILTIN(setup_bound_stride_2d, "vUiULiULi", "n", "xssr") SSR_BUILTIN(setup_bound_stride_3d, "vUiULiULi", "n", "xssr") diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index 307d5b9faec14..835a535a9be48 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -1418,6 +1418,20 @@ let TargetPrefix = "riscv" in { [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [IntrHasSideEffects]>, RISCVSSRIntrinsic; + def int_riscv_ssr_read_imm + : GCCBuiltin<"__builtin_ssr_read_imm">, + /* RetTypes, ParamTypes, Properties */ + Intrinsic<[], + [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], + [IntrHasSideEffects, ImmArg>, ImmArg>]>, + RISCVSSRIntrinsic; + def int_riscv_ssr_write_imm + : GCCBuiltin<"__builtin_ssr_write_imm">, + /* RetTypes, ParamTypes, Properties */ + Intrinsic<[], + [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], + [IntrHasSideEffects, ImmArg>, ImmArg>]>, + RISCVSSRIntrinsic; // The `Throws` attribute ensures that the push/pop don't get removed from loops // by the LICM pass diff --git a/llvm/lib/Target/RISCV/RISCVExpandSSRInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandSSRInsts.cpp index 504b6b36d1813..a90f199b6b1d6 100644 --- a/llvm/lib/Target/RISCV/RISCVExpandSSRInsts.cpp +++ b/llvm/lib/Target/RISCV/RISCVExpandSSRInsts.cpp @@ -108,6 +108,8 @@ class RISCVExpandSSR : public MachineFunctionPass { MachineBasicBlock::iterator MBBI); bool expandSSR_ReadWrite(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); + bool expandSSR_ReadWriteImm(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI); bool expandSSR_BoundStride(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); bool expandSSR_EnDis(MachineBasicBlock &MBB, @@ -192,6 +194,9 @@ bool RISCVExpandSSR::expandMI(MachineBasicBlock &MBB, case RISCV::PseudoSSRRead: case RISCV::PseudoSSRWrite: return expandSSR_ReadWrite(MBB, MBBI); + case RISCV::PseudoSSRReadImm: + case RISCV::PseudoSSRWriteImm: + return expandSSR_ReadWriteImm(MBB, MBBI); case RISCV::PseudoSSRSetupBoundStride_1D: case RISCV::PseudoSSRSetupBoundStride_2D: case RISCV::PseudoSSRSetupBoundStride_3D: @@ -325,6 +330,25 @@ bool RISCVExpandSSR::expandSSR_ReadWrite(MachineBasicBlock &MBB, return true; } +bool RISCVExpandSSR::expandSSR_ReadWriteImm(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI) { + DebugLoc DL = MBBI->getDebugLoc(); + + bool read = MBBI->getOpcode() == RISCV::PseudoSSRReadImm; + + // select streamer based on first argument + int dm_off = (int)MBBI->getOperand(0).getImm(); + int dim = (int)MBBI->getOperand(1).getImm(); + int ssr_reg = (((read ? 0x18 : 0x1c) + dim) << 5) + dm_off; + Register PtrReg = MBBI->getOperand(2).getReg(); + + // set read/write pointer + BuildMI(MBB, MBBI, DL, TII->get(RISCV::SCFGWI)).addReg(PtrReg).addImm(ssr_reg); + + MBBI->eraseFromParent(); // The pseudo instruction is gone now. + return true; +} + bool RISCVExpandSSR::expandSSR_SetupRep(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) { DebugLoc DL = MBBI->getDebugLoc(); diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXssr.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXssr.td index 99d948e9ae4ae..67f38e03e1fc0 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXssr.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXssr.td @@ -121,6 +121,14 @@ class SPseudoRW: let usesCustomInserter = 0; } +class SPseudoRWImm: + Pseudo<(outs), (ins uimm5:$ssr, uimm5:$dim, GPR:$ptr),[]> { + let mayLoad = 1; + let mayStore = 1; + let hasSideEffects = 1; + let usesCustomInserter = 0; +} + class SPseudoEnDis: Pseudo<(outs), (ins),[]> { let mayLoad = 1; @@ -149,6 +157,8 @@ let Predicates = [HasExtXssr] in { def PseudoSSRDisable : SPseudoEnDis; def PseudoSSRRead : SPseudoRW; def PseudoSSRWrite : SPseudoRW; + def PseudoSSRReadImm : SPseudoRWImm; + def PseudoSSRWriteImm : SPseudoRWImm; def PseudoSSRSetupRepetition : SPseudoSetupRepetition; def PseudoSSRBarrier : SPseudoBarrier; @@ -171,6 +181,10 @@ let Predicates = [HasExtXssr] in { (PseudoSSRRead GPR:$ssr, GPR:$dim, GPR:$ptr)>; def : Pat<(int_riscv_ssr_write GPR:$ssr, GPR:$dim, GPR:$ptr), (PseudoSSRWrite GPR:$ssr, GPR:$dim, GPR:$ptr)>; + def : Pat<(int_riscv_ssr_read_imm timm:$ssr, timm:$dim, GPR:$ptr), + (PseudoSSRReadImm timm:$ssr, timm:$dim, GPR:$ptr)>; + def : Pat<(int_riscv_ssr_write_imm timm:$ssr, timm:$dim, GPR:$ptr), + (PseudoSSRWriteImm timm:$ssr, timm:$dim, GPR:$ptr)>; def : Pat<(int_riscv_ssr_push timm:$ssr, FPR64:$val), (PseudoSSRPush timm:$ssr, FPR64:$val)>; diff --git a/llvm/test/CodeGen/RISCV/ssr-pseudo-instructions.mir b/llvm/test/CodeGen/RISCV/ssr-pseudo-instructions.mir index a1077836e9453..8d11372bb7c04 100644 --- a/llvm/test/CodeGen/RISCV/ssr-pseudo-instructions.mir +++ b/llvm/test/CodeGen/RISCV/ssr-pseudo-instructions.mir @@ -9,6 +9,7 @@ define i32 @outline_4(i32 %a, i32 %b) { ret i32 0 } define i32 @outline_5(i32 %a, i32 %b) { ret i32 0 } define i32 @outline_6(i32 %a, i32 %b) { ret i32 0 } + define i32 @outline_7(i32 %a, i32 %b) { ret i32 0 } ... --- name: outline_0 @@ -126,3 +127,15 @@ body: | PseudoRET ... +--- +name: outline_7 +tracksRegLiveness: true +body: | + bb.0: + liveins: $x1, $x2 + ; RV32-SSR: SCFGWI $x1, 800 + ; RV32-SSR-NEXT: SCFGWI $x2, 961 + PseudoSSRReadImm 0, 1, $x1 /* streamer, dim, ptr */ + PseudoSSRWriteImm 1, 2, $x2 /* streamer, dim, ptr */ + PseudoRET +...