forked from OSchip/llvm-project
Improve TargetPassConfig. No intended functionality.
Split CodeGen into stages. Distinguish between optimization and correctness. llvm-svn: 150122
This commit is contained in:
parent
c24e09b226
commit
f542675ae3
|
@ -111,6 +111,10 @@ protected:
|
||||||
return true;
|
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
|
/// addPreRegAlloc - This method may be implemented by targets that want to
|
||||||
/// run passes immediately before register allocation. This should return
|
/// run passes immediately before register allocation. This should return
|
||||||
/// true if -print-machineinstrs should print after these passes.
|
/// true if -print-machineinstrs should print after these passes.
|
||||||
|
@ -118,6 +122,9 @@ protected:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addRegAlloc - Add standard passes related to register allocation.
|
||||||
|
virtual void addRegAlloc();
|
||||||
|
|
||||||
/// addPostRegAlloc - This method may be implemented by targets that want
|
/// addPostRegAlloc - This method may be implemented by targets that want
|
||||||
/// to run passes after register allocation but before prolog-epilog
|
/// to run passes after register allocation but before prolog-epilog
|
||||||
/// insertion. This should return true if -print-machineinstrs should print
|
/// insertion. This should return true if -print-machineinstrs should print
|
||||||
|
@ -126,6 +133,9 @@ protected:
|
||||||
return false;
|
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
|
/// addPreSched2 - This method may be implemented by targets that want to
|
||||||
/// run passes after prolog-epilog insertion and before the second instruction
|
/// run passes after prolog-epilog insertion and before the second instruction
|
||||||
/// scheduling pass. This should return true if -print-machineinstrs should
|
/// scheduling pass. This should return true if -print-machineinstrs should
|
||||||
|
@ -134,6 +144,9 @@ protected:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add standard basic block placement passes.
|
||||||
|
virtual void addBlockPlacement();
|
||||||
|
|
||||||
/// addPreEmitPass - This pass may be implemented by targets that want to run
|
/// addPreEmitPass - This pass may be implemented by targets that want to run
|
||||||
/// passes immediately before machine code is emitted. This should return
|
/// passes immediately before machine code is emitted. This should return
|
||||||
/// true if -print-machineinstrs should print out the code after the passes.
|
/// true if -print-machineinstrs should print out the code after the passes.
|
||||||
|
|
|
@ -184,6 +184,24 @@ void TargetPassConfig::addISelPrepare() {
|
||||||
PM.add(createVerifierPass());
|
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() {
|
void TargetPassConfig::addMachinePasses() {
|
||||||
// Print the instruction selected machine code...
|
// Print the instruction selected machine code...
|
||||||
printAndVerify("After Instruction Selection");
|
printAndVerify("After Instruction Selection");
|
||||||
|
@ -191,63 +209,23 @@ void TargetPassConfig::addMachinePasses() {
|
||||||
// Expand pseudo-instructions emitted by ISel.
|
// Expand pseudo-instructions emitted by ISel.
|
||||||
addPass(ExpandISelPseudosID);
|
addPass(ExpandISelPseudosID);
|
||||||
|
|
||||||
// Pre-ra tail duplication.
|
// Add passes that optimize machine instructions in SSA form.
|
||||||
if (getOptLevel() != CodeGenOpt::None && !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) {
|
if (getOptLevel() != CodeGenOpt::None) {
|
||||||
// With optimization, dead code should already be eliminated. However
|
addMachineSSAOptimization();
|
||||||
// there is one known exception: lowered code for arguments that are only
|
}
|
||||||
// used by tail calls, where the tail calls reuse the incoming stack
|
else {
|
||||||
// arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
|
// If the target requests it, assign local variables to stack slots relative
|
||||||
if (!DisableMachineDCE)
|
// to one another and simplify frame index references where possible.
|
||||||
addPass(DeadMachineInstructionElimID);
|
addPass(LocalStackSlotAllocationID);
|
||||||
printAndVerify("After codegen DCE pass");
|
|
||||||
|
|
||||||
if (!DisableMachineLICM)
|
|
||||||
addPass(MachineLICMID);
|
|
||||||
if (!DisableMachineCSE)
|
|
||||||
addPass(MachineCSEID);
|
|
||||||
if (!DisableMachineSink)
|
|
||||||
addPass(MachineSinkingID);
|
|
||||||
printAndVerify("After Machine LICM, CSE and Sinking passes");
|
|
||||||
|
|
||||||
addPass(PeepholeOptimizerID);
|
|
||||||
printAndVerify("After codegen peephole optimization pass");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run pre-ra passes.
|
// Run pre-ra passes.
|
||||||
if (addPreRegAlloc())
|
if (addPreRegAlloc())
|
||||||
printAndVerify("After PreRegAlloc passes");
|
printAndVerify("After PreRegAlloc passes");
|
||||||
|
|
||||||
// Perform register allocation.
|
// Run register allocation and passes that are tightly coupled with it,
|
||||||
PM.add(createRegisterAllocator(getOptLevel()));
|
// including phi elimination and scheduling.
|
||||||
printAndVerify("After Register Allocation");
|
addRegAlloc();
|
||||||
|
|
||||||
// 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.
|
// Run post-ra passes.
|
||||||
if (addPostRegAlloc())
|
if (addPostRegAlloc())
|
||||||
|
@ -257,23 +235,9 @@ void TargetPassConfig::addMachinePasses() {
|
||||||
addPass(PrologEpilogCodeInserterID);
|
addPass(PrologEpilogCodeInserterID);
|
||||||
printAndVerify("After PrologEpilogCodeInserter");
|
printAndVerify("After PrologEpilogCodeInserter");
|
||||||
|
|
||||||
// Branch folding must be run after regalloc and prolog/epilog insertion.
|
/// Add passes that optimize machine instructions after register allocation.
|
||||||
if (getOptLevel() != CodeGenOpt::None && !DisableBranchFold) {
|
if (getOptLevel() != CodeGenOpt::None)
|
||||||
addPass(BranchFolderPassID);
|
addMachineLateOptimization();
|
||||||
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.
|
// Expand pseudo instructions before second scheduling pass.
|
||||||
addPass(ExpandPostRAPseudosID);
|
addPass(ExpandPostRAPseudosID);
|
||||||
|
@ -289,52 +253,71 @@ void TargetPassConfig::addMachinePasses() {
|
||||||
printNoVerify("After PostRAScheduler");
|
printNoVerify("After PostRAScheduler");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GC
|
||||||
addPass(GCMachineCodeAnalysisID);
|
addPass(GCMachineCodeAnalysisID);
|
||||||
|
|
||||||
if (PrintGCInfo)
|
if (PrintGCInfo)
|
||||||
PM.add(createGCInfoPrinter(dbgs()));
|
PM.add(createGCInfoPrinter(dbgs()));
|
||||||
|
|
||||||
if (getOptLevel() != CodeGenOpt::None && !DisableCodePlace) {
|
// Basic block placement.
|
||||||
if (EnableBlockPlacement) {
|
if (getOptLevel() != CodeGenOpt::None && !DisableCodePlace)
|
||||||
// MachineBlockPlacement is an experimental pass which is disabled by
|
addBlockPlacement();
|
||||||
// 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())
|
if (addPreEmitPass())
|
||||||
printNoVerify("After PreEmit passes");
|
printNoVerify("After PreEmit passes");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add passes that optimize machine instructions in SSA form.
|
||||||
|
void TargetPassConfig::addMachineSSAOptimization() {
|
||||||
|
// Pre-ra tail duplication.
|
||||||
|
if (!DisableEarlyTailDup) {
|
||||||
|
addPass(TailDuplicateID);
|
||||||
|
printAndVerify("After Pre-RegAlloc TailDuplicate");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optimize PHIs before DCE: removing dead PHI cycles may make more
|
||||||
|
// instructions dead.
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
|
||||||
|
if (!DisableMachineDCE)
|
||||||
|
addPass(DeadMachineInstructionElimID);
|
||||||
|
printAndVerify("After codegen DCE pass");
|
||||||
|
|
||||||
|
if (!DisableMachineLICM)
|
||||||
|
addPass(MachineLICMID);
|
||||||
|
if (!DisableMachineCSE)
|
||||||
|
addPass(MachineCSEID);
|
||||||
|
if (!DisableMachineSink)
|
||||||
|
addPass(MachineSinkingID);
|
||||||
|
printAndVerify("After Machine LICM, CSE and Sinking passes");
|
||||||
|
|
||||||
|
addPass(PeepholeOptimizerID);
|
||||||
|
printAndVerify("After codegen peephole optimization pass");
|
||||||
|
}
|
||||||
|
|
||||||
//===---------------------------------------------------------------------===//
|
//===---------------------------------------------------------------------===//
|
||||||
///
|
/// Register Allocation Pass Configuration
|
||||||
/// RegisterRegAlloc class - Track the registration of register allocators.
|
|
||||||
///
|
|
||||||
//===---------------------------------------------------------------------===//
|
//===---------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// RegisterRegAlloc's global Registry tracks allocator registration.
|
||||||
MachinePassRegistry RegisterRegAlloc::Registry;
|
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 FunctionPass *createDefaultRegisterAllocator() { return 0; }
|
||||||
static RegisterRegAlloc
|
static RegisterRegAlloc
|
||||||
defaultRegAlloc("default",
|
defaultRegAlloc("default",
|
||||||
"pick register allocator based on -O option",
|
"pick register allocator based on -O option",
|
||||||
createDefaultRegisterAllocator);
|
createDefaultRegisterAllocator);
|
||||||
|
|
||||||
//===---------------------------------------------------------------------===//
|
/// -regalloc=... command line option.
|
||||||
///
|
|
||||||
/// RegAlloc command line options.
|
|
||||||
///
|
|
||||||
//===---------------------------------------------------------------------===//
|
|
||||||
static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
|
static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
|
||||||
RegisterPassParser<RegisterRegAlloc> >
|
RegisterPassParser<RegisterRegAlloc> >
|
||||||
RegAlloc("regalloc",
|
RegAlloc("regalloc",
|
||||||
|
@ -342,11 +325,7 @@ RegAlloc("regalloc",
|
||||||
cl::desc("Register allocator to use"));
|
cl::desc("Register allocator to use"));
|
||||||
|
|
||||||
|
|
||||||
//===---------------------------------------------------------------------===//
|
|
||||||
///
|
|
||||||
/// createRegisterAllocator - choose the appropriate register allocator.
|
/// createRegisterAllocator - choose the appropriate register allocator.
|
||||||
///
|
|
||||||
//===---------------------------------------------------------------------===//
|
|
||||||
FunctionPass *llvm::createRegisterAllocator(CodeGenOpt::Level OptLevel) {
|
FunctionPass *llvm::createRegisterAllocator(CodeGenOpt::Level OptLevel) {
|
||||||
RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault();
|
RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault();
|
||||||
|
|
||||||
|
@ -366,3 +345,75 @@ FunctionPass *llvm::createRegisterAllocator(CodeGenOpt::Level OptLevel) {
|
||||||
return createGreedyRegisterAllocator();
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue