Home | History | Annotate | Line # | Download | only in IR
      1 //===- llvm/SymbolTableListTraits.h - Traits for iplist ---------*- 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 defines a generic class that is used to implement the automatic
     10 // symbol table manipulation that occurs when you put (for example) a named
     11 // instruction into a basic block.
     12 //
     13 // The way that this is implemented is by using a special traits class with the
     14 // intrusive list that makes up the list of instructions in a basic block.  When
     15 // a new element is added to the list of instructions, the traits class is
     16 // notified, allowing the symbol table to be updated.
     17 //
     18 // This generic class implements the traits class.  It must be generic so that
     19 // it can work for all uses it, which include lists of instructions, basic
     20 // blocks, arguments, functions, global variables, etc...
     21 //
     22 //===----------------------------------------------------------------------===//
     23 
     24 #ifndef LLVM_IR_SYMBOLTABLELISTTRAITS_H
     25 #define LLVM_IR_SYMBOLTABLELISTTRAITS_H
     26 
     27 #include "llvm/ADT/ilist.h"
     28 #include "llvm/ADT/simple_ilist.h"
     29 #include <cstddef>
     30 
     31 namespace llvm {
     32 
     33 class Argument;
     34 class BasicBlock;
     35 class Function;
     36 class GlobalAlias;
     37 class GlobalIFunc;
     38 class GlobalVariable;
     39 class Instruction;
     40 class Module;
     41 class ValueSymbolTable;
     42 
     43 /// Template metafunction to get the parent type for a symbol table list.
     44 ///
     45 /// Implementations create a typedef called \c type so that we only need a
     46 /// single template parameter for the list and traits.
     47 template <typename NodeTy> struct SymbolTableListParentType {};
     48 
     49 #define DEFINE_SYMBOL_TABLE_PARENT_TYPE(NODE, PARENT)                          \
     50   template <> struct SymbolTableListParentType<NODE> { using type = PARENT; };
     51 DEFINE_SYMBOL_TABLE_PARENT_TYPE(Instruction, BasicBlock)
     52 DEFINE_SYMBOL_TABLE_PARENT_TYPE(BasicBlock, Function)
     53 DEFINE_SYMBOL_TABLE_PARENT_TYPE(Argument, Function)
     54 DEFINE_SYMBOL_TABLE_PARENT_TYPE(Function, Module)
     55 DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalVariable, Module)
     56 DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalAlias, Module)
     57 DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalIFunc, Module)
     58 #undef DEFINE_SYMBOL_TABLE_PARENT_TYPE
     59 
     60 template <typename NodeTy> class SymbolTableList;
     61 
     62 // ValueSubClass   - The type of objects that I hold, e.g. Instruction.
     63 // ItemParentClass - The type of object that owns the list, e.g. BasicBlock.
     64 //
     65 template <typename ValueSubClass>
     66 class SymbolTableListTraits : public ilist_alloc_traits<ValueSubClass> {
     67   using ListTy = SymbolTableList<ValueSubClass>;
     68   using iterator = typename simple_ilist<ValueSubClass>::iterator;
     69   using ItemParentClass =
     70       typename SymbolTableListParentType<ValueSubClass>::type;
     71 
     72 public:
     73   SymbolTableListTraits() = default;
     74 
     75 private:
     76   /// getListOwner - Return the object that owns this list.  If this is a list
     77   /// of instructions, it returns the BasicBlock that owns them.
     78   ItemParentClass *getListOwner() {
     79     size_t Offset = reinterpret_cast<size_t>(
     80         &((ItemParentClass *)nullptr->*ItemParentClass::getSublistAccess(
     81                                            static_cast<ValueSubClass *>(
     82                                                nullptr))));
     83     ListTy *Anchor = static_cast<ListTy *>(this);
     84     return reinterpret_cast<ItemParentClass*>(reinterpret_cast<char*>(Anchor)-
     85                                               Offset);
     86   }
     87 
     88   static ListTy &getList(ItemParentClass *Par) {
     89     return Par->*(Par->getSublistAccess((ValueSubClass*)nullptr));
     90   }
     91 
     92   static ValueSymbolTable *getSymTab(ItemParentClass *Par) {
     93     return Par ? toPtr(Par->getValueSymbolTable()) : nullptr;
     94   }
     95 
     96 public:
     97   void addNodeToList(ValueSubClass *V);
     98   void removeNodeFromList(ValueSubClass *V);
     99   void transferNodesFromList(SymbolTableListTraits &L2, iterator first,
    100                              iterator last);
    101   // private:
    102   template<typename TPtr>
    103   void setSymTabObject(TPtr *, TPtr);
    104   static ValueSymbolTable *toPtr(ValueSymbolTable *P) { return P; }
    105   static ValueSymbolTable *toPtr(ValueSymbolTable &R) { return &R; }
    106 };
    107 
    108 /// List that automatically updates parent links and symbol tables.
    109 ///
    110 /// When nodes are inserted into and removed from this list, the associated
    111 /// symbol table will be automatically updated.  Similarly, parent links get
    112 /// updated automatically.
    113 template <class T>
    114 class SymbolTableList
    115     : public iplist_impl<simple_ilist<T>, SymbolTableListTraits<T>> {};
    116 
    117 } // end namespace llvm
    118 
    119 #endif // LLVM_IR_SYMBOLTABLELISTTRAITS_H
    120