1 //===- llvm/CodeGen/MachinePassRegistry.h -----------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the mechanics for machine function pass registries. A 11 // function pass registry (MachinePassRegistry) is auto filled by the static 12 // constructors of MachinePassRegistryNode. Further there is a command line 13 // parser (RegisterPassParser) which listens to each registry for additions 14 // and deletions, so that the appropriate command option is updated. 15 // 16 //===----------------------------------------------------------------------===// 17 18 #ifndef LLVM_CODEGEN_MACHINEPASSREGISTRY_H 19 #define LLVM_CODEGEN_MACHINEPASSREGISTRY_H 20 21 #include "llvm/ADT/StringRef.h" 22 #include "llvm/CodeGen/Passes.h" 23 #include "llvm/Support/CommandLine.h" 24 25 namespace llvm { 26 27 //===----------------------------------------------------------------------===// 28 /// 29 /// MachinePassRegistryListener - Listener to adds and removals of nodes in 30 /// registration list. 31 /// 32 //===----------------------------------------------------------------------===// 33 template <class PassCtorTy> class MachinePassRegistryListener { anchor()34 virtual void anchor() {} 35 36 public: 37 MachinePassRegistryListener() = default; 38 virtual ~MachinePassRegistryListener() = default; 39 40 virtual void NotifyAdd(StringRef N, PassCtorTy C, StringRef D) = 0; 41 virtual void NotifyRemove(StringRef N) = 0; 42 }; 43 44 //===----------------------------------------------------------------------===// 45 /// 46 /// MachinePassRegistryNode - Machine pass node stored in registration list. 47 /// 48 //===----------------------------------------------------------------------===// 49 template <typename PassCtorTy> class MachinePassRegistryNode { 50 private: 51 MachinePassRegistryNode *Next = nullptr; // Next function pass in list. 52 StringRef Name; // Name of function pass. 53 StringRef Description; // Description string. 54 PassCtorTy Ctor; // Pass creator. 55 56 public: MachinePassRegistryNode(const char * N,const char * D,PassCtorTy C)57 MachinePassRegistryNode(const char *N, const char *D, PassCtorTy C) 58 : Name(N), Description(D), Ctor(C) {} 59 60 // Accessors getNext()61 MachinePassRegistryNode *getNext() const { return Next; } getNextAddress()62 MachinePassRegistryNode **getNextAddress() { return &Next; } getName()63 StringRef getName() const { return Name; } getDescription()64 StringRef getDescription() const { return Description; } getCtor()65 PassCtorTy getCtor() const { return Ctor; } setNext(MachinePassRegistryNode * N)66 void setNext(MachinePassRegistryNode *N) { Next = N; } 67 }; 68 69 //===----------------------------------------------------------------------===// 70 /// 71 /// MachinePassRegistry - Track the registration of machine passes. 72 /// 73 //===----------------------------------------------------------------------===// 74 template <typename PassCtorTy> class MachinePassRegistry { 75 private: 76 MachinePassRegistryNode<PassCtorTy> *List; // List of registry nodes. 77 PassCtorTy Default; // Default function pass creator. 78 MachinePassRegistryListener<PassCtorTy> 79 *Listener; // Listener for list adds are removes. 80 81 public: 82 // NO CONSTRUCTOR - we don't want static constructor ordering to mess 83 // with the registry. 84 85 // Accessors. 86 // getList()87 MachinePassRegistryNode<PassCtorTy> *getList() { return List; } getDefault()88 PassCtorTy getDefault() { return Default; } setDefault(PassCtorTy C)89 void setDefault(PassCtorTy C) { Default = C; } 90 /// setDefault - Set the default constructor by name. setDefault(StringRef Name)91 void setDefault(StringRef Name) { 92 PassCtorTy Ctor = nullptr; 93 for (MachinePassRegistryNode<PassCtorTy> *R = getList(); R; 94 R = R->getNext()) { 95 if (R->getName() == Name) { 96 Ctor = R->getCtor(); 97 break; 98 } 99 } 100 assert(Ctor && "Unregistered pass name"); 101 setDefault(Ctor); 102 } setListener(MachinePassRegistryListener<PassCtorTy> * L)103 void setListener(MachinePassRegistryListener<PassCtorTy> *L) { Listener = L; } 104 105 /// Add - Adds a function pass to the registration list. 106 /// Add(MachinePassRegistryNode<PassCtorTy> * Node)107 void Add(MachinePassRegistryNode<PassCtorTy> *Node) { 108 Node->setNext(List); 109 List = Node; 110 if (Listener) 111 Listener->NotifyAdd(Node->getName(), Node->getCtor(), 112 Node->getDescription()); 113 } 114 115 /// Remove - Removes a function pass from the registration list. 116 /// Remove(MachinePassRegistryNode<PassCtorTy> * Node)117 void Remove(MachinePassRegistryNode<PassCtorTy> *Node) { 118 for (MachinePassRegistryNode<PassCtorTy> **I = &List; *I; 119 I = (*I)->getNextAddress()) { 120 if (*I == Node) { 121 if (Listener) 122 Listener->NotifyRemove(Node->getName()); 123 *I = (*I)->getNext(); 124 break; 125 } 126 } 127 } 128 }; 129 130 //===----------------------------------------------------------------------===// 131 /// 132 /// RegisterPassParser class - Handle the addition of new machine passes. 133 /// 134 //===----------------------------------------------------------------------===// 135 template <class RegistryClass> 136 class RegisterPassParser 137 : public MachinePassRegistryListener< 138 typename RegistryClass::FunctionPassCtor>, 139 public cl::parser<typename RegistryClass::FunctionPassCtor> { 140 public: RegisterPassParser(cl::Option & O)141 RegisterPassParser(cl::Option &O) 142 : cl::parser<typename RegistryClass::FunctionPassCtor>(O) {} ~RegisterPassParser()143 ~RegisterPassParser() override { RegistryClass::setListener(nullptr); } 144 initialize()145 void initialize() { 146 cl::parser<typename RegistryClass::FunctionPassCtor>::initialize(); 147 148 // Add existing passes to option. 149 for (RegistryClass *Node = RegistryClass::getList(); 150 Node; Node = Node->getNext()) { 151 this->addLiteralOption(Node->getName(), 152 (typename RegistryClass::FunctionPassCtor)Node->getCtor(), 153 Node->getDescription()); 154 } 155 156 // Make sure we listen for list changes. 157 RegistryClass::setListener(this); 158 } 159 160 // Implement the MachinePassRegistryListener callbacks. NotifyAdd(StringRef N,typename RegistryClass::FunctionPassCtor C,StringRef D)161 void NotifyAdd(StringRef N, typename RegistryClass::FunctionPassCtor C, 162 StringRef D) override { 163 this->addLiteralOption(N, C, D); 164 } NotifyRemove(StringRef N)165 void NotifyRemove(StringRef N) override { 166 this->removeLiteralOption(N); 167 } 168 }; 169 170 } // end namespace llvm 171 172 #endif // LLVM_CODEGEN_MACHINEPASSREGISTRY_H 173