Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 1 | //===- llvm/PassSupport.h - Pass Support code -------------------*- C++ -*-===// |
John Criswell | 6fbcc26 | 2003-10-20 20:19:47 +0000 | [diff] [blame^] | 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file was developed by the LLVM research group and is distributed under |
| 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 9 | // |
| 10 | // This file defines stuff that is used to define and "use" Passes. This file |
| 11 | // is automatically #included by Pass.h, so: |
| 12 | // |
| 13 | // NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY |
| 14 | // |
| 15 | // Instead, #include Pass.h. |
| 16 | // |
| 17 | // This file defines Pass registration code and classes used for it. |
| 18 | // |
| 19 | //===----------------------------------------------------------------------===// |
| 20 | |
| 21 | #ifndef LLVM_PASS_SUPPORT_H |
| 22 | #define LLVM_PASS_SUPPORT_H |
| 23 | |
| 24 | // No need to include Pass.h, we are being included by it! |
| 25 | |
Chris Lattner | 5d1cf5b | 2002-07-30 03:55:01 +0000 | [diff] [blame] | 26 | class TargetMachine; |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 27 | |
| 28 | //===--------------------------------------------------------------------------- |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 29 | /// PassInfo class - An instance of this class exists for every pass known by |
| 30 | /// the system, and can be obtained from a live Pass by calling its |
| 31 | /// getPassInfo() method. These objects are set up by the RegisterPass<> |
| 32 | /// template, defined below. |
| 33 | /// |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 34 | class PassInfo { |
| 35 | const char *PassName; // Nice name for Pass |
| 36 | const char *PassArgument; // Command Line argument to run this pass |
| 37 | const std::type_info &TypeInfo; // type_info object for this Pass class |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 38 | unsigned char PassType; // Set of enums values below... |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 39 | std::vector<const PassInfo*> ItfImpl;// Interfaces implemented by this pass |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 40 | |
| 41 | Pass *(*NormalCtor)(); // No argument ctor |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 42 | Pass *(*TargetCtor)(TargetMachine&); // Ctor taking TargetMachine object... |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 43 | |
| 44 | public: |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 45 | /// PassType - Define symbolic constants that can be used to test to see if |
| 46 | /// this pass should be listed by analyze or opt. Passes can use none, one or |
| 47 | /// many of these flags or'd together. It is not legal to combine the |
| 48 | /// AnalysisGroup flag with others. |
| 49 | /// |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 50 | enum { |
Chris Lattner | 0756c11 | 2002-08-21 22:16:59 +0000 | [diff] [blame] | 51 | Analysis = 1, Optimization = 2, LLC = 4, AnalysisGroup = 8 |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 52 | }; |
| 53 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 54 | /// PassInfo ctor - Do not call this directly, this should only be invoked |
| 55 | /// through RegisterPass. |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 56 | PassInfo(const char *name, const char *arg, const std::type_info &ti, |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 57 | unsigned pt, Pass *(*normal)() = 0, |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 58 | Pass *(*targetctor)(TargetMachine &) = 0) |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 59 | : PassName(name), PassArgument(arg), TypeInfo(ti), PassType(pt), |
Chris Lattner | baf64b1 | 2003-04-24 18:41:30 +0000 | [diff] [blame] | 60 | NormalCtor(normal), TargetCtor(targetctor) { |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 61 | } |
| 62 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 63 | /// getPassName - Return the friendly name for the pass, never returns null |
| 64 | /// |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 65 | const char *getPassName() const { return PassName; } |
Chris Lattner | 0756c11 | 2002-08-21 22:16:59 +0000 | [diff] [blame] | 66 | void setPassName(const char *Name) { PassName = Name; } |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 67 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 68 | /// getPassArgument - Return the command line option that may be passed to |
| 69 | /// 'opt' that will cause this pass to be run. This will return null if there |
| 70 | /// is no argument. |
| 71 | /// |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 72 | const char *getPassArgument() const { return PassArgument; } |
| 73 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 74 | /// getTypeInfo - Return the type_info object for the pass... |
| 75 | /// |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 76 | const std::type_info &getTypeInfo() const { return TypeInfo; } |
| 77 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 78 | /// getPassType - Return the PassType of a pass. Note that this can be |
| 79 | /// several different types or'd together. This is _strictly_ for use by opt, |
| 80 | /// analyze and llc for deciding which passes to use as command line options. |
| 81 | /// |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 82 | unsigned getPassType() const { return PassType; } |
| 83 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 84 | /// getNormalCtor - Return a pointer to a function, that when called, creates |
| 85 | /// an instance of the pass and returns it. This pointer may be null if there |
| 86 | /// is no default constructor for the pass. |
| 87 | /// |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 88 | Pass *(*getNormalCtor() const)() { |
| 89 | return NormalCtor; |
| 90 | } |
Chris Lattner | 0756c11 | 2002-08-21 22:16:59 +0000 | [diff] [blame] | 91 | void setNormalCtor(Pass *(*Ctor)()) { |
| 92 | NormalCtor = Ctor; |
| 93 | } |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 94 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 95 | /// createPass() - Use this method to create an instance of this pass. |
Chris Lattner | a59cbb2 | 2002-07-27 01:12:17 +0000 | [diff] [blame] | 96 | Pass *createPass() const { |
Chris Lattner | 0756c11 | 2002-08-21 22:16:59 +0000 | [diff] [blame] | 97 | assert((PassType != AnalysisGroup || NormalCtor) && |
| 98 | "No default implementation found for analysis group!"); |
Chris Lattner | a59cbb2 | 2002-07-27 01:12:17 +0000 | [diff] [blame] | 99 | assert(NormalCtor && |
| 100 | "Cannot call createPass on PassInfo without default ctor!"); |
| 101 | return NormalCtor(); |
| 102 | } |
| 103 | |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 104 | /// getTargetCtor - Return a pointer to a function that creates an instance of |
| 105 | /// the pass and returns it. This returns a constructor for a version of the |
| 106 | /// pass that takes a TargetMachine object as a parameter. |
| 107 | /// |
| 108 | Pass *(*getTargetCtor() const)(TargetMachine &) { |
| 109 | return TargetCtor; |
| 110 | } |
| 111 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 112 | /// addInterfaceImplemented - This method is called when this pass is |
| 113 | /// registered as a member of an analysis group with the RegisterAnalysisGroup |
| 114 | /// template. |
| 115 | /// |
| 116 | void addInterfaceImplemented(const PassInfo *ItfPI) { |
| 117 | ItfImpl.push_back(ItfPI); |
| 118 | } |
| 119 | |
| 120 | /// getInterfacesImplemented - Return a list of all of the analysis group |
| 121 | /// interfaces implemented by this pass. |
| 122 | /// |
| 123 | const std::vector<const PassInfo*> &getInterfacesImplemented() const { |
| 124 | return ItfImpl; |
| 125 | } |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 126 | }; |
| 127 | |
| 128 | |
| 129 | //===--------------------------------------------------------------------------- |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 130 | /// RegisterPass<t> template - This template class is used to notify the system |
| 131 | /// that a Pass is available for use, and registers it into the internal |
| 132 | /// database maintained by the PassManager. Unless this template is used, opt, |
| 133 | /// for example will not be able to see the pass and attempts to create the pass |
| 134 | /// will fail. This template is used in the follow manner (at global scope, in |
| 135 | /// your .cpp file): |
| 136 | /// |
| 137 | /// static RegisterPass<YourPassClassName> tmp("passopt", "My Pass Name"); |
| 138 | /// |
| 139 | /// This statement will cause your pass to be created by calling the default |
| 140 | /// constructor exposed by the pass. If you have a different constructor that |
| 141 | /// must be called, create a global constructor function (which takes the |
| 142 | /// arguments you need and returns a Pass*) and register your pass like this: |
| 143 | /// |
| 144 | /// Pass *createMyPass(foo &opt) { return new MyPass(opt); } |
| 145 | /// static RegisterPass<PassClassName> tmp("passopt", "My Name", createMyPass); |
| 146 | /// |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 147 | struct RegisterPassBase { |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 148 | /// getPassInfo - Get the pass info for the registered class... |
| 149 | /// |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 150 | const PassInfo *getPassInfo() const { return PIObj; } |
| 151 | |
Chris Lattner | 0756c11 | 2002-08-21 22:16:59 +0000 | [diff] [blame] | 152 | RegisterPassBase() : PIObj(0) {} |
| 153 | ~RegisterPassBase() { // Intentionally non-virtual... |
| 154 | if (PIObj) unregisterPass(PIObj); |
| 155 | } |
Chris Lattner | a59cbb2 | 2002-07-27 01:12:17 +0000 | [diff] [blame] | 156 | |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 157 | protected: |
| 158 | PassInfo *PIObj; // The PassInfo object for this pass |
| 159 | void registerPass(PassInfo *); |
Chris Lattner | 0756c11 | 2002-08-21 22:16:59 +0000 | [diff] [blame] | 160 | void unregisterPass(PassInfo *); |
Chris Lattner | 6b5fe19 | 2002-07-30 16:27:32 +0000 | [diff] [blame] | 161 | |
Chris Lattner | 7f9bb6e | 2003-10-12 18:51:53 +0000 | [diff] [blame] | 162 | /// setOnlyUsesCFG - Notice that this pass only depends on the CFG, so |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 163 | /// transformations that do not modify the CFG do not invalidate this pass. |
| 164 | /// |
Chris Lattner | 7f9bb6e | 2003-10-12 18:51:53 +0000 | [diff] [blame] | 165 | void setOnlyUsesCFG(); |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 166 | }; |
| 167 | |
| 168 | template<typename PassName> |
| 169 | Pass *callDefaultCtor() { return new PassName(); } |
| 170 | |
| 171 | template<typename PassName> |
| 172 | struct RegisterPass : public RegisterPassBase { |
| 173 | |
| 174 | // Register Pass using default constructor... |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 175 | RegisterPass(const char *PassArg, const char *Name, unsigned PassTy = 0) { |
| 176 | registerPass(new PassInfo(Name, PassArg, typeid(PassName), PassTy, |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 177 | callDefaultCtor<PassName>)); |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 178 | } |
| 179 | |
| 180 | // Register Pass using default constructor explicitly... |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 181 | RegisterPass(const char *PassArg, const char *Name, unsigned PassTy, |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 182 | Pass *(*ctor)()) { |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 183 | registerPass(new PassInfo(Name, PassArg, typeid(PassName), PassTy, ctor)); |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 184 | } |
| 185 | |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 186 | // Register Pass using TargetMachine constructor... |
| 187 | RegisterPass(const char *PassArg, const char *Name, unsigned PassTy, |
| 188 | Pass *(*targetctor)(TargetMachine &)) { |
| 189 | registerPass(new PassInfo(Name, PassArg, typeid(PassName), PassTy, |
Chris Lattner | baf64b1 | 2003-04-24 18:41:30 +0000 | [diff] [blame] | 190 | 0, targetctor)); |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 191 | } |
| 192 | |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 193 | // Generic constructor version that has an unknown ctor type... |
| 194 | template<typename CtorType> |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 195 | RegisterPass(const char *PassArg, const char *Name, unsigned PassTy, |
| 196 | CtorType *Fn) { |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 197 | registerPass(new PassInfo(Name, PassArg, typeid(PassName), PassTy, 0)); |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 198 | } |
| 199 | }; |
| 200 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 201 | /// RegisterOpt - Register something that is to show up in Opt, this is just a |
| 202 | /// shortcut for specifying RegisterPass... |
| 203 | /// |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 204 | template<typename PassName> |
| 205 | struct RegisterOpt : public RegisterPassBase { |
Chris Lattner | 7f9bb6e | 2003-10-12 18:51:53 +0000 | [diff] [blame] | 206 | RegisterOpt(const char *PassArg, const char *Name, bool CFGOnly = false) { |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 207 | registerPass(new PassInfo(Name, PassArg, typeid(PassName), |
| 208 | PassInfo::Optimization, |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 209 | callDefaultCtor<PassName>)); |
Chris Lattner | 7f9bb6e | 2003-10-12 18:51:53 +0000 | [diff] [blame] | 210 | if (CFGOnly) setOnlyUsesCFG(); |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 211 | } |
| 212 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 213 | /// Register Pass using default constructor explicitly... |
| 214 | /// |
Chris Lattner | 7f9bb6e | 2003-10-12 18:51:53 +0000 | [diff] [blame] | 215 | RegisterOpt(const char *PassArg, const char *Name, Pass *(*ctor)(), |
| 216 | bool CFGOnly = false) { |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 217 | registerPass(new PassInfo(Name, PassArg, typeid(PassName), |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 218 | PassInfo::Optimization, ctor)); |
Chris Lattner | 7f9bb6e | 2003-10-12 18:51:53 +0000 | [diff] [blame] | 219 | if (CFGOnly) setOnlyUsesCFG(); |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 220 | } |
| 221 | |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 222 | /// Register Pass using TargetMachine constructor... |
| 223 | /// |
| 224 | RegisterOpt(const char *PassArg, const char *Name, |
Chris Lattner | 7f9bb6e | 2003-10-12 18:51:53 +0000 | [diff] [blame] | 225 | Pass *(*targetctor)(TargetMachine &), bool CFGOnly = false) { |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 226 | registerPass(new PassInfo(Name, PassArg, typeid(PassName), |
Chris Lattner | baf64b1 | 2003-04-24 18:41:30 +0000 | [diff] [blame] | 227 | PassInfo::Optimization, 0, targetctor)); |
Chris Lattner | 7f9bb6e | 2003-10-12 18:51:53 +0000 | [diff] [blame] | 228 | if (CFGOnly) setOnlyUsesCFG(); |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 229 | } |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 230 | }; |
| 231 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 232 | /// RegisterAnalysis - Register something that is to show up in Analysis, this |
| 233 | /// is just a shortcut for specifying RegisterPass... Analyses take a special |
| 234 | /// argument that, when set to true, tells the system that the analysis ONLY |
| 235 | /// depends on the shape of the CFG, so if a transformation preserves the CFG |
| 236 | /// that the analysis is not invalidated. |
| 237 | /// |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 238 | template<typename PassName> |
| 239 | struct RegisterAnalysis : public RegisterPassBase { |
Chris Lattner | 6b5fe19 | 2002-07-30 16:27:32 +0000 | [diff] [blame] | 240 | RegisterAnalysis(const char *PassArg, const char *Name, |
| 241 | bool CFGOnly = false) { |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 242 | registerPass(new PassInfo(Name, PassArg, typeid(PassName), |
| 243 | PassInfo::Analysis, |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 244 | callDefaultCtor<PassName>)); |
Chris Lattner | 7f9bb6e | 2003-10-12 18:51:53 +0000 | [diff] [blame] | 245 | if (CFGOnly) setOnlyUsesCFG(); |
Chris Lattner | 6311492 | 2002-07-26 21:11:38 +0000 | [diff] [blame] | 246 | } |
| 247 | }; |
| 248 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 249 | /// RegisterLLC - Register something that is to show up in LLC, this is just a |
| 250 | /// shortcut for specifying RegisterPass... |
| 251 | /// |
Chris Lattner | 5d1cf5b | 2002-07-30 03:55:01 +0000 | [diff] [blame] | 252 | template<typename PassName> |
| 253 | struct RegisterLLC : public RegisterPassBase { |
| 254 | RegisterLLC(const char *PassArg, const char *Name) { |
| 255 | registerPass(new PassInfo(Name, PassArg, typeid(PassName), |
| 256 | PassInfo::LLC, |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 257 | callDefaultCtor<PassName>)); |
Chris Lattner | 5d1cf5b | 2002-07-30 03:55:01 +0000 | [diff] [blame] | 258 | } |
| 259 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 260 | /// Register Pass using default constructor explicitly... |
| 261 | /// |
Chris Lattner | 5d1cf5b | 2002-07-30 03:55:01 +0000 | [diff] [blame] | 262 | RegisterLLC(const char *PassArg, const char *Name, Pass *(*ctor)()) { |
| 263 | registerPass(new PassInfo(Name, PassArg, typeid(PassName), |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 264 | PassInfo::LLC, ctor)); |
Chris Lattner | 5d1cf5b | 2002-07-30 03:55:01 +0000 | [diff] [blame] | 265 | } |
| 266 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 267 | /// Register Pass using TargetMachine constructor... |
| 268 | /// |
Chris Lattner | 5d1cf5b | 2002-07-30 03:55:01 +0000 | [diff] [blame] | 269 | RegisterLLC(const char *PassArg, const char *Name, |
| 270 | Pass *(*datactor)(TargetMachine &)) { |
| 271 | registerPass(new PassInfo(Name, PassArg, typeid(PassName), |
Vikram S. Adve | a081baa | 2002-09-16 16:01:39 +0000 | [diff] [blame] | 272 | PassInfo::LLC)); |
Chris Lattner | 5d1cf5b | 2002-07-30 03:55:01 +0000 | [diff] [blame] | 273 | } |
| 274 | }; |
| 275 | |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 276 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 277 | /// RegisterAnalysisGroup - Register a Pass as a member of an analysis _group_. |
| 278 | /// Analysis groups are used to define an interface (which need not derive from |
| 279 | /// Pass) that is required by passes to do their job. Analysis Groups differ |
| 280 | /// from normal analyses because any available implementation of the group will |
| 281 | /// be used if it is available. |
| 282 | /// |
| 283 | /// If no analysis implementing the interface is available, a default |
| 284 | /// implementation is created and added. A pass registers itself as the default |
| 285 | /// implementation by specifying 'true' as the third template argument of this |
| 286 | /// class. |
| 287 | /// |
| 288 | /// In addition to registering itself as an analysis group member, a pass must |
| 289 | /// register itself normally as well. Passes may be members of multiple groups |
| 290 | /// and may still be "required" specifically by name. |
| 291 | /// |
| 292 | /// The actual interface may also be registered as well (by not specifying the |
| 293 | /// second template argument). The interface should be registered to associate |
| 294 | /// a nice name with the interface. |
| 295 | /// |
Chris Lattner | 0756c11 | 2002-08-21 22:16:59 +0000 | [diff] [blame] | 296 | class RegisterAGBase : public RegisterPassBase { |
| 297 | PassInfo *InterfaceInfo; |
| 298 | const PassInfo *ImplementationInfo; |
| 299 | bool isDefaultImplementation; |
| 300 | protected: |
| 301 | RegisterAGBase(const std::type_info &Interface, |
| 302 | const std::type_info *Pass = 0, |
| 303 | bool isDefault = false); |
| 304 | void setGroupName(const char *Name); |
| 305 | public: |
| 306 | ~RegisterAGBase(); |
| 307 | }; |
| 308 | |
| 309 | |
| 310 | template<typename Interface, typename DefaultImplementationPass = void, |
| 311 | bool Default = false> |
| 312 | struct RegisterAnalysisGroup : public RegisterAGBase { |
| 313 | RegisterAnalysisGroup() : RegisterAGBase(typeid(Interface), |
| 314 | &typeid(DefaultImplementationPass), |
| 315 | Default) { |
| 316 | } |
| 317 | }; |
| 318 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 319 | /// Define a specialization of RegisterAnalysisGroup that is used to set the |
| 320 | /// name for the analysis group. |
| 321 | /// |
Chris Lattner | 0756c11 | 2002-08-21 22:16:59 +0000 | [diff] [blame] | 322 | template<typename Interface> |
| 323 | struct RegisterAnalysisGroup<Interface, void, false> : public RegisterAGBase { |
| 324 | RegisterAnalysisGroup(const char *Name) |
| 325 | : RegisterAGBase(typeid(Interface)) { |
| 326 | setGroupName(Name); |
| 327 | } |
| 328 | }; |
| 329 | |
| 330 | |
| 331 | |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 332 | //===--------------------------------------------------------------------------- |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 333 | /// PassRegistrationListener class - This class is meant to be derived from by |
| 334 | /// clients that are interested in which passes get registered and unregistered |
| 335 | /// at runtime (which can be because of the RegisterPass constructors being run |
| 336 | /// as the program starts up, or may be because a shared object just got |
| 337 | /// loaded). Deriving from the PassRegistationListener class automatically |
| 338 | /// registers your object to receive callbacks indicating when passes are loaded |
| 339 | /// and removed. |
| 340 | /// |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 341 | struct PassRegistrationListener { |
| 342 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 343 | /// PassRegistrationListener ctor - Add the current object to the list of |
| 344 | /// PassRegistrationListeners... |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 345 | PassRegistrationListener(); |
| 346 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 347 | /// dtor - Remove object from list of listeners... |
| 348 | /// |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 349 | virtual ~PassRegistrationListener(); |
| 350 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 351 | /// Callback functions - These functions are invoked whenever a pass is loaded |
| 352 | /// or removed from the current executable. |
| 353 | /// |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 354 | virtual void passRegistered(const PassInfo *P) {} |
| 355 | virtual void passUnregistered(const PassInfo *P) {} |
| 356 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 357 | /// enumeratePasses - Iterate over the registered passes, calling the |
| 358 | /// passEnumerate callback on each PassInfo object. |
| 359 | /// |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 360 | void enumeratePasses(); |
| 361 | |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 362 | /// passEnumerate - Callback function invoked when someone calls |
| 363 | /// enumeratePasses on this PassRegistrationListener object. |
| 364 | /// |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 365 | virtual void passEnumerate(const PassInfo *P) {} |
| 366 | }; |
| 367 | |
Chris Lattner | c37fca1 | 2002-08-21 23:48:55 +0000 | [diff] [blame] | 368 | |
| 369 | //===--------------------------------------------------------------------------- |
Chris Lattner | ada23c0 | 2002-08-30 20:20:39 +0000 | [diff] [blame] | 370 | /// IncludeFile class - This class is used as a hack to make sure that the |
| 371 | /// implementation of a header file is included into a tool that uses the |
| 372 | /// header. This is solely to overcome problems linking .a files and not |
| 373 | /// getting the implementation of passes we need. |
| 374 | /// |
Chris Lattner | c37fca1 | 2002-08-21 23:48:55 +0000 | [diff] [blame] | 375 | struct IncludeFile { |
| 376 | IncludeFile(void *); |
| 377 | }; |
Chris Lattner | 4c76fc0 | 2002-07-23 17:59:55 +0000 | [diff] [blame] | 378 | #endif |