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(Par: getListOwner()); |
37 | |
38 | // Do it. |
39 | *Dest = Src; |
40 | |
41 | // Get the new SymTab object. |
42 | ValueSymbolTable *NewST = getSymTab(Par: 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(Par: 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(V: 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(V: &*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(Par: 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(Par: getListOwner())) |
84 | ST->removeValueName(V: 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(Par: NewIP); |
103 | ValueSymbolTable *OldST = getSymTab(Par: 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: V.getValueName()); |
110 | V.setParent(NewIP); |
111 | if (NewST && HasName) |
112 | NewST->reinsertValue(V: &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 | |