TargetPassConfig: confine the MC configuration to TargetMachine.
Passes prior to instructon selection are now split into separate configurable stages.
Header dependencies are simplified.
The bulk of this diff is simply removal of the silly DisableVerify flags.
Sorry for the target header churn. Attempting to stabilize them.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149754 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index b10dab4..de69526 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -11,18 +11,24 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/Scalar.h"
#include "llvm/PassManager.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineFunctionAnalysis.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
@@ -30,6 +36,13 @@
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
+// Enable or disable FastISel. Both options are needed, because
+// FastISel is enabled by default with -fast, and we wish to be
+// able to enable or disable fast-isel independently from -O0.
+static cl::opt<cl::boolOrDefault>
+EnableFastISelOption("fast-isel", cl::Hidden,
+ cl::desc("Enable the \"fast\" instruction selector"));
+
static cl::opt<bool> ShowMCEncoding("show-mc-encoding", cl::Hidden,
cl::desc("Show encoding in .s output"));
static cl::opt<bool> ShowMCInst("show-mc-inst", cl::Hidden,
@@ -65,17 +78,84 @@
"and that InitializeAllTargetMCs() is being invoked!");
}
+/// Turn exception handling constructs into something the code generators can
+/// handle.
+static void addPassesToHandleExceptions(TargetMachine *TM,
+ PassManagerBase &PM) {
+ switch (TM->getMCAsmInfo()->getExceptionHandlingType()) {
+ case ExceptionHandling::SjLj:
+ // 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,
+ // catch info can get misplaced when a selector ends up more than one block
+ // removed from the parent invoke(s). This could happen when a landing
+ // pad is shared by multiple invokes and is also a target of a normal
+ // edge from elsewhere.
+ PM.add(createSjLjEHPass(TM->getTargetLowering()));
+ // FALLTHROUGH
+ case ExceptionHandling::DwarfCFI:
+ case ExceptionHandling::ARM:
+ case ExceptionHandling::Win64:
+ PM.add(createDwarfEHPass(TM));
+ break;
+ case ExceptionHandling::None:
+ PM.add(createLowerInvokePass(TM->getTargetLowering()));
+
+ // The lower invoke pass may create unreachable code. Remove it.
+ PM.add(createUnreachableBlockEliminationPass());
+ break;
+ }
+}
+
+/// addPassesToX helper drives creation and initialization of TargetPassConfig.
+static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM,
+ PassManagerBase &PM,
+ bool DisableVerify) {
+ // Targets may override createPassConfig to provide a target-specific sublass.
+ TargetPassConfig *PassConfig = TM->createPassConfig(PM);
+
+ // Set PassConfig options provided by TargetMachine.
+ PassConfig->setDisableVerify(DisableVerify);
+
+ PassConfig->addIRPasses();
+
+ addPassesToHandleExceptions(TM, PM);
+
+ PassConfig->addISelPrepare();
+
+ // Install a MachineModuleInfo class, which is an immutable pass that holds
+ // all the per-module stuff we're generating, including MCContext.
+ MachineModuleInfo *MMI =
+ new MachineModuleInfo(*TM->getMCAsmInfo(), *TM->getRegisterInfo(),
+ &TM->getTargetLowering()->getObjFileLowering());
+ PM.add(MMI);
+ MCContext *Context = &MMI->getContext(); // Return the MCContext specifically by-ref.
+
+ // Set up a MachineFunction for the rest of CodeGen to work on.
+ PM.add(new MachineFunctionAnalysis(*TM));
+
+ // Enable FastISel with -fast, but allow that to be overridden.
+ if (EnableFastISelOption == cl::BOU_TRUE ||
+ (TM->getOptLevel() == CodeGenOpt::None &&
+ EnableFastISelOption != cl::BOU_FALSE))
+ TM->setFastISel(true);
+
+ // Ask the target for an isel.
+ if (PassConfig->addInstSelector())
+ return NULL;
+
+ PassConfig->addMachinePasses();
+
+ return Context;
+}
+
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
formatted_raw_ostream &Out,
CodeGenFileType FileType,
bool DisableVerify) {
// Add common CodeGen passes.
- MCContext *Context = 0;
- TargetPassConfig *PassConfig = createPassConfig(PM, DisableVerify);
- PM.add(PassConfig);
- if (PassConfig->addCodeGenPasses(Context))
+ MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify);
+ if (!Context)
return true;
- assert(Context != 0 && "Failed to get MCContext");
if (hasMCSaveTempLabels())
Context->setAllowTemporaryLabels(false);
@@ -156,9 +236,8 @@
JITCodeEmitter &JCE,
bool DisableVerify) {
// Add common CodeGen passes.
- MCContext *Ctx = 0;
- OwningPtr<TargetPassConfig> PassConfig(createPassConfig(PM, DisableVerify));
- if (PassConfig->addCodeGenPasses(Ctx))
+ MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify);
+ if (!Context)
return true;
addCodeEmitter(PM, JCE);
@@ -177,8 +256,8 @@
raw_ostream &Out,
bool DisableVerify) {
// Add common CodeGen passes.
- OwningPtr<TargetPassConfig> PassConfig(createPassConfig(PM, DisableVerify));
- if (PassConfig->addCodeGenPasses(Ctx))
+ Ctx = addPassesToGenerateCode(this, PM, DisableVerify);
+ if (!Ctx)
return true;
if (hasMCSaveTempLabels())
diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp
index 739ff60..21d8714 100644
--- a/lib/CodeGen/Passes.cpp
+++ b/lib/CodeGen/Passes.cpp
@@ -17,16 +17,11 @@
#include "llvm/Transforms/Scalar.h"
#include "llvm/PassManager.h"
#include "llvm/CodeGen/GCStrategy.h"
-#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/Target/TargetLowering.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -77,13 +72,6 @@
cl::desc("Verify generated machine code"),
cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL));
-// Enable or disable FastISel. Both options are needed, because
-// FastISel is enabled by default with -fast, and we wish to be
-// able to enable or disable fast-isel independently from -O0.
-static cl::opt<cl::boolOrDefault>
-EnableFastISelOption("fast-isel", cl::Hidden,
- cl::desc("Enable the \"fast\" instruction selector"));
-
//===---------------------------------------------------------------------===//
/// TargetPassConfig
//===---------------------------------------------------------------------===//
@@ -95,9 +83,8 @@
// Out of line virtual method.
TargetPassConfig::~TargetPassConfig() {}
-TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm,
- bool DisableVerifyFlag)
- : ImmutablePass(ID), TM(tm), PM(pm), DisableVerify(DisableVerifyFlag) {
+TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm)
+ : ImmutablePass(ID), TM(tm), PM(pm), DisableVerify(false) {
// Register all target independent codegen passes to activate their PassIDs,
// including this pass itself.
initializeCodeGen(*PassRegistry::getPassRegistry());
@@ -107,9 +94,8 @@
/// addPassToEmitX methods for generating a pipeline of CodeGen passes.
///
/// Targets may override this to extend TargetPassConfig.
-TargetPassConfig *LLVMTargetMachine::createPassConfig(PassManagerBase &PM,
- bool DisableVerify) {
- return new TargetPassConfig(this, PM, DisableVerify);
+TargetPassConfig *LLVMTargetMachine::createPassConfig(PassManagerBase &PM) {
+ return new TargetPassConfig(this, PM);
}
TargetPassConfig::TargetPassConfig()
@@ -117,6 +103,9 @@
llvm_unreachable("TargetPassConfig should not be constructed on-the-fly");
}
+void TargetPassConfig::addCommonPass(char &ID) {
+ // FIXME: about to be implemented.
+}
void TargetPassConfig::printNoVerify(const char *Banner) const {
if (TM->shouldPrintMachineCode())
@@ -131,12 +120,9 @@
PM.add(createMachineVerifierPass(Banner));
}
-/// addCodeGenPasses - Add standard LLVM codegen passes used for both
-/// emitting to assembly files or machine code output.
-///
-bool TargetPassConfig::addCodeGenPasses(MCContext *&OutContext) {
- // Standard LLVM-Level Passes.
-
+/// Add common target configurable passes that perform LLVM IR to IR transforms
+/// following machine independent optimization.
+void TargetPassConfig::addIRPasses() {
// Basic AliasAnalysis support.
// Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
// BasicAliasAnalysis wins if they disagree. This is intended to help
@@ -160,32 +146,11 @@
// Make sure that no unreachable blocks are instruction selected.
PM.add(createUnreachableBlockEliminationPass());
+}
- // Turn exception handling constructs into something the code generators can
- // handle.
- switch (TM->getMCAsmInfo()->getExceptionHandlingType()) {
- case ExceptionHandling::SjLj:
- // 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,
- // catch info can get misplaced when a selector ends up more than one block
- // removed from the parent invoke(s). This could happen when a landing
- // pad is shared by multiple invokes and is also a target of a normal
- // edge from elsewhere.
- PM.add(createSjLjEHPass(getTargetLowering()));
- // FALLTHROUGH
- case ExceptionHandling::DwarfCFI:
- case ExceptionHandling::ARM:
- case ExceptionHandling::Win64:
- PM.add(createDwarfEHPass(TM));
- break;
- case ExceptionHandling::None:
- PM.add(createLowerInvokePass(getTargetLowering()));
-
- // The lower invoke pass may create unreachable code. Remove it.
- PM.add(createUnreachableBlockEliminationPass());
- break;
- }
-
+/// Add common passes that perform LLVM IR to IR transforms in preparation for
+/// instruction selection.
+void TargetPassConfig::addISelPrepare() {
if (getOptLevel() != CodeGenOpt::None && !DisableCGP)
PM.add(createCodeGenPreparePass(getTargetLowering()));
@@ -202,30 +167,9 @@
// to ensure that the IR is valid.
if (!DisableVerify)
PM.add(createVerifierPass());
+}
- // Standard Lower-Level Passes.
-
- // Install a MachineModuleInfo class, which is an immutable pass that holds
- // all the per-module stuff we're generating, including MCContext.
- MachineModuleInfo *MMI =
- new MachineModuleInfo(*TM->getMCAsmInfo(), *TM->getRegisterInfo(),
- &getTargetLowering()->getObjFileLowering());
- PM.add(MMI);
- OutContext = &MMI->getContext(); // Return the MCContext specifically by-ref.
-
- // Set up a MachineFunction for the rest of CodeGen to work on.
- PM.add(new MachineFunctionAnalysis(*TM));
-
- // Enable FastISel with -fast, but allow that to be overridden.
- if (EnableFastISelOption == cl::BOU_TRUE ||
- (getOptLevel() == CodeGenOpt::None &&
- EnableFastISelOption != cl::BOU_FALSE))
- TM->setFastISel(true);
-
- // Ask the target for an isel.
- if (addInstSelector())
- return true;
-
+void TargetPassConfig::addMachinePasses() {
// Print the instruction selected machine code...
printAndVerify("After Instruction Selection");
@@ -356,8 +300,6 @@
if (addPreEmitPass())
printNoVerify("After PreEmit passes");
-
- return false;
}
//===---------------------------------------------------------------------===//