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 24namespace llvm { 25 26//===----------------------------------------------------------------------===// 27/// 28/// MachinePassRegistryListener - Listener to adds and removals of nodes in 29/// registration list. 30/// 31//===----------------------------------------------------------------------===// 32template <class PassCtorTy> class MachinePassRegistryListener { 33 virtual void anchor() {} 34 35public: 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//===----------------------------------------------------------------------===// 48template <typename PassCtorTy> class MachinePassRegistryNode { 49private: 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 55public: 56 MachinePassRegistryNode(const char *N, const char *D, PassCtorTy C) 57 : Name(N), Description(D), Ctor(C) {} 58 59 // Accessors 60 MachinePassRegistryNode *getNext() const { return Next; } 61 MachinePassRegistryNode **getNextAddress() { return &Next; } 62 StringRef getName() const { return Name; } 63 StringRef getDescription() const { return Description; } 64 PassCtorTy getCtor() const { return Ctor; } 65 void setNext(MachinePassRegistryNode *N) { Next = N; } 66}; 67 68//===----------------------------------------------------------------------===// 69/// 70/// MachinePassRegistry - Track the registration of machine passes. 71/// 72//===----------------------------------------------------------------------===// 73template <typename PassCtorTy> class MachinePassRegistry { 74private: 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 80public: 81 // NO CONSTRUCTOR - we don't want static constructor ordering to mess 82 // with the registry. 83 84 // Accessors. 85 // 86 MachinePassRegistryNode<PassCtorTy> *getList() { return List; } 87 PassCtorTy getDefault() { return Default; } 88 void setDefault(PassCtorTy C) { Default = C; } 89 /// setDefault - Set the default constructor by 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 } 102 void setListener(MachinePassRegistryListener<PassCtorTy> *L) { Listener = L; } 103 104 /// Add - Adds a function pass to the registration list. 105 /// 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 /// 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//===----------------------------------------------------------------------===// 134template <class RegistryClass> 135class RegisterPassParser 136 : public MachinePassRegistryListener< 137 typename RegistryClass::FunctionPassCtor>, 138 public cl::parser<typename RegistryClass::FunctionPassCtor> { 139public: 140 RegisterPassParser(cl::Option &O) 141 : cl::parser<typename RegistryClass::FunctionPassCtor>(O) {} 142 ~RegisterPassParser() override { RegistryClass::setListener(nullptr); } 143 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. 160 void NotifyAdd(StringRef N, typename RegistryClass::FunctionPassCtor C, 161 StringRef D) override { 162 this->addLiteralOption(N, C, D); 163 } 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