diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index ccc79345e03..baee77f1338 100644 --- a/include/llvm/PassSupport.h +++ b/include/llvm/PassSupport.h @@ -30,6 +30,7 @@ namespace llvm { +class TargetMachine; //===--------------------------------------------------------------------------- /// PassInfo class - An instance of this class exists for every pass known by /// the system, and can be obtained from a live Pass by calling its @@ -39,6 +40,7 @@ namespace llvm { class PassInfo { public: typedef Pass* (*NormalCtor_t)(); + typedef Pass *(*TargetMachineCtor_t)(TargetMachine *); private: const char *const PassName; // Nice name for Pass @@ -50,22 +52,26 @@ private: std::vector ItfImpl;// Interfaces implemented by this pass NormalCtor_t NormalCtor; + TargetMachineCtor_t TargetMachineCtor; public: /// PassInfo ctor - Do not call this directly, this should only be invoked /// through RegisterPass. PassInfo(const char *name, const char *arg, const void *pi, - NormalCtor_t normal, bool isCFGOnly, bool is_analysis) + NormalCtor_t normal, bool isCFGOnly, bool is_analysis, + TargetMachineCtor_t machine = NULL) : PassName(name), PassArgument(arg), PassID(pi), IsCFGOnlyPass(isCFGOnly), - IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal) { } + IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal), + TargetMachineCtor(machine) {} /// PassInfo ctor - Do not call this directly, this should only be invoked /// through RegisterPass. This version is for use by analysis groups; it /// does not auto-register the pass. PassInfo(const char *name, const void *pi) : PassName(name), PassArgument(""), PassID(pi), IsCFGOnlyPass(false), - IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(0) { } + IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(0), + TargetMachineCtor(0) {} /// getPassName - Return the friendly name for the pass, never returns null /// @@ -107,6 +113,16 @@ public: NormalCtor = Ctor; } + /// getTargetMachineCtor - Return a pointer to a function, that when called + /// with a TargetMachine, creates an instance of the pass and returns it. + /// This pointer may be null if there is no constructor with a TargetMachine + /// for the pass. + /// + TargetMachineCtor_t getTargetMachineCtor() const { return TargetMachineCtor; } + void setTargetMachineCtor(TargetMachineCtor_t Ctor) { + TargetMachineCtor = Ctor; + } + /// createPass() - Use this method to create an instance of this pass. Pass *createPass() const; @@ -182,6 +198,10 @@ private: template Pass *callDefaultCtor() { return new PassName(); } +template Pass *callTargetMachineCtor(TargetMachine *TM) { + return new PassName(TM); +} + //===--------------------------------------------------------------------------- /// RegisterPass template - This template class is used to notify the system /// that a Pass is available for use, and registers it into the internal diff --git a/lib/IR/PassRegistry.cpp b/lib/IR/PassRegistry.cpp index d3b2f1fce1c..74dc0f1daaa 100644 --- a/lib/IR/PassRegistry.cpp +++ b/lib/IR/PassRegistry.cpp @@ -179,6 +179,8 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID, assert(ImplementationInfo->getNormalCtor() && "Cannot specify pass as default if it does not have a default ctor"); InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor()); + InterfaceInfo->setTargetMachineCtor( + ImplementationInfo->getTargetMachineCtor()); } } diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp index c5fbc340b12..38f587b2cc8 100644 --- a/lib/Transforms/Scalar/CodeGenPrepare.cpp +++ b/lib/Transforms/Scalar/CodeGenPrepare.cpp @@ -129,11 +129,19 @@ namespace { } char CodeGenPrepare::ID = 0; -INITIALIZE_PASS_BEGIN(CodeGenPrepare, "codegenprepare", - "Optimize for code generation", false, false) -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo) -INITIALIZE_PASS_END(CodeGenPrepare, "codegenprepare", - "Optimize for code generation", false, false) +static void *initializeCodeGenPreparePassOnce(PassRegistry &Registry) { + initializeTargetLibraryInfoPass(Registry); + PassInfo *PI = new PassInfo( + "Optimize for code generation", "codegenprepare", &CodeGenPrepare::ID, + PassInfo::NormalCtor_t(callDefaultCtor), false, false, + PassInfo::TargetMachineCtor_t(callTargetMachineCtor)); + Registry.registerPass(*PI, true); + return PI; +} + +void llvm::initializeCodeGenPreparePass(PassRegistry &Registry) { + CALL_ONCE_INITIALIZATION(initializeCodeGenPreparePassOnce) +} FunctionPass *llvm::createCodeGenPreparePass(const TargetMachine *TM) { return new CodeGenPrepare(TM); diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index dcff891bcd0..ef8c504d0fe 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -795,7 +795,9 @@ int main(int argc, char **argv) { const PassInfo *PassInf = PassList[i]; Pass *P = 0; - if (PassInf->getNormalCtor()) + if (PassInf->getTargetMachineCtor()) + P = PassInf->getTargetMachineCtor()(TM.get()); + else if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); else errs() << argv[0] << ": cannot create pass: "