Added TargetPassConfig. The first little step toward configuring codegen passes.

Allows command line overrides to be centralized in LLVMTargetMachine.cpp.
LLVMTargetMachine can intercept common passes and give precedence to command line overrides.
Allows adding "internal" target configuration options without touching TargetOptions.
Encapsulates the PassManager.
Provides a good point to initialize all CodeGen passes so that Pass ID's can be used in APIs.
Allows modifying the target configuration hooks without rebuilding the world.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149672 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Trick 2012-02-03 05:12:41 +00:00
parent 8247e0dca6
commit 843ee2e6a4
25 changed files with 565 additions and 268 deletions

View File

@ -26,7 +26,111 @@ namespace llvm {
class TargetLowering; class TargetLowering;
class TargetRegisterClass; class TargetRegisterClass;
class raw_ostream; class raw_ostream;
}
namespace llvm {
/// Target-Independent Code Generator Pass Configuration Options.
///
/// FIXME: Why are we passing the DisableVerify flags around instead of setting
/// an options in the target machine, like all the other driver options?
class TargetPassConfig {
protected:
TargetMachine *TM;
PassManagerBase ±
bool DisableVerify;
public:
TargetPassConfig(TargetMachine *tm, PassManagerBase &pm,
bool DisableVerifyFlag)
: TM(tm), PM(pm), DisableVerify(DisableVerifyFlag) {}
virtual ~TargetPassConfig() {}
/// Get the right type of TargetMachine for this target.
template<typename TMC> TMC &getTM() const {
return *static_cast<TMC*>(TM);
}
CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); }
const TargetLowering *getTargetLowering() const { return TM->getTargetLowering(); }
/// Add the complete, standard set of LLVM CodeGen passes.
/// Fully developed targets will not generally override this.
virtual bool addCodeGenPasses(MCContext *&OutContext);
protected:
/// Convenient points in the common codegen pass pipeline for inserting
/// passes, and major CodeGen stages that some targets may override.
///
/// addPreISelPasses - This method should add any "last minute" LLVM->LLVM
/// passes (which are run just before instruction selector).
virtual bool addPreISel() {
return true;
}
/// addInstSelector - This method should install an instruction selector pass,
/// which converts from LLVM code to machine instructions.
virtual bool addInstSelector() {
return true;
}
/// 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.
virtual bool addPreRegAlloc() {
return false;
}
/// 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
/// after these passes.
virtual bool addPostRegAlloc() {
return false;
}
/// getEnableTailMergeDefault - the default setting for -enable-tail-merge
/// on this target. User flag overrides.
virtual bool getEnableTailMergeDefault() const { return true; }
/// 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
/// print after these passes.
virtual bool addPreSched2() {
return false;
}
/// 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.
virtual bool addPreEmitPass() {
return false;
}
/// Utilities for targets to add passes to the pass manager.
///
/// Add a target-independent CodeGen pass at this point in the pipeline.
void addCommonPass(char &ID);
/// printNoVerify - Add a pass to dump the machine function, if debugging is
/// enabled.
///
void printNoVerify(const char *Banner) const;
/// printAndVerify - Add a pass to dump then verify the machine function, if
/// those steps are enabled.
///
void printAndVerify(const char *Banner) const;
};
} // namespace llvm
/// List of target independent CodeGen pass IDs.
namespace llvm {
/// createUnreachableBlockEliminationPass - The LLVM code generator does not /// createUnreachableBlockEliminationPass - The LLVM code generator does not
/// work well with unreachable basic blocks (what live ranges make sense for a /// work well with unreachable basic blocks (what live ranges make sense for a
/// block that cannot be reached?). As such, a code generator should either /// block that cannot be reached?). As such, a code generator should either

View File

@ -38,6 +38,7 @@ class TargetInstrInfo;
class TargetIntrinsicInfo; class TargetIntrinsicInfo;
class TargetJITInfo; class TargetJITInfo;
class TargetLowering; class TargetLowering;
class TargetPassConfig;
class TargetRegisterInfo; class TargetRegisterInfo;
class TargetSelectionDAGInfo; class TargetSelectionDAGInfo;
class TargetSubtargetInfo; class TargetSubtargetInfo;
@ -200,6 +201,10 @@ public:
/// Default, or Aggressive. /// Default, or Aggressive.
CodeGenOpt::Level getOptLevel() const; CodeGenOpt::Level getOptLevel() const;
void setFastISel(bool Enable) { Options.EnableFastISel = Enable; }
bool shouldPrintMachineCode() const { return Options.PrintMachineCode; }
/// getAsmVerbosityDefault - Returns the default value of asm verbosity. /// getAsmVerbosityDefault - Returns the default value of asm verbosity.
/// ///
static bool getAsmVerbosityDefault(); static bool getAsmVerbosityDefault();
@ -232,10 +237,6 @@ public:
CGFT_Null // Do not emit any output. CGFT_Null // Do not emit any output.
}; };
/// getEnableTailMergeDefault - the default setting for -enable-tail-merge
/// on this target. User flag overrides.
virtual bool getEnableTailMergeDefault() const { return true; }
/// addPassesToEmitFile - Add passes to the specified pass manager to get the /// addPassesToEmitFile - Add passes to the specified pass manager to get the
/// specified file emitted. Typically this will involve several steps of code /// specified file emitted. Typically this will involve several steps of code
/// generation. This method should return true if emission of this file type /// generation. This method should return true if emission of this file type
@ -282,24 +283,12 @@ protected: // Can only create subclasses.
Reloc::Model RM, CodeModel::Model CM, Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL); CodeGenOpt::Level OL);
/// printNoVerify - Add a pass to dump the machine function, if debugging is
/// enabled.
///
void printNoVerify(PassManagerBase &PM, const char *Banner) const;
/// printAndVerify - Add a pass to dump then verify the machine function, if
/// those steps are enabled.
///
void printAndVerify(PassManagerBase &PM, const char *Banner) const;
private:
/// addCommonCodeGenPasses - Add standard LLVM codegen passes used for
/// both emitting to assembly files or machine code output.
///
bool addCommonCodeGenPasses(PassManagerBase &,
bool DisableVerify, MCContext *&OutCtx);
public: public:
/// createPassConfig - Create a pass configuration object to be used by
/// addPassToEmitX methods for generating a pipeline of CodeGen passes.
virtual TargetPassConfig *createPassConfig(PassManagerBase &PM,
bool DisableVerify);
/// addPassesToEmitFile - Add passes to the specified pass manager to get the /// addPassesToEmitFile - Add passes to the specified pass manager to get the
/// specified file emitted. Typically this will involve several steps of code /// specified file emitted. Typically this will involve several steps of code
/// generation. /// generation.
@ -328,51 +317,6 @@ public:
raw_ostream &OS, raw_ostream &OS,
bool DisableVerify = true); bool DisableVerify = true);
/// Target-Independent Code Generator Pass Configuration Options.
/// addPreISelPasses - This method should add any "last minute" LLVM->LLVM
/// passes (which are run just before instruction selector).
virtual bool addPreISel(PassManagerBase &) {
return true;
}
/// addInstSelector - This method should install an instruction selector pass,
/// which converts from LLVM code to machine instructions.
virtual bool addInstSelector(PassManagerBase &) {
return true;
}
/// 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.
virtual bool addPreRegAlloc(PassManagerBase &) {
return false;
}
/// 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
/// after these passes.
virtual bool addPostRegAlloc(PassManagerBase &) {
return false;
}
/// 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
/// print after these passes.
virtual bool addPreSched2(PassManagerBase &) {
return false;
}
/// 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.
virtual bool addPreEmitPass(PassManagerBase &) {
return false;
}
/// addCodeEmitter - This pass should be overridden by the target to add a /// addCodeEmitter - This pass should be overridden by the target to add a
/// code emitter, if supported. If this is not supported, 'true' should be /// code emitter, if supported. If this is not supported, 'true' should be
/// returned. /// returned.
@ -380,10 +324,6 @@ public:
JITCodeEmitter &) { JITCodeEmitter &) {
return true; return true;
} }
/// getEnableTailMergeDefault - the default setting for -enable-tail-merge
/// on this target. User flag overrides.
virtual bool getEnableTailMergeDefault() const { return true; }
}; };
} // End llvm namespace } // End llvm namespace

View File

@ -125,13 +125,21 @@ LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple,
"and that InitializeAllTargetMCs() is being invoked!"); "and that InitializeAllTargetMCs() is being invoked!");
} }
/// createPassConfig - Create a pass configuration object to be used by
/// addPassToEmitX methods for generating a pipeline of CodeGen passes.
TargetPassConfig *LLVMTargetMachine::createPassConfig(PassManagerBase &PM,
bool DisableVerify) {
return new TargetPassConfig(this, PM, DisableVerify);
}
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
formatted_raw_ostream &Out, formatted_raw_ostream &Out,
CodeGenFileType FileType, CodeGenFileType FileType,
bool DisableVerify) { bool DisableVerify) {
// Add common CodeGen passes. // Add common CodeGen passes.
MCContext *Context = 0; MCContext *Context = 0;
if (addCommonCodeGenPasses(PM, DisableVerify, Context)) OwningPtr<TargetPassConfig> PassConfig(createPassConfig(PM, DisableVerify));
if (PassConfig->addCodeGenPasses(Context))
return true; return true;
assert(Context != 0 && "Failed to get MCContext"); assert(Context != 0 && "Failed to get MCContext");
@ -215,7 +223,8 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
bool DisableVerify) { bool DisableVerify) {
// Add common CodeGen passes. // Add common CodeGen passes.
MCContext *Ctx = 0; MCContext *Ctx = 0;
if (addCommonCodeGenPasses(PM, DisableVerify, Ctx)) OwningPtr<TargetPassConfig> PassConfig(createPassConfig(PM, DisableVerify));
if (PassConfig->addCodeGenPasses(Ctx))
return true; return true;
addCodeEmitter(PM, JCE); addCodeEmitter(PM, JCE);
@ -234,7 +243,8 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
raw_ostream &Out, raw_ostream &Out,
bool DisableVerify) { bool DisableVerify) {
// Add common CodeGen passes. // Add common CodeGen passes.
if (addCommonCodeGenPasses(PM, DisableVerify, Ctx)) OwningPtr<TargetPassConfig> PassConfig(createPassConfig(PM, DisableVerify));
if (PassConfig->addCodeGenPasses(Ctx))
return true; return true;
if (hasMCSaveTempLabels()) if (hasMCSaveTempLabels())
@ -268,27 +278,23 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
return false; // success! return false; // success!
} }
void LLVMTargetMachine::printNoVerify(PassManagerBase &PM, void TargetPassConfig::printNoVerify(const char *Banner) const {
const char *Banner) const { if (TM->shouldPrintMachineCode())
if (Options.PrintMachineCode)
PM.add(createMachineFunctionPrinterPass(dbgs(), Banner)); PM.add(createMachineFunctionPrinterPass(dbgs(), Banner));
} }
void LLVMTargetMachine::printAndVerify(PassManagerBase &PM, void TargetPassConfig::printAndVerify(const char *Banner) const {
const char *Banner) const { if (TM->shouldPrintMachineCode())
if (Options.PrintMachineCode)
PM.add(createMachineFunctionPrinterPass(dbgs(), Banner)); PM.add(createMachineFunctionPrinterPass(dbgs(), Banner));
if (VerifyMachineCode) if (VerifyMachineCode)
PM.add(createMachineVerifierPass(Banner)); PM.add(createMachineVerifierPass(Banner));
} }
/// addCommonCodeGenPasses - Add standard LLVM codegen passes used for both /// addCodeGenPasses - Add standard LLVM codegen passes used for both
/// emitting to assembly files or machine code output. /// emitting to assembly files or machine code output.
/// ///
bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, bool TargetPassConfig::addCodeGenPasses(MCContext *&OutContext) {
bool DisableVerify,
MCContext *&OutContext) {
// Standard LLVM-Level Passes. // Standard LLVM-Level Passes.
// Basic AliasAnalysis support. // Basic AliasAnalysis support.
@ -317,7 +323,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
// Turn exception handling constructs into something the code generators can // Turn exception handling constructs into something the code generators can
// handle. // handle.
switch (getMCAsmInfo()->getExceptionHandlingType()) { switch (TM->getMCAsmInfo()->getExceptionHandlingType()) {
case ExceptionHandling::SjLj: case ExceptionHandling::SjLj:
// SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
// Dwarf EH prepare needs to be run after SjLj prepare. Otherwise, // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
@ -330,7 +336,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
case ExceptionHandling::DwarfCFI: case ExceptionHandling::DwarfCFI:
case ExceptionHandling::ARM: case ExceptionHandling::ARM:
case ExceptionHandling::Win64: case ExceptionHandling::Win64:
PM.add(createDwarfEHPass(this)); PM.add(createDwarfEHPass(TM));
break; break;
case ExceptionHandling::None: case ExceptionHandling::None:
PM.add(createLowerInvokePass(getTargetLowering())); PM.add(createLowerInvokePass(getTargetLowering()));
@ -345,7 +351,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
PM.add(createStackProtectorPass(getTargetLowering())); PM.add(createStackProtectorPass(getTargetLowering()));
addPreISel(PM); addPreISel();
if (PrintISelInput) if (PrintISelInput)
PM.add(createPrintFunctionPass("\n\n" PM.add(createPrintFunctionPass("\n\n"
@ -362,26 +368,26 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
// Install a MachineModuleInfo class, which is an immutable pass that holds // Install a MachineModuleInfo class, which is an immutable pass that holds
// all the per-module stuff we're generating, including MCContext. // all the per-module stuff we're generating, including MCContext.
MachineModuleInfo *MMI = MachineModuleInfo *MMI =
new MachineModuleInfo(*getMCAsmInfo(), *getRegisterInfo(), new MachineModuleInfo(*TM->getMCAsmInfo(), *TM->getRegisterInfo(),
&getTargetLowering()->getObjFileLowering()); &getTargetLowering()->getObjFileLowering());
PM.add(MMI); PM.add(MMI);
OutContext = &MMI->getContext(); // Return the MCContext specifically by-ref. OutContext = &MMI->getContext(); // Return the MCContext specifically by-ref.
// Set up a MachineFunction for the rest of CodeGen to work on. // Set up a MachineFunction for the rest of CodeGen to work on.
PM.add(new MachineFunctionAnalysis(*this)); PM.add(new MachineFunctionAnalysis(*TM));
// Enable FastISel with -fast, but allow that to be overridden. // Enable FastISel with -fast, but allow that to be overridden.
if (EnableFastISelOption == cl::BOU_TRUE || if (EnableFastISelOption == cl::BOU_TRUE ||
(getOptLevel() == CodeGenOpt::None && (getOptLevel() == CodeGenOpt::None &&
EnableFastISelOption != cl::BOU_FALSE)) EnableFastISelOption != cl::BOU_FALSE))
Options.EnableFastISel = true; TM->setFastISel(true);
// Ask the target for an isel. // Ask the target for an isel.
if (addInstSelector(PM)) if (addInstSelector())
return true; return true;
// Print the instruction selected machine code... // Print the instruction selected machine code...
printAndVerify(PM, "After Instruction Selection"); printAndVerify("After Instruction Selection");
// Expand pseudo-instructions emitted by ISel. // Expand pseudo-instructions emitted by ISel.
PM.add(createExpandISelPseudosPass()); PM.add(createExpandISelPseudosPass());
@ -389,7 +395,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
// Pre-ra tail duplication. // Pre-ra tail duplication.
if (getOptLevel() != CodeGenOpt::None && !DisableEarlyTailDup) { if (getOptLevel() != CodeGenOpt::None && !DisableEarlyTailDup) {
PM.add(createTailDuplicatePass(true)); PM.add(createTailDuplicatePass(true));
printAndVerify(PM, "After Pre-RegAlloc TailDuplicate"); printAndVerify("After Pre-RegAlloc TailDuplicate");
} }
// Optimize PHIs before DCE: removing dead PHI cycles may make more // Optimize PHIs before DCE: removing dead PHI cycles may make more
@ -408,7 +414,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
// arguments directly (see t11 in test/CodeGen/X86/sibcall.ll). // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
if (!DisableMachineDCE) if (!DisableMachineDCE)
PM.add(createDeadMachineInstructionElimPass()); PM.add(createDeadMachineInstructionElimPass());
printAndVerify(PM, "After codegen DCE pass"); printAndVerify("After codegen DCE pass");
if (!DisableMachineLICM) if (!DisableMachineLICM)
PM.add(createMachineLICMPass()); PM.add(createMachineLICMPass());
@ -416,19 +422,19 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
PM.add(createMachineCSEPass()); PM.add(createMachineCSEPass());
if (!DisableMachineSink) if (!DisableMachineSink)
PM.add(createMachineSinkingPass()); PM.add(createMachineSinkingPass());
printAndVerify(PM, "After Machine LICM, CSE and Sinking passes"); printAndVerify("After Machine LICM, CSE and Sinking passes");
PM.add(createPeepholeOptimizerPass()); PM.add(createPeepholeOptimizerPass());
printAndVerify(PM, "After codegen peephole optimization pass"); printAndVerify("After codegen peephole optimization pass");
} }
// Run pre-ra passes. // Run pre-ra passes.
if (addPreRegAlloc(PM)) if (addPreRegAlloc())
printAndVerify(PM, "After PreRegAlloc passes"); printAndVerify("After PreRegAlloc passes");
// Perform register allocation. // Perform register allocation.
PM.add(createRegisterAllocator(getOptLevel())); PM.add(createRegisterAllocator(getOptLevel()));
printAndVerify(PM, "After Register Allocation"); printAndVerify("After Register Allocation");
// Perform stack slot coloring and post-ra machine LICM. // Perform stack slot coloring and post-ra machine LICM.
if (getOptLevel() != CodeGenOpt::None) { if (getOptLevel() != CodeGenOpt::None) {
@ -441,47 +447,47 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
if (!DisablePostRAMachineLICM) if (!DisablePostRAMachineLICM)
PM.add(createMachineLICMPass(false)); PM.add(createMachineLICMPass(false));
printAndVerify(PM, "After StackSlotColoring and postra Machine LICM"); printAndVerify("After StackSlotColoring and postra Machine LICM");
} }
// Run post-ra passes. // Run post-ra passes.
if (addPostRegAlloc(PM)) if (addPostRegAlloc())
printAndVerify(PM, "After PostRegAlloc passes"); printAndVerify("After PostRegAlloc passes");
// Insert prolog/epilog code. Eliminate abstract frame index references... // Insert prolog/epilog code. Eliminate abstract frame index references...
PM.add(createPrologEpilogCodeInserter()); PM.add(createPrologEpilogCodeInserter());
printAndVerify(PM, "After PrologEpilogCodeInserter"); printAndVerify("After PrologEpilogCodeInserter");
// Branch folding must be run after regalloc and prolog/epilog insertion. // Branch folding must be run after regalloc and prolog/epilog insertion.
if (getOptLevel() != CodeGenOpt::None && !DisableBranchFold) { if (getOptLevel() != CodeGenOpt::None && !DisableBranchFold) {
PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));
printNoVerify(PM, "After BranchFolding"); printNoVerify("After BranchFolding");
} }
// Tail duplication. // Tail duplication.
if (getOptLevel() != CodeGenOpt::None && !DisableTailDuplicate) { if (getOptLevel() != CodeGenOpt::None && !DisableTailDuplicate) {
PM.add(createTailDuplicatePass(false)); PM.add(createTailDuplicatePass(false));
printNoVerify(PM, "After TailDuplicate"); printNoVerify("After TailDuplicate");
} }
// Copy propagation. // Copy propagation.
if (getOptLevel() != CodeGenOpt::None && !DisableCopyProp) { if (getOptLevel() != CodeGenOpt::None && !DisableCopyProp) {
PM.add(createMachineCopyPropagationPass()); PM.add(createMachineCopyPropagationPass());
printNoVerify(PM, "After copy propagation pass"); printNoVerify("After copy propagation pass");
} }
// Expand pseudo instructions before second scheduling pass. // Expand pseudo instructions before second scheduling pass.
PM.add(createExpandPostRAPseudosPass()); PM.add(createExpandPostRAPseudosPass());
printNoVerify(PM, "After ExpandPostRAPseudos"); printNoVerify("After ExpandPostRAPseudos");
// Run pre-sched2 passes. // Run pre-sched2 passes.
if (addPreSched2(PM)) if (addPreSched2())
printNoVerify(PM, "After PreSched2 passes"); printNoVerify("After PreSched2 passes");
// Second pass scheduler. // Second pass scheduler.
if (getOptLevel() != CodeGenOpt::None && !DisablePostRA) { if (getOptLevel() != CodeGenOpt::None && !DisablePostRA) {
PM.add(createPostRAScheduler(getOptLevel())); PM.add(createPostRAScheduler(getOptLevel()));
printNoVerify(PM, "After PostRAScheduler"); printNoVerify("After PostRAScheduler");
} }
PM.add(createGCMachineCodeAnalysisPass()); PM.add(createGCMachineCodeAnalysisPass());
@ -495,21 +501,21 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
// default currently. Eventually it should subsume CodePlacementOpt, so // default currently. Eventually it should subsume CodePlacementOpt, so
// when enabled, the other is disabled. // when enabled, the other is disabled.
PM.add(createMachineBlockPlacementPass()); PM.add(createMachineBlockPlacementPass());
printNoVerify(PM, "After MachineBlockPlacement"); printNoVerify("After MachineBlockPlacement");
} else { } else {
PM.add(createCodePlacementOptPass()); PM.add(createCodePlacementOptPass());
printNoVerify(PM, "After CodePlacementOpt"); printNoVerify("After CodePlacementOpt");
} }
// Run a separate pass to collect block placement statistics. // Run a separate pass to collect block placement statistics.
if (EnableBlockPlacementStats) { if (EnableBlockPlacementStats) {
PM.add(createMachineBlockPlacementStatsPass()); PM.add(createMachineBlockPlacementStatsPass());
printNoVerify(PM, "After MachineBlockPlacementStats"); printNoVerify("After MachineBlockPlacementStats");
} }
} }
if (addPreEmitPass(PM)) if (addPreEmitPass())
printNoVerify(PM, "After PreEmit passes"); printNoVerify("After PreEmit passes");
return false; return false;
} }

View File

@ -107,33 +107,62 @@ ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT,
: (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) { : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) {
} }
bool ARMBaseTargetMachine::addPreISel(PassManagerBase &PM) { namespace {
if (getOptLevel() != CodeGenOpt::None && EnableGlobalMerge) /// ARM Code Generator Pass Configuration Options.
PM.add(createGlobalMergePass(getTargetLowering())); class ARMPassConfig : public TargetPassConfig {
public:
ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM,
bool DisableVerifyFlag)
: TargetPassConfig(TM, PM, DisableVerifyFlag) {}
ARMBaseTargetMachine &getARMTargetMachine() const {
return getTM<ARMBaseTargetMachine>();
}
const ARMSubtarget &getARMSubtarget() const {
return *getARMTargetMachine().getSubtargetImpl();
}
virtual bool addPreISel();
virtual bool addInstSelector();
virtual bool addPreRegAlloc();
virtual bool addPreSched2();
virtual bool addPreEmitPass();
};
} // namespace
TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM,
bool DisableVerify) {
return new ARMPassConfig(this, PM, DisableVerify);
}
bool ARMPassConfig::addPreISel() {
if (TM->getOptLevel() != CodeGenOpt::None && EnableGlobalMerge)
PM.add(createGlobalMergePass(TM->getTargetLowering()));
return false; return false;
} }
bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM) { bool ARMPassConfig::addInstSelector() {
PM.add(createARMISelDag(*this, getOptLevel())); PM.add(createARMISelDag(getARMTargetMachine(), getOptLevel()));
return false; return false;
} }
bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM) { bool ARMPassConfig::addPreRegAlloc() {
// FIXME: temporarily disabling load / store optimization pass for Thumb1. // FIXME: temporarily disabling load / store optimization pass for Thumb1.
if (getOptLevel() != CodeGenOpt::None && !Subtarget.isThumb1Only()) if (getOptLevel() != CodeGenOpt::None && !getARMSubtarget().isThumb1Only())
PM.add(createARMLoadStoreOptimizationPass(true)); PM.add(createARMLoadStoreOptimizationPass(true));
if (getOptLevel() != CodeGenOpt::None && Subtarget.isCortexA9()) if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA9())
PM.add(createMLxExpansionPass()); PM.add(createMLxExpansionPass());
return true; return true;
} }
bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM) { bool ARMPassConfig::addPreSched2() {
// FIXME: temporarily disabling load / store optimization pass for Thumb1. // FIXME: temporarily disabling load / store optimization pass for Thumb1.
if (getOptLevel() != CodeGenOpt::None) { if (getOptLevel() != CodeGenOpt::None) {
if (!Subtarget.isThumb1Only()) if (!getARMSubtarget().isThumb1Only())
PM.add(createARMLoadStoreOptimizationPass()); PM.add(createARMLoadStoreOptimizationPass());
if (Subtarget.hasNEON()) if (getARMSubtarget().hasNEON())
PM.add(createExecutionDependencyFixPass(&ARM::DPRRegClass)); PM.add(createExecutionDependencyFixPass(&ARM::DPRRegClass));
} }
@ -142,18 +171,18 @@ bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM) {
PM.add(createARMExpandPseudoPass()); PM.add(createARMExpandPseudoPass());
if (getOptLevel() != CodeGenOpt::None) { if (getOptLevel() != CodeGenOpt::None) {
if (!Subtarget.isThumb1Only()) if (!getARMSubtarget().isThumb1Only())
PM.add(createIfConverterPass()); PM.add(createIfConverterPass());
} }
if (Subtarget.isThumb2()) if (getARMSubtarget().isThumb2())
PM.add(createThumb2ITBlockPass()); PM.add(createThumb2ITBlockPass());
return true; return true;
} }
bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM) { bool ARMPassConfig::addPreEmitPass() {
if (Subtarget.isThumb2()) { if (getARMSubtarget().isThumb2()) {
if (!Subtarget.prefers32BitThumb()) if (!getARMSubtarget().prefers32BitThumb())
PM.add(createThumb2SizeReductionPass()); PM.add(createThumb2SizeReductionPass());
// Constant island pass work on unbundled instructions. // Constant island pass work on unbundled instructions.
@ -165,8 +194,7 @@ bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM) {
return true; return true;
} }
bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &JCE) {
JITCodeEmitter &JCE) {
// Machine code emitter pass for ARM. // Machine code emitter pass for ARM.
PM.add(createARMJITCodeEmitterPass(*this, JCE)); PM.add(createARMJITCodeEmitterPass(*this, JCE));
return false; return false;

View File

@ -52,11 +52,8 @@ public:
} }
// Pass Pipeline Configuration // Pass Pipeline Configuration
virtual bool addPreISel(PassManagerBase &PM); virtual TargetPassConfig *createPassConfig(PassManagerBase &PM, bool DisableVerify);
virtual bool addInstSelector(PassManagerBase &PM);
virtual bool addPreRegAlloc(PassManagerBase &PM);
virtual bool addPreSched2(PassManagerBase &PM);
virtual bool addPreEmitPass(PassManagerBase &PM);
virtual bool addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &MCE); virtual bool addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &MCE);
}; };

View File

@ -51,15 +51,36 @@ SPUTargetMachine::SPUTargetMachine(const Target &T, StringRef TT,
// Pass Pipeline Configuration // Pass Pipeline Configuration
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
bool SPUTargetMachine::addInstSelector(PassManagerBase &PM) { namespace {
/// SPU Code Generator Pass Configuration Options.
class SPUPassConfig : public TargetPassConfig {
public:
SPUPassConfig(SPUTargetMachine *TM, PassManagerBase &PM,
bool DisableVerifyFlag)
: TargetPassConfig(TM, PM, DisableVerifyFlag) {}
SPUTargetMachine &getSPUTargetMachine() const {
return getTM<SPUTargetMachine>();
}
virtual bool addInstSelector();
virtual bool addPreEmitPass();
};
} // namespace
TargetPassConfig *SPUTargetMachine::createPassConfig(PassManagerBase &PM,
bool DisableVerify) {
return new SPUPassConfig(this, PM, DisableVerify);
}
bool SPUPassConfig::addInstSelector() {
// Install an instruction selector. // Install an instruction selector.
PM.add(createSPUISelDag(*this)); PM.add(createSPUISelDag(getSPUTargetMachine()));
return false; return false;
} }
// passes to run just before printing the assembly // passes to run just before printing the assembly
bool SPUTargetMachine:: bool SPUPassConfig::addPreEmitPass() {
addPreEmitPass(PassManagerBase &PM) {
// load the TCE instruction scheduler, if available via // load the TCE instruction scheduler, if available via
// loaded plugins // loaded plugins
typedef llvm::FunctionPass* (*BuilderFunc)(const char*); typedef llvm::FunctionPass* (*BuilderFunc)(const char*);
@ -70,6 +91,6 @@ addPreEmitPass(PassManagerBase &PM) {
PM.add(schedulerCreator("cellspu")); PM.add(schedulerCreator("cellspu"));
//align instructions with nops/lnops for dual issue //align instructions with nops/lnops for dual issue
PM.add(createSPUNopFillerPass(*this)); PM.add(createSPUNopFillerPass(getSPUTargetMachine()));
return true; return true;
} }

View File

@ -82,8 +82,8 @@ public:
} }
// Pass Pipeline Configuration // Pass Pipeline Configuration
virtual bool addInstSelector(PassManagerBase &PM); virtual TargetPassConfig *createPassConfig(PassManagerBase &PM,
virtual bool addPreEmitPass(PassManagerBase &); bool DisableVerify);
}; };
} // end namespace llvm } // end namespace llvm

View File

@ -76,14 +76,39 @@ bool HexagonTargetMachine::addPassesForOptimizations(PassManagerBase &PM) {
return true; return true;
} }
bool HexagonTargetMachine::addInstSelector(PassManagerBase &PM) { namespace {
PM.add(createHexagonRemoveExtendOps(*this)); /// Hexagon Code Generator Pass Configuration Options.
PM.add(createHexagonISelDag(*this)); class HexagonPassConfig : public TargetPassConfig {
public:
HexagonPassConfig(HexagonTargetMachine *TM, PassManagerBase &PM,
bool DisableVerifyFlag)
: TargetPassConfig(TM, PM, DisableVerifyFlag) {}
HexagonTargetMachine &getHexagonTargetMachine() const {
return getTM<HexagonTargetMachine>();
}
virtual bool addInstSelector();
virtual bool addPreRegAlloc();
virtual bool addPostRegAlloc();
virtual bool addPreSched2();
virtual bool addPreEmitPass();
};
} // namespace
TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM,
bool DisableVerify) {
return new HexagonPassConfig(this, PM, DisableVerify);
}
bool HexagonPassConfig::addInstSelector() {
PM.add(createHexagonRemoveExtendOps(getHexagonTargetMachine()));
PM.add(createHexagonISelDag(getHexagonTargetMachine()));
return false; return false;
} }
bool HexagonTargetMachine::addPreRegAlloc(PassManagerBase &PM) { bool HexagonPassConfig::addPreRegAlloc() {
if (!DisableHardwareLoops) { if (!DisableHardwareLoops) {
PM.add(createHexagonHardwareLoops()); PM.add(createHexagonHardwareLoops());
} }
@ -91,28 +116,28 @@ bool HexagonTargetMachine::addPreRegAlloc(PassManagerBase &PM) {
return false; return false;
} }
bool HexagonTargetMachine::addPostRegAlloc(PassManagerBase &PM) { bool HexagonPassConfig::addPostRegAlloc() {
PM.add(createHexagonCFGOptimizer(*this)); PM.add(createHexagonCFGOptimizer(getHexagonTargetMachine()));
return true; return true;
} }
bool HexagonTargetMachine::addPreSched2(PassManagerBase &PM) { bool HexagonPassConfig::addPreSched2() {
PM.add(createIfConverterPass()); PM.add(createIfConverterPass());
return true; return true;
} }
bool HexagonTargetMachine::addPreEmitPass(PassManagerBase &PM) { bool HexagonPassConfig::addPreEmitPass() {
if (!DisableHardwareLoops) { if (!DisableHardwareLoops) {
PM.add(createHexagonFixupHwLoops()); PM.add(createHexagonFixupHwLoops());
} }
// Expand Spill code for predicate registers. // Expand Spill code for predicate registers.
PM.add(createHexagonExpandPredSpillCode(*this)); PM.add(createHexagonExpandPredSpillCode(getHexagonTargetMachine()));
// Split up TFRcondsets into conditional transfers. // Split up TFRcondsets into conditional transfers.
PM.add(createHexagonSplitTFRCondSets(*this)); PM.add(createHexagonSplitTFRCondSets(getHexagonTargetMachine()));
return false; return false;
} }

View File

@ -72,11 +72,8 @@ public:
// Pass Pipeline Configuration. // Pass Pipeline Configuration.
virtual bool addPassesForOptimizations(PassManagerBase &PM); virtual bool addPassesForOptimizations(PassManagerBase &PM);
virtual bool addInstSelector(PassManagerBase &PM); virtual TargetPassConfig *createPassConfig(PassManagerBase &PM,
virtual bool addPreEmitPass(PassManagerBase &PM); bool DisableVerify);
virtual bool addPreRegAlloc(llvm::PassManagerBase &PM);
virtual bool addPostRegAlloc(PassManagerBase &PM);
virtual bool addPreSched2(PassManagerBase &PM);
}; };
extern bool flag_aligned_memcpy; extern bool flag_aligned_memcpy;

View File

@ -45,17 +45,39 @@ MBlazeTargetMachine(const Target &T, StringRef TT,
InstrItins(Subtarget.getInstrItineraryData()) { InstrItins(Subtarget.getInstrItineraryData()) {
} }
namespace {
/// MBlaze Code Generator Pass Configuration Options.
class MBlazePassConfig : public TargetPassConfig {
public:
MBlazePassConfig(MBlazeTargetMachine *TM, PassManagerBase &PM,
bool DisableVerifyFlag)
: TargetPassConfig(TM, PM, DisableVerifyFlag) {}
MBlazeTargetMachine &getMBlazeTargetMachine() const {
return getTM<MBlazeTargetMachine>();
}
virtual bool addInstSelector();
virtual bool addPreEmitPass();
};
} // namespace
TargetPassConfig *MBlazeTargetMachine::createPassConfig(PassManagerBase &PM,
bool DisableVerify) {
return new MBlazePassConfig(this, PM, DisableVerify);
}
// Install an instruction selector pass using // Install an instruction selector pass using
// the ISelDag to gen MBlaze code. // the ISelDag to gen MBlaze code.
bool MBlazeTargetMachine::addInstSelector(PassManagerBase &PM) { bool MBlazePassConfig::addInstSelector() {
PM.add(createMBlazeISelDag(*this)); PM.add(createMBlazeISelDag(getMBlazeTargetMachine()));
return false; return false;
} }
// Implemented by targets that want to run passes immediately before // Implemented by targets that want to run passes immediately before
// machine code is emitted. return true if -print-machineinstrs should // machine code is emitted. return true if -print-machineinstrs should
// print out the code after the passes. // print out the code after the passes.
bool MBlazeTargetMachine::addPreEmitPass(PassManagerBase &PM) { bool MBlazePassConfig::addPreEmitPass() {
PM.add(createMBlazeDelaySlotFillerPass(*this)); PM.add(createMBlazeDelaySlotFillerPass(getMBlazeTargetMachine()));
return true; return true;
} }

View File

@ -79,8 +79,8 @@ namespace llvm {
} }
// Pass Pipeline Configuration // Pass Pipeline Configuration
virtual bool addInstSelector(PassManagerBase &PM); virtual TargetPassConfig *createPassConfig(PassManagerBase &PM,
virtual bool addPreEmitPass(PassManagerBase &PM); bool DisableVerify);
}; };
} // End llvm namespace } // End llvm namespace

View File

@ -38,14 +38,35 @@ MSP430TargetMachine::MSP430TargetMachine(const Target &T,
InstrInfo(*this), TLInfo(*this), TSInfo(*this), InstrInfo(*this), TLInfo(*this), TSInfo(*this),
FrameLowering(Subtarget) { } FrameLowering(Subtarget) { }
namespace {
/// MSP430 Code Generator Pass Configuration Options.
class MSP430PassConfig : public TargetPassConfig {
public:
MSP430PassConfig(MSP430TargetMachine *TM, PassManagerBase &PM,
bool DisableVerifyFlag)
: TargetPassConfig(TM, PM, DisableVerifyFlag) {}
bool MSP430TargetMachine::addInstSelector(PassManagerBase &PM) { MSP430TargetMachine &getMSP430TargetMachine() const {
return getTM<MSP430TargetMachine>();
}
virtual bool addInstSelector();
virtual bool addPreEmitPass();
};
} // namespace
TargetPassConfig *MSP430TargetMachine::createPassConfig(PassManagerBase &PM,
bool DisableVerify) {
return new MSP430PassConfig(this, PM, DisableVerify);
}
bool MSP430PassConfig::addInstSelector() {
// Install an instruction selector. // Install an instruction selector.
PM.add(createMSP430ISelDag(*this, getOptLevel())); PM.add(createMSP430ISelDag(getMSP430TargetMachine(), getOptLevel()));
return false; return false;
} }
bool MSP430TargetMachine::addPreEmitPass(PassManagerBase &PM) { bool MSP430PassConfig::addPreEmitPass() {
// Must run branch selection immediately preceding the asm printer. // Must run branch selection immediately preceding the asm printer.
PM.add(createMSP430BranchSelectionPass()); PM.add(createMSP430BranchSelectionPass());
return false; return false;

View File

@ -62,8 +62,8 @@ public:
return &TSInfo; return &TSInfo;
} }
virtual bool addInstSelector(PassManagerBase &PM); virtual TargetPassConfig *createPassConfig(PassManagerBase &PM,
virtual bool addPreEmitPass(PassManagerBase &PM); bool DisableVerify);
}; // MSP430TargetMachine. }; // MSP430TargetMachine.
} // end namespace llvm } // end namespace llvm

View File

@ -14,6 +14,7 @@
#include "Mips.h" #include "Mips.h"
#include "MipsTargetMachine.h" #include "MipsTargetMachine.h"
#include "llvm/PassManager.h" #include "llvm/PassManager.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetRegistry.h"
using namespace llvm; using namespace llvm;
@ -88,37 +89,61 @@ Mips64elTargetMachine(const Target &T, StringRef TT,
CodeGenOpt::Level OL) CodeGenOpt::Level OL)
: MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
namespace {
/// Mips Code Generator Pass Configuration Options.
class MipsPassConfig : public TargetPassConfig {
public:
MipsPassConfig(MipsTargetMachine *TM, PassManagerBase &PM,
bool DisableVerifyFlag)
: TargetPassConfig(TM, PM, DisableVerifyFlag) {}
MipsTargetMachine &getMipsTargetMachine() const {
return getTM<MipsTargetMachine>();
}
const MipsSubtarget &getMipsSubtarget() const {
return *getMipsTargetMachine().getSubtargetImpl();
}
virtual bool addInstSelector();
virtual bool addPreRegAlloc();
virtual bool addPostRegAlloc();
virtual bool addPreEmitPass();
};
} // namespace
TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM,
bool DisableVerify) {
return new MipsPassConfig(this, PM, DisableVerify);
}
// Install an instruction selector pass using // Install an instruction selector pass using
// the ISelDag to gen Mips code. // the ISelDag to gen Mips code.
bool MipsTargetMachine:: bool MipsPassConfig::addInstSelector()
addInstSelector(PassManagerBase &PM)
{ {
PM.add(createMipsISelDag(*this)); PM.add(createMipsISelDag(getMipsTargetMachine()));
return false; return false;
} }
// Implemented by targets that want to run passes immediately before // Implemented by targets that want to run passes immediately before
// machine code is emitted. return true if -print-machineinstrs should // machine code is emitted. return true if -print-machineinstrs should
// print out the code after the passes. // print out the code after the passes.
bool MipsTargetMachine:: bool MipsPassConfig::addPreEmitPass()
addPreEmitPass(PassManagerBase &PM)
{ {
PM.add(createMipsDelaySlotFillerPass(*this)); PM.add(createMipsDelaySlotFillerPass(getMipsTargetMachine()));
return true; return true;
} }
bool MipsTargetMachine:: bool MipsPassConfig::addPreRegAlloc() {
addPreRegAlloc(PassManagerBase &PM) {
// Do not restore $gp if target is Mips64. // Do not restore $gp if target is Mips64.
// In N32/64, $gp is a callee-saved register. // In N32/64, $gp is a callee-saved register.
if (!Subtarget.hasMips64()) if (!getMipsSubtarget().hasMips64())
PM.add(createMipsEmitGPRestorePass(*this)); PM.add(createMipsEmitGPRestorePass(getMipsTargetMachine()));
return true; return true;
} }
bool MipsTargetMachine:: bool MipsPassConfig::addPostRegAlloc() {
addPostRegAlloc(PassManagerBase &PM) { PM.add(createMipsExpandPseudoPass(getMipsTargetMachine()));
PM.add(createMipsExpandPseudoPass(*this));
return true; return true;
} }

View File

@ -68,10 +68,8 @@ namespace llvm {
} }
// Pass Pipeline Configuration // Pass Pipeline Configuration
virtual bool addInstSelector(PassManagerBase &PM); virtual TargetPassConfig *createPassConfig(PassManagerBase &PM,
virtual bool addPreEmitPass(PassManagerBase &PM); bool DisableVerify);
virtual bool addPreRegAlloc(PassManagerBase &PM);
virtual bool addPostRegAlloc(PassManagerBase &);
virtual bool addCodeEmitter(PassManagerBase &PM, virtual bool addCodeEmitter(PassManagerBase &PM,
JITCodeEmitter &JCE); JITCodeEmitter &JCE);

View File

@ -105,14 +105,36 @@ PTX64TargetMachine::PTX64TargetMachine(const Target &T, StringRef TT,
: PTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) { : PTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {
} }
bool PTXTargetMachine::addInstSelector(PassManagerBase &PM) { namespace {
PM.add(createPTXISelDag(*this, getOptLevel())); /// PTX Code Generator Pass Configuration Options.
class PTXPassConfig : public TargetPassConfig {
public:
PTXPassConfig(PTXTargetMachine *TM, PassManagerBase &PM, bool DisableVerifyFlag)
: TargetPassConfig(TM, PM, DisableVerifyFlag) {}
PTXTargetMachine &getPTXTargetMachine() const {
return getTM<PTXTargetMachine>();
}
bool addInstSelector();
bool addPostRegAlloc();
bool addCodeGenPasses(MCContext *&OutContext);
};
} // namespace
TargetPassConfig *PTXTargetMachine::createPassConfig(PassManagerBase &PM,
bool DisableVerify) {
return new PTXPassConfig(this, PM, DisableVerify);
}
bool PTXPassConfig::addInstSelector() {
PM.add(createPTXISelDag(getPTXTargetMachine(), getOptLevel()));
return false; return false;
} }
bool PTXTargetMachine::addPostRegAlloc(PassManagerBase &PM) { bool PTXPassConfig::addPostRegAlloc() {
// PTXMFInfoExtract must after register allocation! // PTXMFInfoExtract must after register allocation!
//PM.add(createPTXMFInfoExtract(*this)); //PM.add(createPTXMFInfoExtract(getPTXTargetMachine()));
return false; return false;
} }
@ -124,7 +146,8 @@ bool PTXTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
// Add common CodeGen passes. // Add common CodeGen passes.
MCContext *Context = 0; MCContext *Context = 0;
if (addCommonCodeGenPasses(PM, DisableVerify, Context)) OwningPtr<TargetPassConfig> PassConfig(createPassConfig(PM, DisableVerify));
if (PassConfig->addCodeGenPasses(Context))
return true; return true;
assert(Context != 0 && "Failed to get MCContext"); assert(Context != 0 && "Failed to get MCContext");
@ -179,9 +202,7 @@ bool PTXTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
return false; return false;
} }
bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, bool PTXPassConfig::addCodeGenPasses(MCContext *&OutContext) {
bool DisableVerify,
MCContext *&OutContext) {
// Add standard LLVM codegen passes. // Add standard LLVM codegen passes.
// This is derived from LLVMTargetMachine::addCommonCodeGenPasses, with some // This is derived from LLVMTargetMachine::addCommonCodeGenPasses, with some
// modifications for the PTX target. // modifications for the PTX target.
@ -220,7 +241,7 @@ bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
PM.add(createStackProtectorPass(getTargetLowering())); PM.add(createStackProtectorPass(getTargetLowering()));
addPreISel(PM); addPreISel();
//PM.add(createPrintFunctionPass("\n\n" //PM.add(createPrintFunctionPass("\n\n"
// "*** Final LLVM Code input to ISel ***\n", // "*** Final LLVM Code input to ISel ***\n",
@ -235,21 +256,21 @@ bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
// Install a MachineModuleInfo class, which is an immutable pass that holds // Install a MachineModuleInfo class, which is an immutable pass that holds
// all the per-module stuff we're generating, including MCContext. // all the per-module stuff we're generating, including MCContext.
MachineModuleInfo *MMI = new MachineModuleInfo(*getMCAsmInfo(), MachineModuleInfo *MMI = new MachineModuleInfo(*TM->getMCAsmInfo(),
*getRegisterInfo(), *TM->getRegisterInfo(),
&getTargetLowering()->getObjFileLowering()); &getTargetLowering()->getObjFileLowering());
PM.add(MMI); PM.add(MMI);
OutContext = &MMI->getContext(); // Return the MCContext specifically by-ref. OutContext = &MMI->getContext(); // Return the MCContext specifically by-ref.
// Set up a MachineFunction for the rest of CodeGen to work on. // Set up a MachineFunction for the rest of CodeGen to work on.
PM.add(new MachineFunctionAnalysis(*this)); PM.add(new MachineFunctionAnalysis(*TM));
// Ask the target for an isel. // Ask the target for an isel.
if (addInstSelector(PM)) if (addInstSelector())
return true; return true;
// Print the instruction selected machine code... // Print the instruction selected machine code...
printAndVerify(PM, "After Instruction Selection"); printAndVerify("After Instruction Selection");
// Expand pseudo-instructions emitted by ISel. // Expand pseudo-instructions emitted by ISel.
PM.add(createExpandISelPseudosPass()); PM.add(createExpandISelPseudosPass());
@ -257,7 +278,7 @@ bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
// Pre-ra tail duplication. // Pre-ra tail duplication.
if (getOptLevel() != CodeGenOpt::None) { if (getOptLevel() != CodeGenOpt::None) {
PM.add(createTailDuplicatePass(true)); PM.add(createTailDuplicatePass(true));
printAndVerify(PM, "After Pre-RegAlloc TailDuplicate"); printAndVerify("After Pre-RegAlloc TailDuplicate");
} }
// Optimize PHIs before DCE: removing dead PHI cycles may make more // Optimize PHIs before DCE: removing dead PHI cycles may make more
@ -275,24 +296,24 @@ bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
// used by tail calls, where the tail calls reuse the incoming stack // used by tail calls, where the tail calls reuse the incoming stack
// arguments directly (see t11 in test/CodeGen/X86/sibcall.ll). // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
PM.add(createDeadMachineInstructionElimPass()); PM.add(createDeadMachineInstructionElimPass());
printAndVerify(PM, "After codegen DCE pass"); printAndVerify("After codegen DCE pass");
PM.add(createMachineLICMPass()); PM.add(createMachineLICMPass());
PM.add(createMachineCSEPass()); PM.add(createMachineCSEPass());
PM.add(createMachineSinkingPass()); PM.add(createMachineSinkingPass());
printAndVerify(PM, "After Machine LICM, CSE and Sinking passes"); printAndVerify("After Machine LICM, CSE and Sinking passes");
PM.add(createPeepholeOptimizerPass()); PM.add(createPeepholeOptimizerPass());
printAndVerify(PM, "After codegen peephole optimization pass"); printAndVerify("After codegen peephole optimization pass");
} }
// Run pre-ra passes. // Run pre-ra passes.
if (addPreRegAlloc(PM)) if (addPreRegAlloc())
printAndVerify(PM, "After PreRegAlloc passes"); printAndVerify("After PreRegAlloc passes");
// Perform register allocation. // Perform register allocation.
PM.add(createPTXRegisterAllocator()); PM.add(createPTXRegisterAllocator());
printAndVerify(PM, "After Register Allocation"); printAndVerify("After Register Allocation");
// Perform stack slot coloring and post-ra machine LICM. // Perform stack slot coloring and post-ra machine LICM.
if (getOptLevel() != CodeGenOpt::None) { if (getOptLevel() != CodeGenOpt::None) {
@ -305,40 +326,40 @@ bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
//if (!DisablePostRAMachineLICM) //if (!DisablePostRAMachineLICM)
// PM.add(createMachineLICMPass(false)); // PM.add(createMachineLICMPass(false));
printAndVerify(PM, "After StackSlotColoring and postra Machine LICM"); printAndVerify("After StackSlotColoring and postra Machine LICM");
} }
// Run post-ra passes. // Run post-ra passes.
if (addPostRegAlloc(PM)) if (addPostRegAlloc())
printAndVerify(PM, "After PostRegAlloc passes"); printAndVerify("After PostRegAlloc passes");
PM.add(createExpandPostRAPseudosPass()); PM.add(createExpandPostRAPseudosPass());
printAndVerify(PM, "After ExpandPostRAPseudos"); printAndVerify("After ExpandPostRAPseudos");
// Insert prolog/epilog code. Eliminate abstract frame index references... // Insert prolog/epilog code. Eliminate abstract frame index references...
PM.add(createPrologEpilogCodeInserter()); PM.add(createPrologEpilogCodeInserter());
printAndVerify(PM, "After PrologEpilogCodeInserter"); printAndVerify("After PrologEpilogCodeInserter");
// Run pre-sched2 passes. // Run pre-sched2 passes.
if (addPreSched2(PM)) if (addPreSched2())
printAndVerify(PM, "After PreSched2 passes"); printAndVerify("After PreSched2 passes");
// Second pass scheduler. // Second pass scheduler.
if (getOptLevel() != CodeGenOpt::None) { if (getOptLevel() != CodeGenOpt::None) {
PM.add(createPostRAScheduler(getOptLevel())); PM.add(createPostRAScheduler(getOptLevel()));
printAndVerify(PM, "After PostRAScheduler"); printAndVerify("After PostRAScheduler");
} }
// Branch folding must be run after regalloc and prolog/epilog insertion. // Branch folding must be run after regalloc and prolog/epilog insertion.
if (getOptLevel() != CodeGenOpt::None) { if (getOptLevel() != CodeGenOpt::None) {
PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));
printNoVerify(PM, "After BranchFolding"); printNoVerify("After BranchFolding");
} }
// Tail duplication. // Tail duplication.
if (getOptLevel() != CodeGenOpt::None) { if (getOptLevel() != CodeGenOpt::None) {
PM.add(createTailDuplicatePass(false)); PM.add(createTailDuplicatePass(false));
printNoVerify(PM, "After TailDuplicate"); printNoVerify("After TailDuplicate");
} }
PM.add(createGCMachineCodeAnalysisPass()); PM.add(createGCMachineCodeAnalysisPass());
@ -348,14 +369,14 @@ bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
if (getOptLevel() != CodeGenOpt::None) { if (getOptLevel() != CodeGenOpt::None) {
PM.add(createCodePlacementOptPass()); PM.add(createCodePlacementOptPass());
printNoVerify(PM, "After CodePlacementOpt"); printNoVerify("After CodePlacementOpt");
} }
if (addPreEmitPass(PM)) if (addPreEmitPass())
printNoVerify(PM, "After PreEmit passes"); printNoVerify("After PreEmit passes");
PM.add(createPTXMFInfoExtract(*this, getOptLevel())); PM.add(createPTXMFInfoExtract(getPTXTargetMachine(), getOptLevel()));
PM.add(createPTXFPRoundingModePass(*this, getOptLevel())); PM.add(createPTXFPRoundingModePass(getPTXTargetMachine(), getOptLevel()));
return false; return false;
} }

View File

@ -59,9 +59,6 @@ class PTXTargetMachine : public LLVMTargetMachine {
virtual const PTXSubtarget *getSubtargetImpl() const { return &Subtarget; } virtual const PTXSubtarget *getSubtargetImpl() const { return &Subtarget; }
virtual bool addInstSelector(PassManagerBase &PM);
virtual bool addPostRegAlloc(PassManagerBase &PM);
// We override this method to supply our own set of codegen passes. // We override this method to supply our own set of codegen passes.
virtual bool addPassesToEmitFile(PassManagerBase &, virtual bool addPassesToEmitFile(PassManagerBase &,
formatted_raw_ostream &, formatted_raw_ostream &,
@ -83,10 +80,9 @@ class PTXTargetMachine : public LLVMTargetMachine {
return true; return true;
} }
private: // Pass Pipeline Configuration
virtual TargetPassConfig *createPassConfig(PassManagerBase &PM,
bool addCommonCodeGenPasses(PassManagerBase &, bool DisableVerify);
bool DisableVerify, MCContext *&OutCtx);
}; // class PTXTargetMachine }; // class PTXTargetMachine

View File

@ -15,6 +15,7 @@
#include "PPCTargetMachine.h" #include "PPCTargetMachine.h"
#include "llvm/PassManager.h" #include "llvm/PassManager.h"
#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCStreamer.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetOptions.h"
#include "llvm/Support/FormattedStream.h" #include "llvm/Support/FormattedStream.h"
#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetRegistry.h"
@ -40,10 +41,6 @@ PPCTargetMachine::PPCTargetMachine(const Target &T, StringRef TT,
InstrItins(Subtarget.getInstrItineraryData()) { InstrItins(Subtarget.getInstrItineraryData()) {
} }
/// Override this for PowerPC. Tail merging happily breaks up instruction issue
/// groups, which typically degrades performance.
bool PPCTargetMachine::getEnableTailMergeDefault() const { return false; }
void PPC32TargetMachine::anchor() { } void PPC32TargetMachine::anchor() { }
PPC32TargetMachine::PPC32TargetMachine(const Target &T, StringRef TT, PPC32TargetMachine::PPC32TargetMachine(const Target &T, StringRef TT,
@ -69,13 +66,40 @@ PPC64TargetMachine::PPC64TargetMachine(const Target &T, StringRef TT,
// Pass Pipeline Configuration // Pass Pipeline Configuration
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
bool PPCTargetMachine::addInstSelector(PassManagerBase &PM) { namespace {
/// PPC Code Generator Pass Configuration Options.
class PPCPassConfig : public TargetPassConfig {
public:
PPCPassConfig(PPCTargetMachine *TM, PassManagerBase &PM,
bool DisableVerifyFlag)
: TargetPassConfig(TM, PM, DisableVerifyFlag) {}
PPCTargetMachine &getPPCTargetMachine() const {
return getTM<PPCTargetMachine>();
}
virtual bool addInstSelector();
virtual bool getEnableTailMergeDefault() const;
virtual bool addPreEmitPass();
};
} // namespace
TargetPassConfig *PPCTargetMachine::createPassConfig(PassManagerBase &PM,
bool DisableVerify) {
return new PPCPassConfig(this, PM, DisableVerify);
}
bool PPCPassConfig::addInstSelector() {
// Install an instruction selector. // Install an instruction selector.
PM.add(createPPCISelDag(*this)); PM.add(createPPCISelDag(getPPCTargetMachine()));
return false; return false;
} }
bool PPCTargetMachine::addPreEmitPass(PassManagerBase &PM) { /// Override this for PowerPC. Tail merging happily breaks up instruction issue
/// groups, which typically degrades performance.
bool PPCPassConfig::getEnableTailMergeDefault() const { return false; }
bool PPCPassConfig::addPreEmitPass() {
// Must run branch selection immediately preceding the asm printer. // Must run branch selection immediately preceding the asm printer.
PM.add(createPPCBranchSelectionPass()); PM.add(createPPCBranchSelectionPass());
return false; return false;

View File

@ -67,11 +67,10 @@ public:
} }
// Pass Pipeline Configuration // Pass Pipeline Configuration
virtual bool addInstSelector(PassManagerBase &PM); virtual TargetPassConfig *createPassConfig(PassManagerBase &PM,
virtual bool addPreEmitPass(PassManagerBase &PM); bool DisableVerify);
virtual bool addCodeEmitter(PassManagerBase &PM, virtual bool addCodeEmitter(PassManagerBase &PM,
JITCodeEmitter &JCE); JITCodeEmitter &JCE);
virtual bool getEnableTailMergeDefault() const;
}; };
/// PPC32TargetMachine - PowerPC 32-bit target machine. /// PPC32TargetMachine - PowerPC 32-bit target machine.

View File

@ -13,6 +13,7 @@
#include "Sparc.h" #include "Sparc.h"
#include "SparcTargetMachine.h" #include "SparcTargetMachine.h"
#include "llvm/PassManager.h" #include "llvm/PassManager.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetRegistry.h"
using namespace llvm; using namespace llvm;
@ -37,17 +38,39 @@ SparcTargetMachine::SparcTargetMachine(const Target &T, StringRef TT,
FrameLowering(Subtarget) { FrameLowering(Subtarget) {
} }
bool SparcTargetMachine::addInstSelector(PassManagerBase &PM) { namespace {
PM.add(createSparcISelDag(*this)); /// Sparc Code Generator Pass Configuration Options.
class SparcPassConfig : public TargetPassConfig {
public:
SparcPassConfig(SparcTargetMachine *TM, PassManagerBase &PM,
bool DisableVerifyFlag)
: TargetPassConfig(TM, PM, DisableVerifyFlag) {}
SparcTargetMachine &getSparcTargetMachine() const {
return getTM<SparcTargetMachine>();
}
virtual bool addInstSelector();
virtual bool addPreEmitPass();
};
} // namespace
TargetPassConfig *SparcTargetMachine::createPassConfig(PassManagerBase &PM,
bool DisableVerify) {
return new SparcPassConfig(this, PM, DisableVerify);
}
bool SparcPassConfig::addInstSelector() {
PM.add(createSparcISelDag(getSparcTargetMachine()));
return false; return false;
} }
/// 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.
bool SparcTargetMachine::addPreEmitPass(PassManagerBase &PM){ bool SparcPassConfig::addPreEmitPass(){
PM.add(createSparcFPMoverPass(*this)); PM.add(createSparcFPMoverPass(getSparcTargetMachine()));
PM.add(createSparcDelaySlotFillerPass(*this)); PM.add(createSparcDelaySlotFillerPass(getSparcTargetMachine()));
return true; return true;
} }

View File

@ -55,8 +55,8 @@ public:
virtual const TargetData *getTargetData() const { return &DataLayout; } virtual const TargetData *getTargetData() const { return &DataLayout; }
// Pass Pipeline Configuration // Pass Pipeline Configuration
virtual bool addInstSelector(PassManagerBase &PM); virtual TargetPassConfig *createPassConfig(PassManagerBase &PM,
virtual bool addPreEmitPass(PassManagerBase &PM); bool DisableVerify);
}; };
/// SparcV8TargetMachine - Sparc 32-bit target machine /// SparcV8TargetMachine - Sparc 32-bit target machine

View File

@ -117,35 +117,63 @@ UseVZeroUpper("x86-use-vzeroupper",
// Pass Pipeline Configuration // Pass Pipeline Configuration
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
bool X86TargetMachine::addInstSelector(PassManagerBase &PM) { namespace {
/// X86 Code Generator Pass Configuration Options.
class X86PassConfig : public TargetPassConfig {
public:
X86PassConfig(X86TargetMachine *TM, PassManagerBase &PM,
bool DisableVerifyFlag)
: TargetPassConfig(TM, PM, DisableVerifyFlag) {}
X86TargetMachine &getX86TargetMachine() const {
return getTM<X86TargetMachine>();
}
const X86Subtarget &getX86Subtarget() const {
return *getX86TargetMachine().getSubtargetImpl();
}
virtual bool addInstSelector();
virtual bool addPreRegAlloc();
virtual bool addPostRegAlloc();
virtual bool addPreEmitPass();
};
} // namespace
TargetPassConfig *X86TargetMachine::createPassConfig(PassManagerBase &PM,
bool DisableVerify) {
return new X86PassConfig(this, PM, DisableVerify);
}
bool X86PassConfig::addInstSelector() {
// Install an instruction selector. // Install an instruction selector.
PM.add(createX86ISelDag(*this, getOptLevel())); PM.add(createX86ISelDag(getX86TargetMachine(), getOptLevel()));
// For 32-bit, prepend instructions to set the "global base reg" for PIC. // For 32-bit, prepend instructions to set the "global base reg" for PIC.
if (!Subtarget.is64Bit()) if (!getX86Subtarget().is64Bit())
PM.add(createGlobalBaseRegPass()); PM.add(createGlobalBaseRegPass());
return false; return false;
} }
bool X86TargetMachine::addPreRegAlloc(PassManagerBase &PM) { bool X86PassConfig::addPreRegAlloc() {
PM.add(createX86MaxStackAlignmentHeuristicPass()); PM.add(createX86MaxStackAlignmentHeuristicPass());
return false; // -print-machineinstr shouldn't print after this. return false; // -print-machineinstr shouldn't print after this.
} }
bool X86TargetMachine::addPostRegAlloc(PassManagerBase &PM) { bool X86PassConfig::addPostRegAlloc() {
PM.add(createX86FloatingPointStackifierPass()); PM.add(createX86FloatingPointStackifierPass());
return true; // -print-machineinstr should print after this. return true; // -print-machineinstr should print after this.
} }
bool X86TargetMachine::addPreEmitPass(PassManagerBase &PM) { bool X86PassConfig::addPreEmitPass() {
bool ShouldPrint = false; bool ShouldPrint = false;
if (getOptLevel() != CodeGenOpt::None && Subtarget.hasSSE2()) { if (getOptLevel() != CodeGenOpt::None && getX86Subtarget().hasSSE2()) {
PM.add(createExecutionDependencyFixPass(&X86::VR128RegClass)); PM.add(createExecutionDependencyFixPass(&X86::VR128RegClass));
ShouldPrint = true; ShouldPrint = true;
} }
if (Subtarget.hasAVX() && UseVZeroUpper) { if (getX86Subtarget().hasAVX() && UseVZeroUpper) {
PM.add(createX86IssueVZeroUpperPass()); PM.add(createX86IssueVZeroUpperPass());
ShouldPrint = true; ShouldPrint = true;
} }

View File

@ -71,10 +71,9 @@ public:
} }
// Set up the pass pipeline. // Set up the pass pipeline.
virtual bool addInstSelector(PassManagerBase &PM); virtual TargetPassConfig *createPassConfig(PassManagerBase &PM,
virtual bool addPreRegAlloc(PassManagerBase &PM); bool DisableVerify);
virtual bool addPostRegAlloc(PassManagerBase &PM);
virtual bool addPreEmitPass(PassManagerBase &PM);
virtual bool addCodeEmitter(PassManagerBase &PM, virtual bool addCodeEmitter(PassManagerBase &PM,
JITCodeEmitter &JCE); JITCodeEmitter &JCE);
}; };

View File

@ -14,6 +14,7 @@
#include "XCore.h" #include "XCore.h"
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/PassManager.h" #include "llvm/PassManager.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetRegistry.h"
using namespace llvm; using namespace llvm;
@ -34,8 +35,29 @@ XCoreTargetMachine::XCoreTargetMachine(const Target &T, StringRef TT,
TSInfo(*this) { TSInfo(*this) {
} }
bool XCoreTargetMachine::addInstSelector(PassManagerBase &PM) { namespace {
PM.add(createXCoreISelDag(*this, getOptLevel())); /// XCore Code Generator Pass Configuration Options.
class XCorePassConfig : public TargetPassConfig {
public:
XCorePassConfig(XCoreTargetMachine *TM, PassManagerBase &PM,
bool DisableVerifyFlag)
: TargetPassConfig(TM, PM, DisableVerifyFlag) {}
XCoreTargetMachine &getXCoreTargetMachine() const {
return getTM<XCoreTargetMachine>();
}
virtual bool addInstSelector();
};
} // namespace
TargetPassConfig *XCoreTargetMachine::createPassConfig(PassManagerBase &PM,
bool DisableVerify) {
return new XCorePassConfig(this, PM, DisableVerify);
}
bool XCorePassConfig::addInstSelector() {
PM.add(createXCoreISelDag(getXCoreTargetMachine(), getOptLevel()));
return false; return false;
} }

View File

@ -56,7 +56,8 @@ public:
virtual const TargetData *getTargetData() const { return &DataLayout; } virtual const TargetData *getTargetData() const { return &DataLayout; }
// Pass Pipeline Configuration // Pass Pipeline Configuration
virtual bool addInstSelector(PassManagerBase &PM); virtual TargetPassConfig *createPassConfig(PassManagerBase &PM,
bool DisableVerify);
}; };
} // end namespace llvm } // end namespace llvm