Index: include/llvm/CodeGen/TargetPassConfig.h =================================================================== --- include/llvm/CodeGen/TargetPassConfig.h +++ include/llvm/CodeGen/TargetPassConfig.h @@ -360,11 +360,11 @@ /// addFastRegAlloc - Add the minimum set of target-independent passes that /// are required for fast register allocation. - virtual void addFastRegAlloc(FunctionPass *RegAllocPass); + virtual void addFastRegAlloc(); /// addOptimizedRegAlloc - Add passes related to register allocation. /// LLVMTargetMachine provides standard regalloc passes for most targets. - virtual void addOptimizedRegAlloc(FunctionPass *RegAllocPass); + virtual void addOptimizedRegAlloc(); /// addPreRewrite - Add passes to the optimized register allocation pipeline /// after register allocation is complete, but before virtual registers are @@ -431,7 +431,12 @@ /// addMachinePasses helper to create the target-selected or overriden /// regalloc pass. - FunctionPass *createRegAllocPass(bool Optimized); + virtual FunctionPass *createRegAllocPass(bool Optimized); + + /// Add core register alloator passes which do the actual register assignment + /// and rewriting. \returns true if any passes were added. + virtual bool addRegAssignmentFast(); + virtual bool addRegAssignmentOptimized(); }; } // end namespace llvm Index: lib/CodeGen/TargetPassConfig.cpp =================================================================== --- lib/CodeGen/TargetPassConfig.cpp +++ lib/CodeGen/TargetPassConfig.cpp @@ -887,12 +887,9 @@ // Run register allocation and passes that are tightly coupled with it, // including phi elimination and scheduling. if (getOptimizeRegAlloc()) - addOptimizedRegAlloc(createRegAllocPass(true)); + addOptimizedRegAlloc(); else { - if (RegAlloc != &useDefaultRegisterAllocator && - RegAlloc != &createFastRegisterAllocator) - report_fatal_error("Must use fast (default) register allocator for unoptimized regalloc."); - addFastRegAlloc(createRegAllocPass(false)); + addFastRegAlloc(); } // Run post-ra passes. @@ -1083,6 +1080,33 @@ return createTargetRegisterAllocator(Optimized); } +bool TargetPassConfig::addRegAssignmentFast() { + if (RegAlloc != &useDefaultRegisterAllocator && + RegAlloc != &createFastRegisterAllocator) + report_fatal_error("Must use fast (default) register allocator for unoptimized regalloc."); + + addPass(createRegAllocPass(false)); + return true; +} + +bool TargetPassConfig::addRegAssignmentOptimized() { + // Add the selected register allocation pass. + addPass(createRegAllocPass(true)); + + // Allow targets to change the register assignments before rewriting. + addPreRewrite(); + + // Finally rewrite virtual registers. + addPass(&VirtRegRewriterID); + // Perform stack slot coloring and post-ra machine LICM. + // + // FIXME: Re-enable coloring with register when it's capable of adding + // kill markers. + addPass(&StackSlotColoringID); + + return true; +} + /// Return true if the default global register allocator is in use and /// has not be overriden on the command line with '-regalloc=...' bool TargetPassConfig::usingDefaultRegAlloc() const { @@ -1091,18 +1115,17 @@ /// Add the minimum set of target-independent passes that are required for /// register allocation. No coalescing or scheduling. -void TargetPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) { +void TargetPassConfig::addFastRegAlloc() { addPass(&PHIEliminationID, false); addPass(&TwoAddressInstructionPassID, false); - if (RegAllocPass) - addPass(RegAllocPass); + addRegAssignmentFast(); } /// Add standard target-independent passes that are tightly coupled with /// optimized register allocation, including coalescing, machine instruction /// scheduling, and register allocation itself. -void TargetPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) { +void TargetPassConfig::addOptimizedRegAlloc() { addPass(&DetectDeadLanesID, false); addPass(&ProcessImplicitDefsID, false); @@ -1134,22 +1157,7 @@ // PreRA instruction scheduling. addPass(&MachineSchedulerID); - if (RegAllocPass) { - // Add the selected register allocation pass. - addPass(RegAllocPass); - - // Allow targets to change the register assignments before rewriting. - addPreRewrite(); - - // Finally rewrite virtual registers. - addPass(&VirtRegRewriterID); - - // Perform stack slot coloring and post-ra machine LICM. - // - // FIXME: Re-enable coloring with register when it's capable of adding - // kill markers. - addPass(&StackSlotColoringID); - + if (addRegAssignmentOptimized()) { // Copy propagate to forward register uses and try to eliminate COPYs that // were not coalesced. addPass(&MachineCopyPropagationID); Index: lib/Target/AMDGPU/AMDGPUTargetMachine.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -570,8 +570,8 @@ bool addLegalizeMachineIR() override; bool addRegBankSelect() override; bool addGlobalInstructionSelect() override; - void addFastRegAlloc(FunctionPass *RegAllocPass) override; - void addOptimizedRegAlloc(FunctionPass *RegAllocPass) override; + void addFastRegAlloc() override; + void addOptimizedRegAlloc() override; void addPreRegAlloc() override; void addPostRegAlloc() override; void addPreSched2() override; @@ -853,7 +853,7 @@ addPass(createSIWholeQuadModePass()); } -void GCNPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) { +void GCNPassConfig::addFastRegAlloc() { // FIXME: We have to disable the verifier here because of PHIElimination + // TwoAddressInstructions disabling it. @@ -866,10 +866,10 @@ // machine-level CFG, but before register allocation. insertPass(&SILowerControlFlowID, &SIFixWWMLivenessID, false); - TargetPassConfig::addFastRegAlloc(RegAllocPass); + TargetPassConfig::addFastRegAlloc(); } -void GCNPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) { +void GCNPassConfig::addOptimizedRegAlloc() { insertPass(&MachineSchedulerID, &SIOptimizeExecMaskingPreRAID); insertPass(&SIOptimizeExecMaskingPreRAID, &SIFormMemoryClausesID); @@ -883,7 +883,7 @@ // machine-level CFG, but before register allocation. insertPass(&SILowerControlFlowID, &SIFixWWMLivenessID, false); - TargetPassConfig::addOptimizedRegAlloc(RegAllocPass); + TargetPassConfig::addOptimizedRegAlloc(); } void GCNPassConfig::addPostRegAlloc() { Index: lib/Target/NVPTX/NVPTXTargetMachine.cpp =================================================================== --- lib/Target/NVPTX/NVPTXTargetMachine.cpp +++ lib/Target/NVPTX/NVPTXTargetMachine.cpp @@ -170,8 +170,16 @@ void addMachineSSAOptimization() override; FunctionPass *createTargetRegisterAllocator(bool) override; - void addFastRegAlloc(FunctionPass *RegAllocPass) override; - void addOptimizedRegAlloc(FunctionPass *RegAllocPass) override; + void addFastRegAlloc() override; + void addOptimizedRegAlloc() override; + + bool addRegAssignmentFast() override { + llvm_unreachable("should not be used"); + } + + bool addRegAssignmentOptimized() override { + llvm_unreachable("should not be used"); + } private: // If the opt level is aggressive, add GVN; otherwise, add EarlyCSE. This @@ -321,15 +329,12 @@ return nullptr; // No reg alloc } -void NVPTXPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) { - assert(!RegAllocPass && "NVPTX uses no regalloc!"); +void NVPTXPassConfig::addFastRegAlloc() { addPass(&PHIEliminationID); addPass(&TwoAddressInstructionPassID); } -void NVPTXPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) { - assert(!RegAllocPass && "NVPTX uses no regalloc!"); - +void NVPTXPassConfig::addOptimizedRegAlloc() { addPass(&ProcessImplicitDefsID); addPass(&LiveVariablesID); addPass(&MachineLoopInfoID); Index: lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -181,6 +181,16 @@ void addPostRegAlloc() override; bool addGCPasses() override { return false; } void addPreEmitPass() override; + + // No reg alloc + bool addRegAssignmentFast() override { + return false; + } + + // No reg alloc + bool addRegAssignmentOptimized() override { + return false; + } }; } // end anonymous namespace