Home | History | Annotate | Line # | Download | only in CodeGen
      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 {
     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:
     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 //===----------------------------------------------------------------------===//
     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   //
     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 //===----------------------------------------------------------------------===//
    134 template <class RegistryClass>
    135 class RegisterPassParser
    136     : public MachinePassRegistryListener<
    137           typename RegistryClass::FunctionPassCtor>,
    138       public cl::parser<typename RegistryClass::FunctionPassCtor> {
    139 public:
    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