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