Improve TargetPassConfig. No intended functionality.

Split CodeGen into stages.
Distinguish between optimization and correctness.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150122 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Trick 2012-02-09 00:40:55 +00:00
parent 78b2961f4d
commit f7b96311d2
2 changed files with 162 additions and 98 deletions

View File

@ -111,6 +111,10 @@ protected:
return true;
}
/// addMachineSSAOptimization - Add standard passes that optimize machine
/// instructions in SSA form.
virtual void addMachineSSAOptimization();
/// addPreRegAlloc - This method may be implemented by targets that want to
/// run passes immediately before register allocation. This should return
/// true if -print-machineinstrs should print after these passes.
@ -118,6 +122,9 @@ protected:
return false;
}
// addRegAlloc - Add standard passes related to register allocation.
virtual void addRegAlloc();
/// addPostRegAlloc - This method may be implemented by targets that want
/// to run passes after register allocation but before prolog-epilog
/// insertion. This should return true if -print-machineinstrs should print
@ -126,6 +133,9 @@ protected:
return false;
}
/// Add passes that optimize machine instructions after register allocation.
virtual void addMachineLateOptimization();
/// addPreSched2 - This method may be implemented by targets that want to
/// run passes after prolog-epilog insertion and before the second instruction
/// scheduling pass. This should return true if -print-machineinstrs should
@ -134,6 +144,9 @@ protected:
return false;
}
/// Add standard basic block placement passes.
virtual void addBlockPlacement();
/// addPreEmitPass - This pass may be implemented by targets that want to run
/// passes immediately before machine code is emitted. This should return
/// true if -print-machineinstrs should print out the code after the passes.

View File

@ -184,6 +184,24 @@ void TargetPassConfig::addISelPrepare() {
PM.add(createVerifierPass());
}
/// Add the complete set of target-independent postISel code generator passes.
///
/// This can be read as the standard order of major LLVM CodeGen stages. Stages
/// with nontrivial configuration or multiple passes are broken out below in
/// add%Stage routines.
///
/// Any TargetPassConfig::addXX routine may be overriden by the Target. The
/// addPre/Post methods with empty header implementations allow injecting
/// target-specific fixups just before or after major stages. Additionally,
/// targets have the flexibility to change pass order within a stage by
/// overriding default implementation of add%Stage routines below. Each
/// technique has maintainability tradeoffs because alternate pass orders are
/// not well supported. addPre/Post works better if the target pass is easily
/// tied to a common pass. But if it has subtle dependencies on multiple passes,
/// overriding the stage instead.
///
/// TODO: We could use a single addPre/Post(ID) hook to allow pass injection
/// before/after any target-independent pass. But it's currently overkill.
void TargetPassConfig::addMachinePasses() {
// Print the instruction selected machine code...
printAndVerify("After Instruction Selection");
@ -191,22 +209,79 @@ void TargetPassConfig::addMachinePasses() {
// Expand pseudo-instructions emitted by ISel.
addPass(ExpandISelPseudosID);
// Add passes that optimize machine instructions in SSA form.
if (getOptLevel() != CodeGenOpt::None) {
addMachineSSAOptimization();
}
else {
// If the target requests it, assign local variables to stack slots relative
// to one another and simplify frame index references where possible.
addPass(LocalStackSlotAllocationID);
}
// Run pre-ra passes.
if (addPreRegAlloc())
printAndVerify("After PreRegAlloc passes");
// Run register allocation and passes that are tightly coupled with it,
// including phi elimination and scheduling.
addRegAlloc();
// Run post-ra passes.
if (addPostRegAlloc())
printAndVerify("After PostRegAlloc passes");
// Insert prolog/epilog code. Eliminate abstract frame index references...
addPass(PrologEpilogCodeInserterID);
printAndVerify("After PrologEpilogCodeInserter");
/// Add passes that optimize machine instructions after register allocation.
if (getOptLevel() != CodeGenOpt::None)
addMachineLateOptimization();
// Expand pseudo instructions before second scheduling pass.
addPass(ExpandPostRAPseudosID);
printNoVerify("After ExpandPostRAPseudos");
// Run pre-sched2 passes.
if (addPreSched2())
printNoVerify("After PreSched2 passes");
// Second pass scheduler.
if (getOptLevel() != CodeGenOpt::None && !DisablePostRA) {
addPass(PostRASchedulerID);
printNoVerify("After PostRAScheduler");
}
// GC
addPass(GCMachineCodeAnalysisID);
if (PrintGCInfo)
PM.add(createGCInfoPrinter(dbgs()));
// Basic block placement.
if (getOptLevel() != CodeGenOpt::None && !DisableCodePlace)
addBlockPlacement();
if (addPreEmitPass())
printNoVerify("After PreEmit passes");
}
/// Add passes that optimize machine instructions in SSA form.
void TargetPassConfig::addMachineSSAOptimization() {
// Pre-ra tail duplication.
if (getOptLevel() != CodeGenOpt::None && !DisableEarlyTailDup) {
if (!DisableEarlyTailDup) {
addPass(TailDuplicateID);
printAndVerify("After Pre-RegAlloc TailDuplicate");
}
// Optimize PHIs before DCE: removing dead PHI cycles may make more
// instructions dead.
if (getOptLevel() != CodeGenOpt::None)
addPass(OptimizePHIsID);
// If the target requests it, assign local variables to stack slots relative
// to one another and simplify frame index references where possible.
addPass(LocalStackSlotAllocationID);
if (getOptLevel() != CodeGenOpt::None) {
// With optimization, dead code should already be eliminated. However
// there is one known exception: lowered code for arguments that are only
// used by tail calls, where the tail calls reuse the incoming stack
@ -225,116 +300,24 @@ void TargetPassConfig::addMachinePasses() {
addPass(PeepholeOptimizerID);
printAndVerify("After codegen peephole optimization pass");
}
// Run pre-ra passes.
if (addPreRegAlloc())
printAndVerify("After PreRegAlloc passes");
// Perform register allocation.
PM.add(createRegisterAllocator(getOptLevel()));
printAndVerify("After Register Allocation");
// Perform stack slot coloring and post-ra machine LICM.
if (getOptLevel() != CodeGenOpt::None) {
// FIXME: Re-enable coloring with register when it's capable of adding
// kill markers.
if (!DisableSSC)
addPass(StackSlotColoringID);
// Run post-ra machine LICM to hoist reloads / remats.
if (!DisablePostRAMachineLICM)
addPass(MachineLICMID);
printAndVerify("After StackSlotColoring and postra Machine LICM");
}
// Run post-ra passes.
if (addPostRegAlloc())
printAndVerify("After PostRegAlloc passes");
// Insert prolog/epilog code. Eliminate abstract frame index references...
addPass(PrologEpilogCodeInserterID);
printAndVerify("After PrologEpilogCodeInserter");
// Branch folding must be run after regalloc and prolog/epilog insertion.
if (getOptLevel() != CodeGenOpt::None && !DisableBranchFold) {
addPass(BranchFolderPassID);
printNoVerify("After BranchFolding");
}
// Tail duplication.
if (getOptLevel() != CodeGenOpt::None && !DisableTailDuplicate) {
addPass(TailDuplicateID);
printNoVerify("After TailDuplicate");
}
// Copy propagation.
if (getOptLevel() != CodeGenOpt::None && !DisableCopyProp) {
addPass(MachineCopyPropagationID);
printNoVerify("After copy propagation pass");
}
// Expand pseudo instructions before second scheduling pass.
addPass(ExpandPostRAPseudosID);
printNoVerify("After ExpandPostRAPseudos");
// Run pre-sched2 passes.
if (addPreSched2())
printNoVerify("After PreSched2 passes");
// Second pass scheduler.
if (getOptLevel() != CodeGenOpt::None && !DisablePostRA) {
addPass(PostRASchedulerID);
printNoVerify("After PostRAScheduler");
}
addPass(GCMachineCodeAnalysisID);
if (PrintGCInfo)
PM.add(createGCInfoPrinter(dbgs()));
if (getOptLevel() != CodeGenOpt::None && !DisableCodePlace) {
if (EnableBlockPlacement) {
// MachineBlockPlacement is an experimental pass which is disabled by
// default currently. Eventually it should subsume CodePlacementOpt, so
// when enabled, the other is disabled.
addPass(MachineBlockPlacementID);
printNoVerify("After MachineBlockPlacement");
} else {
addPass(CodePlacementOptID);
printNoVerify("After CodePlacementOpt");
}
// Run a separate pass to collect block placement statistics.
if (EnableBlockPlacementStats) {
addPass(MachineBlockPlacementStatsID);
printNoVerify("After MachineBlockPlacementStats");
}
}
if (addPreEmitPass())
printNoVerify("After PreEmit passes");
}
//===---------------------------------------------------------------------===//
///
/// RegisterRegAlloc class - Track the registration of register allocators.
///
/// Register Allocation Pass Configuration
//===---------------------------------------------------------------------===//
/// RegisterRegAlloc's global Registry tracks allocator registration.
MachinePassRegistry RegisterRegAlloc::Registry;
/// A dummy default pass factory indicates whether the register allocator is
/// overridden on the command line.
static FunctionPass *createDefaultRegisterAllocator() { return 0; }
static RegisterRegAlloc
defaultRegAlloc("default",
"pick register allocator based on -O option",
createDefaultRegisterAllocator);
//===---------------------------------------------------------------------===//
///
/// RegAlloc command line options.
///
//===---------------------------------------------------------------------===//
/// -regalloc=... command line option.
static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
RegisterPassParser<RegisterRegAlloc> >
RegAlloc("regalloc",
@ -342,11 +325,7 @@ RegAlloc("regalloc",
cl::desc("Register allocator to use"));
//===---------------------------------------------------------------------===//
///
/// createRegisterAllocator - choose the appropriate register allocator.
///
//===---------------------------------------------------------------------===//
FunctionPass *llvm::createRegisterAllocator(CodeGenOpt::Level OptLevel) {
RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault();
@ -366,3 +345,75 @@ FunctionPass *llvm::createRegisterAllocator(CodeGenOpt::Level OptLevel) {
return createGreedyRegisterAllocator();
}
}
/// Add standard target-independent passes that are tightly coupled with
/// register allocation, including coalescing, machine instruction scheduling,
/// and register allocation itself.
///
/// FIXME: This will become the register allocation "super pass" pipeline.
void TargetPassConfig::addRegAlloc() {
// Perform register allocation.
PM.add(createRegisterAllocator(getOptLevel()));
printAndVerify("After Register Allocation");
// Perform stack slot coloring and post-ra machine LICM.
if (getOptLevel() != CodeGenOpt::None) {
// FIXME: Re-enable coloring with register when it's capable of adding
// kill markers.
if (!DisableSSC)
addPass(StackSlotColoringID);
// Run post-ra machine LICM to hoist reloads / remats.
//
// FIXME: can this move into MachineLateOptimization?
if (!DisablePostRAMachineLICM)
addPass(MachineLICMID);
printAndVerify("After StackSlotColoring and postra Machine LICM");
}
}
//===---------------------------------------------------------------------===//
/// Post RegAlloc Pass Configuration
//===---------------------------------------------------------------------===//
/// Add passes that optimize machine instructions after register allocation.
void TargetPassConfig::addMachineLateOptimization() {
// Branch folding must be run after regalloc and prolog/epilog insertion.
if (!DisableBranchFold) {
addPass(BranchFolderPassID);
printNoVerify("After BranchFolding");
}
// Tail duplication.
if (!DisableTailDuplicate) {
addPass(TailDuplicateID);
printNoVerify("After TailDuplicate");
}
// Copy propagation.
if (!DisableCopyProp) {
addPass(MachineCopyPropagationID);
printNoVerify("After copy propagation pass");
}
}
/// Add standard basic block placement passes.
void TargetPassConfig::addBlockPlacement() {
if (EnableBlockPlacement) {
// MachineBlockPlacement is an experimental pass which is disabled by
// default currently. Eventually it should subsume CodePlacementOpt, so
// when enabled, the other is disabled.
addPass(MachineBlockPlacementID);
printNoVerify("After MachineBlockPlacement");
} else {
addPass(CodePlacementOptID);
printNoVerify("After CodePlacementOpt");
}
// Run a separate pass to collect block placement statistics.
if (EnableBlockPlacementStats) {
addPass(MachineBlockPlacementStatsID);
printNoVerify("After MachineBlockPlacementStats");
}
}