/// 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
/// after RABasic or RAGreedy, they should take advantage of LiveRegMatrix.
/// When these passes run, VirtRegMap contains legal physreg assignments for
/// all virtual registers.
+ ///
+ /// Note if the target overloads addRegAssignAndRewriteOptimized, this may not
+ /// be honored. This is also not generally used for the the fast variant,
+ /// where the allocation and rewriting are done in one pass.
virtual bool addPreRewrite() {
return false;
}
/// 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
// Run register allocation and passes that are tightly coupled with it,
// including phi elimination and scheduling.
if (getOptimizeRegAlloc())
- addOptimizedRegAlloc(createRegAllocPass(true));
- else {
- if (RegAlloc != &useDefaultRegisterAllocator &&
- RegAlloc != &createFastRegisterAllocator)
- report_fatal_error("Must use fast (default) register allocator for unoptimized regalloc.");
- addFastRegAlloc(createRegAllocPass(false));
- }
+ addOptimizedRegAlloc();
+ else
+ addFastRegAlloc();
// Run post-ra passes.
addPostRegAlloc();
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 {
/// 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);
// 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);
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;
addPass(createSIWholeQuadModePass());
}
-void GCNPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) {
+void GCNPassConfig::addFastRegAlloc() {
// FIXME: We have to disable the verifier here because of PHIElimination +
// TwoAddressInstructions disabling it.
// 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);
// machine-level CFG, but before register allocation.
insertPass(&SILowerControlFlowID, &SIFixWWMLivenessID, false);
- TargetPassConfig::addOptimizedRegAlloc(RegAllocPass);
+ TargetPassConfig::addOptimizedRegAlloc();
}
void GCNPassConfig::addPostRegAlloc() {
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
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);
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