diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 218 |
1 files changed, 197 insertions, 21 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp index 59dac5c7b57d..3abdb6003659 100644 --- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -27,6 +27,7 @@ #include "llvm/CodeGen/MIRParser/MIParser.h" #include "llvm/CodeGen/MIRYamlMapping.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/RegAllocRegistry.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/InitializePasses.h" @@ -34,6 +35,7 @@ #include "llvm/Support/FormattedStream.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/Scalar.h" #include <optional> using namespace llvm; @@ -71,21 +73,55 @@ static cl::opt<bool> EnableRISCVCopyPropagation( cl::desc("Enable the copy propagation with RISC-V copy instr"), cl::init(true), cl::Hidden); +static cl::opt<bool> EnableRISCVDeadRegisterElimination( + "riscv-enable-dead-defs", cl::Hidden, + cl::desc("Enable the pass that removes dead" + " definitons and replaces stores to" + " them with stores to x0"), + cl::init(true)); + +static cl::opt<bool> + EnableSinkFold("riscv-enable-sink-fold", + cl::desc("Enable sinking and folding of instruction copies"), + cl::init(false), cl::Hidden); + +static cl::opt<bool> + EnableLoopDataPrefetch("riscv-enable-loop-data-prefetch", cl::Hidden, + cl::desc("Enable the loop data prefetch pass"), + cl::init(true)); + +static cl::opt<bool> + EnableSplitRegAlloc("riscv-split-regalloc", cl::Hidden, + cl::desc("Enable Split RegisterAlloc for RVV"), + cl::init(true)); + +static cl::opt<bool> EnableMISchedLoadClustering( + "riscv-misched-load-clustering", cl::Hidden, + cl::desc("Enable load clustering in the machine scheduler"), + cl::init(false)); + extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() { RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target()); RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target()); auto *PR = PassRegistry::getPassRegistry(); initializeGlobalISel(*PR); + initializeRISCVO0PreLegalizerCombinerPass(*PR); + initializeRISCVPreLegalizerCombinerPass(*PR); + initializeRISCVPostLegalizerCombinerPass(*PR); initializeKCFIPass(*PR); + initializeRISCVDeadRegisterDefinitionsPass(*PR); initializeRISCVMakeCompressibleOptPass(*PR); initializeRISCVGatherScatterLoweringPass(*PR); initializeRISCVCodeGenPreparePass(*PR); + initializeRISCVPostRAExpandPseudoPass(*PR); initializeRISCVMergeBaseOffsetOptPass(*PR); initializeRISCVOptWInstrsPass(*PR); initializeRISCVPreRAExpandPseudoPass(*PR); initializeRISCVExpandPseudoPass(*PR); + initializeRISCVFoldMasksPass(*PR); initializeRISCVInsertVSETVLIPass(*PR); initializeRISCVInsertReadWriteCSRPass(*PR); + initializeRISCVInsertWriteVXRMPass(*PR); initializeRISCVDAGToDAGISelPass(*PR); initializeRISCVInitUndefPass(*PR); initializeRISCVMoveMergePass(*PR); @@ -109,7 +145,7 @@ RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT, const TargetOptions &Options, std::optional<Reloc::Model> RM, std::optional<CodeModel::Model> CM, - CodeGenOpt::Level OL, bool JIT) + CodeGenOptLevel OL, bool JIT) : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, getEffectiveRelocModel(TT, RM), getEffectiveCodeModel(CM, CodeModel::Small), OL), @@ -177,13 +213,8 @@ RISCVTargetMachine::getSubtargetImpl(const Function &F) const { llvm::bit_floor((RVVBitsMax < 64 || RVVBitsMax > 65536) ? 0 : RVVBitsMax); SmallString<512> Key; - Key += "RVVMin"; - Key += std::to_string(RVVBitsMin); - Key += "RVVMax"; - Key += std::to_string(RVVBitsMax); - Key += CPU; - Key += TuneCPU; - Key += FS; + raw_svector_ostream(Key) << "RVVMin" << RVVBitsMin << "RVVMax" << RVVBitsMax + << CPU << TuneCPU << FS; auto &I = SubtargetMap[Key]; if (!I) { // This needs to be done before we create a new subtarget since any @@ -228,10 +259,84 @@ bool RISCVTargetMachine::isNoopAddrSpaceCast(unsigned SrcAS, } namespace { + +class RVVRegisterRegAlloc : public RegisterRegAllocBase<RVVRegisterRegAlloc> { +public: + RVVRegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C) + : RegisterRegAllocBase(N, D, C) {} +}; + +static bool onlyAllocateRVVReg(const TargetRegisterInfo &TRI, + const TargetRegisterClass &RC) { + return RISCV::VRRegClass.hasSubClassEq(&RC) || + RISCV::VRM2RegClass.hasSubClassEq(&RC) || + RISCV::VRM4RegClass.hasSubClassEq(&RC) || + RISCV::VRM8RegClass.hasSubClassEq(&RC) || + RISCV::VRN2M1RegClass.hasSubClassEq(&RC) || + RISCV::VRN2M2RegClass.hasSubClassEq(&RC) || + RISCV::VRN2M4RegClass.hasSubClassEq(&RC) || + RISCV::VRN3M1RegClass.hasSubClassEq(&RC) || + RISCV::VRN3M2RegClass.hasSubClassEq(&RC) || + RISCV::VRN4M1RegClass.hasSubClassEq(&RC) || + RISCV::VRN4M2RegClass.hasSubClassEq(&RC) || + RISCV::VRN5M1RegClass.hasSubClassEq(&RC) || + RISCV::VRN6M1RegClass.hasSubClassEq(&RC) || + RISCV::VRN7M1RegClass.hasSubClassEq(&RC) || + RISCV::VRN8M1RegClass.hasSubClassEq(&RC); +} + +static FunctionPass *useDefaultRegisterAllocator() { return nullptr; } + +static llvm::once_flag InitializeDefaultRVVRegisterAllocatorFlag; + +/// -riscv-rvv-regalloc=<fast|basic|greedy> command line option. +/// This option could designate the rvv register allocator only. +/// For example: -riscv-rvv-regalloc=basic +static cl::opt<RVVRegisterRegAlloc::FunctionPassCtor, false, + RegisterPassParser<RVVRegisterRegAlloc>> + RVVRegAlloc("riscv-rvv-regalloc", cl::Hidden, + cl::init(&useDefaultRegisterAllocator), + cl::desc("Register allocator to use for RVV register.")); + +static void initializeDefaultRVVRegisterAllocatorOnce() { + RegisterRegAlloc::FunctionPassCtor Ctor = RVVRegisterRegAlloc::getDefault(); + + if (!Ctor) { + Ctor = RVVRegAlloc; + RVVRegisterRegAlloc::setDefault(RVVRegAlloc); + } +} + +static FunctionPass *createBasicRVVRegisterAllocator() { + return createBasicRegisterAllocator(onlyAllocateRVVReg); +} + +static FunctionPass *createGreedyRVVRegisterAllocator() { + return createGreedyRegisterAllocator(onlyAllocateRVVReg); +} + +static FunctionPass *createFastRVVRegisterAllocator() { + return createFastRegisterAllocator(onlyAllocateRVVReg, false); +} + +static RVVRegisterRegAlloc basicRegAllocRVVReg("basic", + "basic register allocator", + createBasicRVVRegisterAllocator); +static RVVRegisterRegAlloc + greedyRegAllocRVVReg("greedy", "greedy register allocator", + createGreedyRVVRegisterAllocator); + +static RVVRegisterRegAlloc fastRegAllocRVVReg("fast", "fast register allocator", + createFastRVVRegisterAllocator); + class RISCVPassConfig : public TargetPassConfig { public: RISCVPassConfig(RISCVTargetMachine &TM, PassManagerBase &PM) - : TargetPassConfig(TM, PM) {} + : TargetPassConfig(TM, PM) { + if (TM.getOptLevel() != CodeGenOptLevel::None) + substitutePass(&PostRASchedulerID, &PostMachineSchedulerID); + setEnableSinkAndFold(EnableSinkFold); + } RISCVTargetMachine &getRISCVTargetMachine() const { return getTM<RISCVTargetMachine>(); @@ -240,12 +345,16 @@ public: ScheduleDAGInstrs * createMachineScheduler(MachineSchedContext *C) const override { const RISCVSubtarget &ST = C->MF->getSubtarget<RISCVSubtarget>(); + ScheduleDAGMILive *DAG = nullptr; + if (EnableMISchedLoadClustering) { + DAG = createGenericSchedLive(C); + DAG->addMutation(createLoadClusterDAGMutation(DAG->TII, DAG->TRI)); + } if (ST.hasMacroFusion()) { - ScheduleDAGMILive *DAG = createGenericSchedLive(C); + DAG = DAG ? DAG : createGenericSchedLive(C); DAG->addMutation(createRISCVMacroFusionDAGMutation()); - return DAG; } - return nullptr; + return DAG; } ScheduleDAGInstrs * @@ -263,16 +372,22 @@ public: bool addPreISel() override; bool addInstSelector() override; bool addIRTranslator() override; + void addPreLegalizeMachineIR() override; bool addLegalizeMachineIR() override; + void addPreRegBankSelect() override; bool addRegBankSelect() override; bool addGlobalInstructionSelect() override; void addPreEmitPass() override; void addPreEmitPass2() override; void addPreSched2() override; void addMachineSSAOptimization() override; + FunctionPass *createRVVRegAllocPass(bool Optimized); + bool addRegAssignAndRewriteFast() override; + bool addRegAssignAndRewriteOptimized() override; void addPreRegAlloc() override; void addPostRegAlloc() override; void addOptimizedRegAlloc() override; + void addFastRegAlloc() override; }; } // namespace @@ -280,10 +395,42 @@ TargetPassConfig *RISCVTargetMachine::createPassConfig(PassManagerBase &PM) { return new RISCVPassConfig(*this, PM); } +FunctionPass *RISCVPassConfig::createRVVRegAllocPass(bool Optimized) { + // Initialize the global default. + llvm::call_once(InitializeDefaultRVVRegisterAllocatorFlag, + initializeDefaultRVVRegisterAllocatorOnce); + + RegisterRegAlloc::FunctionPassCtor Ctor = RVVRegisterRegAlloc::getDefault(); + if (Ctor != useDefaultRegisterAllocator) + return Ctor(); + + if (Optimized) + return createGreedyRVVRegisterAllocator(); + + return createFastRVVRegisterAllocator(); +} + +bool RISCVPassConfig::addRegAssignAndRewriteFast() { + if (EnableSplitRegAlloc) + addPass(createRVVRegAllocPass(false)); + return TargetPassConfig::addRegAssignAndRewriteFast(); +} + +bool RISCVPassConfig::addRegAssignAndRewriteOptimized() { + if (EnableSplitRegAlloc) { + addPass(createRVVRegAllocPass(true)); + addPass(createVirtRegRewriter(false)); + } + return TargetPassConfig::addRegAssignAndRewriteOptimized(); +} + void RISCVPassConfig::addIRPasses() { addPass(createAtomicExpandPass()); - if (getOptLevel() != CodeGenOpt::None) { + if (getOptLevel() != CodeGenOptLevel::None) { + if (EnableLoopDataPrefetch) + addPass(createLoopDataPrefetchPass()); + addPass(createRISCVGatherScatterLoweringPass()); addPass(createInterleavedAccessPass()); addPass(createRISCVCodeGenPreparePass()); @@ -293,7 +440,7 @@ void RISCVPassConfig::addIRPasses() { } bool RISCVPassConfig::addPreISel() { - if (TM->getOptLevel() != CodeGenOpt::None) { + if (TM->getOptLevel() != CodeGenOptLevel::None) { // Add a barrier before instruction selection so that we will not get // deleted block address after enabling default outlining. See D99707 for // more details. @@ -320,11 +467,24 @@ bool RISCVPassConfig::addIRTranslator() { return false; } +void RISCVPassConfig::addPreLegalizeMachineIR() { + if (getOptLevel() == CodeGenOptLevel::None) { + addPass(createRISCVO0PreLegalizerCombiner()); + } else { + addPass(createRISCVPreLegalizerCombiner()); + } +} + bool RISCVPassConfig::addLegalizeMachineIR() { addPass(new Legalizer()); return false; } +void RISCVPassConfig::addPreRegBankSelect() { + if (getOptLevel() != CodeGenOptLevel::None) + addPass(createRISCVPostLegalizerCombiner()); +} + bool RISCVPassConfig::addRegBankSelect() { addPass(new RegBankSelect()); return false; @@ -336,6 +496,8 @@ bool RISCVPassConfig::addGlobalInstructionSelect() { } void RISCVPassConfig::addPreSched2() { + addPass(createRISCVPostRAExpandPseudoPass()); + // Emit KCFI checks for indirect calls. addPass(createKCFIPass()); } @@ -349,12 +511,13 @@ void RISCVPassConfig::addPreEmitPass() { // propagation after the machine outliner (which runs after addPreEmitPass) // currently leads to incorrect code-gen, where copies to registers within // outlined functions are removed erroneously. - if (TM->getOptLevel() >= CodeGenOpt::Default && EnableRISCVCopyPropagation) + if (TM->getOptLevel() >= CodeGenOptLevel::Default && + EnableRISCVCopyPropagation) addPass(createMachineCopyPropagationPass(true)); } void RISCVPassConfig::addPreEmitPass2() { - if (TM->getOptLevel() != CodeGenOpt::None) { + if (TM->getOptLevel() != CodeGenOptLevel::None) { addPass(createRISCVMoveMergePass()); // Schedule PushPop Optimization before expansion of Pseudo instruction, // ensuring return instruction is detected correctly. @@ -374,32 +537,45 @@ void RISCVPassConfig::addPreEmitPass2() { } void RISCVPassConfig::addMachineSSAOptimization() { + addPass(createRISCVFoldMasksPass()); + TargetPassConfig::addMachineSSAOptimization(); + if (EnableMachineCombiner) addPass(&MachineCombinerID); - if (TM->getTargetTriple().getArch() == Triple::riscv64) { + if (TM->getTargetTriple().isRISCV64()) { addPass(createRISCVOptWInstrsPass()); } } void RISCVPassConfig::addPreRegAlloc() { addPass(createRISCVPreRAExpandPseudoPass()); - if (TM->getOptLevel() != CodeGenOpt::None) + if (TM->getOptLevel() != CodeGenOptLevel::None) addPass(createRISCVMergeBaseOffsetOptPass()); addPass(createRISCVInsertVSETVLIPass()); + if (TM->getOptLevel() != CodeGenOptLevel::None && + EnableRISCVDeadRegisterElimination) + addPass(createRISCVDeadRegisterDefinitionsPass()); addPass(createRISCVInsertReadWriteCSRPass()); + addPass(createRISCVInsertWriteVXRMPass()); } void RISCVPassConfig::addOptimizedRegAlloc() { - if (getOptimizeRegAlloc()) - insertPass(&DetectDeadLanesID, &RISCVInitUndefID); + insertPass(&DetectDeadLanesID, &RISCVInitUndefID); TargetPassConfig::addOptimizedRegAlloc(); } +void RISCVPassConfig::addFastRegAlloc() { + addPass(createRISCVInitUndefPass()); + TargetPassConfig::addFastRegAlloc(); +} + + void RISCVPassConfig::addPostRegAlloc() { - if (TM->getOptLevel() != CodeGenOpt::None && EnableRedundantCopyElimination) + if (TM->getOptLevel() != CodeGenOptLevel::None && + EnableRedundantCopyElimination) addPass(createRISCVRedundantCopyEliminationPass()); } |
