10b57cec5SDimitry Andric //===-- llvm/SymbolTableListTraitsImpl.h - Implementation ------*- C++ -*--===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the stickier parts of the SymbolTableListTraits class, 100b57cec5SDimitry Andric // and is explicitly instantiated where needed to avoid defining all this code 110b57cec5SDimitry Andric // in a widely used header. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #ifndef LLVM_LIB_IR_SYMBOLTABLELISTTRAITSIMPL_H 160b57cec5SDimitry Andric #define LLVM_LIB_IR_SYMBOLTABLELISTTRAITSIMPL_H 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "llvm/IR/SymbolTableListTraits.h" 190b57cec5SDimitry Andric #include "llvm/IR/ValueSymbolTable.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace llvm { 220b57cec5SDimitry Andric 235ffd83dbSDimitry Andric /// Notify basic blocks when an instruction is inserted. 245ffd83dbSDimitry Andric template <typename ParentClass> 255ffd83dbSDimitry Andric inline void invalidateParentIListOrdering(ParentClass *Parent) {} 265ffd83dbSDimitry Andric template <> void invalidateParentIListOrdering(BasicBlock *BB); 275ffd83dbSDimitry Andric 280b57cec5SDimitry Andric /// setSymTabObject - This is called when (f.e.) the parent of a basic block 290b57cec5SDimitry Andric /// changes. This requires us to remove all the instruction symtab entries from 300b57cec5SDimitry Andric /// the current function and reinsert them into the new function. 31*5f757f3fSDimitry Andric template <typename ValueSubClass, typename... Args> 320b57cec5SDimitry Andric template <typename TPtr> 33*5f757f3fSDimitry Andric void SymbolTableListTraits<ValueSubClass, Args...>::setSymTabObject(TPtr *Dest, 340b57cec5SDimitry Andric TPtr Src) { 350b57cec5SDimitry Andric // Get the old symtab and value list before doing the assignment. 360b57cec5SDimitry Andric ValueSymbolTable *OldST = getSymTab(getListOwner()); 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric // Do it. 390b57cec5SDimitry Andric *Dest = Src; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric // Get the new SymTab object. 420b57cec5SDimitry Andric ValueSymbolTable *NewST = getSymTab(getListOwner()); 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric // If there is nothing to do, quick exit. 450b57cec5SDimitry Andric if (OldST == NewST) return; 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric // Move all the elements from the old symtab to the new one. 480b57cec5SDimitry Andric ListTy &ItemList = getList(getListOwner()); 490b57cec5SDimitry Andric if (ItemList.empty()) return; 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric if (OldST) { 520b57cec5SDimitry Andric // Remove all entries from the previous symtab. 530b57cec5SDimitry Andric for (auto I = ItemList.begin(); I != ItemList.end(); ++I) 540b57cec5SDimitry Andric if (I->hasName()) 550b57cec5SDimitry Andric OldST->removeValueName(I->getValueName()); 560b57cec5SDimitry Andric } 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric if (NewST) { 590b57cec5SDimitry Andric // Add all of the items to the new symtab. 600b57cec5SDimitry Andric for (auto I = ItemList.begin(); I != ItemList.end(); ++I) 610b57cec5SDimitry Andric if (I->hasName()) 620b57cec5SDimitry Andric NewST->reinsertValue(&*I); 630b57cec5SDimitry Andric } 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric 66*5f757f3fSDimitry Andric template <typename ValueSubClass, typename... Args> 67*5f757f3fSDimitry Andric void SymbolTableListTraits<ValueSubClass, Args...>::addNodeToList( 68*5f757f3fSDimitry Andric ValueSubClass *V) { 690b57cec5SDimitry Andric assert(!V->getParent() && "Value already in a container!!"); 700b57cec5SDimitry Andric ItemParentClass *Owner = getListOwner(); 710b57cec5SDimitry Andric V->setParent(Owner); 725ffd83dbSDimitry Andric invalidateParentIListOrdering(Owner); 730b57cec5SDimitry Andric if (V->hasName()) 740b57cec5SDimitry Andric if (ValueSymbolTable *ST = getSymTab(Owner)) 750b57cec5SDimitry Andric ST->reinsertValue(V); 760b57cec5SDimitry Andric } 770b57cec5SDimitry Andric 78*5f757f3fSDimitry Andric template <typename ValueSubClass, typename... Args> 79*5f757f3fSDimitry Andric void SymbolTableListTraits<ValueSubClass, Args...>::removeNodeFromList( 800b57cec5SDimitry Andric ValueSubClass *V) { 810b57cec5SDimitry Andric V->setParent(nullptr); 820b57cec5SDimitry Andric if (V->hasName()) 830b57cec5SDimitry Andric if (ValueSymbolTable *ST = getSymTab(getListOwner())) 840b57cec5SDimitry Andric ST->removeValueName(V->getValueName()); 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 87*5f757f3fSDimitry Andric template <typename ValueSubClass, typename... Args> 88*5f757f3fSDimitry Andric void SymbolTableListTraits<ValueSubClass, Args...>::transferNodesFromList( 890b57cec5SDimitry Andric SymbolTableListTraits &L2, iterator first, iterator last) { 905ffd83dbSDimitry Andric // Transfering nodes, even within the same BB, invalidates the ordering. The 915ffd83dbSDimitry Andric // list that we removed the nodes from still has a valid ordering. 925ffd83dbSDimitry Andric ItemParentClass *NewIP = getListOwner(); 935ffd83dbSDimitry Andric invalidateParentIListOrdering(NewIP); 945ffd83dbSDimitry Andric 955ffd83dbSDimitry Andric // Nothing else needs to be done if we're reording nodes within the same list. 965ffd83dbSDimitry Andric ItemParentClass *OldIP = L2.getListOwner(); 970b57cec5SDimitry Andric if (NewIP == OldIP) 980b57cec5SDimitry Andric return; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric // We only have to update symbol table entries if we are transferring the 1010b57cec5SDimitry Andric // instructions to a different symtab object... 1020b57cec5SDimitry Andric ValueSymbolTable *NewST = getSymTab(NewIP); 1030b57cec5SDimitry Andric ValueSymbolTable *OldST = getSymTab(OldIP); 1040b57cec5SDimitry Andric if (NewST != OldST) { 1050b57cec5SDimitry Andric for (; first != last; ++first) { 1060b57cec5SDimitry Andric ValueSubClass &V = *first; 1070b57cec5SDimitry Andric bool HasName = V.hasName(); 1080b57cec5SDimitry Andric if (OldST && HasName) 1090b57cec5SDimitry Andric OldST->removeValueName(V.getValueName()); 1100b57cec5SDimitry Andric V.setParent(NewIP); 1110b57cec5SDimitry Andric if (NewST && HasName) 1120b57cec5SDimitry Andric NewST->reinsertValue(&V); 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric } else { 1150b57cec5SDimitry Andric // Just transferring between blocks in the same function, simply update the 1160b57cec5SDimitry Andric // parent fields in the instructions... 1170b57cec5SDimitry Andric for (; first != last; ++first) 1180b57cec5SDimitry Andric first->setParent(NewIP); 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric } // End llvm namespace 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric #endif 125