125 lines
4.2 KiB
C++
125 lines
4.2 KiB
C++
//===-- 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
|