| //===-- llvm/SymbolTableListTraitsImpl.h - Implementation ------*- C++ -*--===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file implements the stickier parts of the SymbolTableListTraits class, | |
| // and is explicitly instantiated where needed to avoid defining all this code | |
| // in a widely used header. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef LLVM_LIB_IR_SYMBOLTABLELISTTRAITSIMPL_H | |
| #define LLVM_LIB_IR_SYMBOLTABLELISTTRAITSIMPL_H | |
| #include "llvm/IR/SymbolTableListTraits.h" | |
| #include "llvm/IR/ValueSymbolTable.h" | |
| namespace llvm { | |
| /// Notify basic blocks when an instruction is inserted. | |
| template <typename ParentClass> | |
| inline void invalidateParentIListOrdering(ParentClass *Parent) {} | |
| template <> void invalidateParentIListOrdering(BasicBlock *BB); | |
| /// setSymTabObject - This is called when (f.e.) the parent of a basic block | |
| /// changes. This requires us to remove all the instruction symtab entries from | |
| /// the current function and reinsert them into the new function. | |
| template <typename ValueSubClass> | |
| template <typename TPtr> | |
| void SymbolTableListTraits<ValueSubClass>::setSymTabObject(TPtr *Dest, | |
| TPtr Src) { | |
| // Get the old symtab and value list before doing the assignment. | |
| ValueSymbolTable *OldST = getSymTab(getListOwner()); | |
| // Do it. | |
| *Dest = Src; | |
| // Get the new SymTab object. | |
| ValueSymbolTable *NewST = getSymTab(getListOwner()); | |
| // If there is nothing to do, quick exit. | |
| if (OldST == NewST) return; | |
| // Move all the elements from the old symtab to the new one. | |
| ListTy &ItemList = getList(getListOwner()); | |
| if (ItemList.empty()) return; | |
| if (OldST) { | |
| // Remove all entries from the previous symtab. | |
| for (auto I = ItemList.begin(); I != ItemList.end(); ++I) | |
| if (I->hasName()) | |
| OldST->removeValueName(I->getValueName()); | |
| } | |
| if (NewST) { | |
| // Add all of the items to the new symtab. | |
| for (auto I = ItemList.begin(); I != ItemList.end(); ++I) | |
| if (I->hasName()) | |
| NewST->reinsertValue(&*I); | |
| } | |
| } | |
| template <typename ValueSubClass> | |
| void SymbolTableListTraits<ValueSubClass>::addNodeToList(ValueSubClass *V) { | |
| assert(!V->getParent() && "Value already in a container!!"); | |
| ItemParentClass *Owner = getListOwner(); | |
| V->setParent(Owner); | |
| invalidateParentIListOrdering(Owner); | |
| if (V->hasName()) | |
| if (ValueSymbolTable *ST = getSymTab(Owner)) | |
| ST->reinsertValue(V); | |
| } | |
| template <typename ValueSubClass> | |
| void SymbolTableListTraits<ValueSubClass>::removeNodeFromList( | |
| ValueSubClass *V) { | |
| V->setParent(nullptr); | |
| if (V->hasName()) | |
| if (ValueSymbolTable *ST = getSymTab(getListOwner())) | |
| ST->removeValueName(V->getValueName()); | |
| } | |
| template <typename ValueSubClass> | |
| void SymbolTableListTraits<ValueSubClass>::transferNodesFromList( | |
| SymbolTableListTraits &L2, iterator first, iterator last) { | |
| // Transfering nodes, even within the same BB, invalidates the ordering. The | |
| // list that we removed the nodes from still has a valid ordering. | |
| ItemParentClass *NewIP = getListOwner(); | |
| invalidateParentIListOrdering(NewIP); | |
| // Nothing else needs to be done if we're reording nodes within the same list. | |
| ItemParentClass *OldIP = L2.getListOwner(); | |
| if (NewIP == OldIP) | |
| return; | |
| // We only have to update symbol table entries if we are transferring the | |
| // instructions to a different symtab object... | |
| ValueSymbolTable *NewST = getSymTab(NewIP); | |
| ValueSymbolTable *OldST = getSymTab(OldIP); | |
| if (NewST != OldST) { | |
| for (; first != last; ++first) { | |
| ValueSubClass &V = *first; | |
| bool HasName = V.hasName(); | |
| if (OldST && HasName) | |
| OldST->removeValueName(V.getValueName()); | |
| V.setParent(NewIP); | |
| if (NewST && HasName) | |
| NewST->reinsertValue(&V); | |
| } | |
| } else { | |
| // Just transferring between blocks in the same function, simply update the | |
| // parent fields in the instructions... | |
| for (; first != last; ++first) | |
| first->setParent(NewIP); | |
| } | |
| } | |
| } // End llvm namespace | |
| #endif |