llvm.org GIT mirror llvm / 9b24eee
[opt][PassInfo] Allow opt to run passes that need target machine. When registering a pass, a pass can now specify a second construct that takes as argument a pointer to TargetMachine. The PassInfo class has been updated to reflect that possibility. If such a constructor exists opt will use it instead of the default constructor when instantiating the pass. Since such IR passes are supposed to be rare, no specific support has been added to this commit to allow an easy registration of such a pass. In other words, for such pass, the initialization function has to be hand-written (see CodeGenPrepare for instance). Now, codegenprepare can be tested using opt: opt -codegenprepare -mtriple=mytriple input.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199430 91177308-0d34-0410-b5e6-96231b3b80d8 Quentin Colombet 6 years ago
4 changed file(s) with 41 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
2929
3030 namespace llvm {
3131
32 class TargetMachine;
3233 //===---------------------------------------------------------------------------
3334 /// PassInfo class - An instance of this class exists for every pass known by
3435 /// the system, and can be obtained from a live Pass by calling its
3839 class PassInfo {
3940 public:
4041 typedef Pass* (*NormalCtor_t)();
42 typedef Pass *(*TargetMachineCtor_t)(TargetMachine *);
4143
4244 private:
4345 const char *const PassName; // Nice name for Pass
4951 std::vector ItfImpl;// Interfaces implemented by this pass
5052
5153 NormalCtor_t NormalCtor;
54 TargetMachineCtor_t TargetMachineCtor;
5255
5356 public:
5457 /// PassInfo ctor - Do not call this directly, this should only be invoked
5558 /// through RegisterPass.
5659 PassInfo(const char *name, const char *arg, const void *pi,
57 NormalCtor_t normal, bool isCFGOnly, bool is_analysis)
60 NormalCtor_t normal, bool isCFGOnly, bool is_analysis,
61 TargetMachineCtor_t machine = NULL)
5862 : PassName(name), PassArgument(arg), PassID(pi),
5963 IsCFGOnlyPass(isCFGOnly),
60 IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal) { }
64 IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal),
65 TargetMachineCtor(machine) {}
6166 /// PassInfo ctor - Do not call this directly, this should only be invoked
6267 /// through RegisterPass. This version is for use by analysis groups; it
6368 /// does not auto-register the pass.
6469 PassInfo(const char *name, const void *pi)
6570 : PassName(name), PassArgument(""), PassID(pi),
6671 IsCFGOnlyPass(false),
67 IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(0) { }
72 IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(0),
73 TargetMachineCtor(0) {}
6874
6975 /// getPassName - Return the friendly name for the pass, never returns null
7076 ///
104110 }
105111 void setNormalCtor(NormalCtor_t Ctor) {
106112 NormalCtor = Ctor;
113 }
114
115 /// getTargetMachineCtor - Return a pointer to a function, that when called
116 /// with a TargetMachine, creates an instance of the pass and returns it.
117 /// This pointer may be null if there is no constructor with a TargetMachine
118 /// for the pass.
119 ///
120 TargetMachineCtor_t getTargetMachineCtor() const { return TargetMachineCtor; }
121 void setTargetMachineCtor(TargetMachineCtor_t Ctor) {
122 TargetMachineCtor = Ctor;
107123 }
108124
109125 /// createPass() - Use this method to create an instance of this pass.
181197 template
182198 Pass *callDefaultCtor() { return new PassName(); }
183199
200 template Pass *callTargetMachineCtor(TargetMachine *TM) {
201 return new PassName(TM);
202 }
203
184204 //===---------------------------------------------------------------------------
185205 /// RegisterPass template - This template class is used to notify the system
186206 /// that a Pass is available for use, and registers it into the internal
178178 assert(ImplementationInfo->getNormalCtor() &&
179179 "Cannot specify pass as default if it does not have a default ctor");
180180 InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
181 InterfaceInfo->setTargetMachineCtor(
182 ImplementationInfo->getTargetMachineCtor());
181183 }
182184 }
183185
128128 }
129129
130130 char CodeGenPrepare::ID = 0;
131 INITIALIZE_PASS_BEGIN(CodeGenPrepare, "codegenprepare",
132 "Optimize for code generation", false, false)
133 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
134 INITIALIZE_PASS_END(CodeGenPrepare, "codegenprepare",
135 "Optimize for code generation", false, false)
131 static void *initializeCodeGenPreparePassOnce(PassRegistry &Registry) {
132 initializeTargetLibraryInfoPass(Registry);
133 PassInfo *PI = new PassInfo(
134 "Optimize for code generation", "codegenprepare", &CodeGenPrepare::ID,
135 PassInfo::NormalCtor_t(callDefaultCtor), false, false,
136 PassInfo::TargetMachineCtor_t(callTargetMachineCtor));
137 Registry.registerPass(*PI, true);
138 return PI;
139 }
140
141 void llvm::initializeCodeGenPreparePass(PassRegistry &Registry) {
142 CALL_ONCE_INITIALIZATION(initializeCodeGenPreparePassOnce)
143 }
136144
137145 FunctionPass *llvm::createCodeGenPreparePass(const TargetMachine *TM) {
138146 return new CodeGenPrepare(TM);
794794
795795 const PassInfo *PassInf = PassList[i];
796796 Pass *P = 0;
797 if (PassInf->getNormalCtor())
797 if (PassInf->getTargetMachineCtor())
798 P = PassInf->getTargetMachineCtor()(TM.get());
799 else if (PassInf->getNormalCtor())
798800 P = PassInf->getNormalCtor()();
799801 else
800802 errs() << argv[0] << ": cannot create pass: "