xref: /freebsd/contrib/llvm-project/llvm/lib/IR/SymbolTableListTraitsImpl.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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