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 /// setSymTabObject - This is called when (f.e.) the parent of a basic block 24 /// changes. This requires us to remove all the instruction symtab entries from 25 /// the current function and reinsert them into the new function. 26 template <typename ValueSubClass> 27 template <typename TPtr> 28 void SymbolTableListTraits<ValueSubClass>::setSymTabObject(TPtr *Dest, 29 TPtr Src) { 30 // Get the old symtab and value list before doing the assignment. 31 ValueSymbolTable *OldST = getSymTab(getListOwner()); 32 33 // Do it. 34 *Dest = Src; 35 36 // Get the new SymTab object. 37 ValueSymbolTable *NewST = getSymTab(getListOwner()); 38 39 // If there is nothing to do, quick exit. 40 if (OldST == NewST) return; 41 42 // Move all the elements from the old symtab to the new one. 43 ListTy &ItemList = getList(getListOwner()); 44 if (ItemList.empty()) return; 45 46 if (OldST) { 47 // Remove all entries from the previous symtab. 48 for (auto I = ItemList.begin(); I != ItemList.end(); ++I) 49 if (I->hasName()) 50 OldST->removeValueName(I->getValueName()); 51 } 52 53 if (NewST) { 54 // Add all of the items to the new symtab. 55 for (auto I = ItemList.begin(); I != ItemList.end(); ++I) 56 if (I->hasName()) 57 NewST->reinsertValue(&*I); 58 } 59 60 } 61 62 template <typename ValueSubClass> 63 void SymbolTableListTraits<ValueSubClass>::addNodeToList(ValueSubClass *V) { 64 assert(!V->getParent() && "Value already in a container!!"); 65 ItemParentClass *Owner = getListOwner(); 66 V->setParent(Owner); 67 if (V->hasName()) 68 if (ValueSymbolTable *ST = getSymTab(Owner)) 69 ST->reinsertValue(V); 70 } 71 72 template <typename ValueSubClass> 73 void SymbolTableListTraits<ValueSubClass>::removeNodeFromList( 74 ValueSubClass *V) { 75 V->setParent(nullptr); 76 if (V->hasName()) 77 if (ValueSymbolTable *ST = getSymTab(getListOwner())) 78 ST->removeValueName(V->getValueName()); 79 } 80 81 template <typename ValueSubClass> 82 void SymbolTableListTraits<ValueSubClass>::transferNodesFromList( 83 SymbolTableListTraits &L2, iterator first, iterator last) { 84 // We only have to do work here if transferring instructions between BBs 85 ItemParentClass *NewIP = getListOwner(), *OldIP = L2.getListOwner(); 86 if (NewIP == OldIP) 87 return; 88 89 // We only have to update symbol table entries if we are transferring the 90 // instructions to a different symtab object... 91 ValueSymbolTable *NewST = getSymTab(NewIP); 92 ValueSymbolTable *OldST = getSymTab(OldIP); 93 if (NewST != OldST) { 94 for (; first != last; ++first) { 95 ValueSubClass &V = *first; 96 bool HasName = V.hasName(); 97 if (OldST && HasName) 98 OldST->removeValueName(V.getValueName()); 99 V.setParent(NewIP); 100 if (NewST && HasName) 101 NewST->reinsertValue(&V); 102 } 103 } else { 104 // Just transferring between blocks in the same function, simply update the 105 // parent fields in the instructions... 106 for (; first != last; ++first) 107 first->setParent(NewIP); 108 } 109 } 110 111 } // End llvm namespace 112 113 #endif 114