1 //===-- llvm/SymbolTableListTraitsImpl.h - Implementation ------*- 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 implements the stickier parts of the SymbolTableListTraits class, 10 // and is explicitly instantiated where needed to avoid defining all this code 11 // in a widely used header. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_LIB_IR_SYMBOLTABLELISTTRAITSIMPL_H 16 #define LLVM_LIB_IR_SYMBOLTABLELISTTRAITSIMPL_H 17 18 #include "llvm/IR/SymbolTableListTraits.h" 19 #include "llvm/IR/ValueSymbolTable.h" 20 21 namespace llvm { 22 23 /// Notify basic blocks when an instruction is inserted. 24 template <typename ParentClass> 25 inline void invalidateParentIListOrdering(ParentClass *Parent) {} 26 template <> void invalidateParentIListOrdering(BasicBlock *BB); 27 28 /// setSymTabObject - This is called when (f.e.) the parent of a basic block 29 /// changes. This requires us to remove all the instruction symtab entries from 30 /// the current function and reinsert them into the new function. 31 template <typename ValueSubClass, typename... Args> 32 template <typename TPtr> 33 void SymbolTableListTraits<ValueSubClass, Args...>::setSymTabObject(TPtr *Dest, 34 TPtr Src) { 35 // Get the old symtab and value list before doing the assignment. 36 ValueSymbolTable *OldST = getSymTab(getListOwner()); 37 38 // Do it. 39 *Dest = Src; 40 41 // Get the new SymTab object. 42 ValueSymbolTable *NewST = getSymTab(getListOwner()); 43 44 // If there is nothing to do, quick exit. 45 if (OldST == NewST) return; 46 47 // Move all the elements from the old symtab to the new one. 48 ListTy &ItemList = getList(getListOwner()); 49 if (ItemList.empty()) return; 50 51 if (OldST) { 52 // Remove all entries from the previous symtab. 53 for (auto I = ItemList.begin(); I != ItemList.end(); ++I) 54 if (I->hasName()) 55 OldST->removeValueName(I->getValueName()); 56 } 57 58 if (NewST) { 59 // Add all of the items to the new symtab. 60 for (auto I = ItemList.begin(); I != ItemList.end(); ++I) 61 if (I->hasName()) 62 NewST->reinsertValue(&*I); 63 } 64 } 65 66 template <typename ValueSubClass, typename... Args> 67 void SymbolTableListTraits<ValueSubClass, Args...>::addNodeToList( 68 ValueSubClass *V) { 69 assert(!V->getParent() && "Value already in a container!!"); 70 ItemParentClass *Owner = getListOwner(); 71 V->setParent(Owner); 72 invalidateParentIListOrdering(Owner); 73 if (V->hasName()) 74 if (ValueSymbolTable *ST = getSymTab(Owner)) 75 ST->reinsertValue(V); 76 } 77 78 template <typename ValueSubClass, typename... Args> 79 void SymbolTableListTraits<ValueSubClass, Args...>::removeNodeFromList( 80 ValueSubClass *V) { 81 V->setParent(nullptr); 82 if (V->hasName()) 83 if (ValueSymbolTable *ST = getSymTab(getListOwner())) 84 ST->removeValueName(V->getValueName()); 85 } 86 87 template <typename ValueSubClass, typename... Args> 88 void SymbolTableListTraits<ValueSubClass, Args...>::transferNodesFromList( 89 SymbolTableListTraits &L2, iterator first, iterator last) { 90 // Transfering nodes, even within the same BB, invalidates the ordering. The 91 // list that we removed the nodes from still has a valid ordering. 92 ItemParentClass *NewIP = getListOwner(); 93 invalidateParentIListOrdering(NewIP); 94 95 // Nothing else needs to be done if we're reording nodes within the same list. 96 ItemParentClass *OldIP = L2.getListOwner(); 97 if (NewIP == OldIP) 98 return; 99 100 // We only have to update symbol table entries if we are transferring the 101 // instructions to a different symtab object... 102 ValueSymbolTable *NewST = getSymTab(NewIP); 103 ValueSymbolTable *OldST = getSymTab(OldIP); 104 if (NewST != OldST) { 105 for (; first != last; ++first) { 106 ValueSubClass &V = *first; 107 bool HasName = V.hasName(); 108 if (OldST && HasName) 109 OldST->removeValueName(V.getValueName()); 110 V.setParent(NewIP); 111 if (NewST && HasName) 112 NewST->reinsertValue(&V); 113 } 114 } else { 115 // Just transferring between blocks in the same function, simply update the 116 // parent fields in the instructions... 117 for (; first != last; ++first) 118 first->setParent(NewIP); 119 } 120 } 121 122 } // End llvm namespace 123 124 #endif 125