mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
2a197a86b4
Essentially, fold OrderedBasicBlock into BasicBlock, and make it auto-invalidate the instruction ordering when new instructions are added. Notably, we don't need to invalidate it when removing instructions, which is helpful when a pass mostly delete dead instructions rather than transforming them. The downside is that Instruction grows from 56 bytes to 64 bytes. The resulting LLVM code is substantially simpler and automatically handles invalidation, which makes me think that this is the right speed and size tradeoff. The important change is in SymbolTableTraitsImpl.h, where the numbering is invalidated. Everything else should be straightforward. We probably want to implement a fancier re-numbering scheme so that local updates don't invalidate the ordering, but I plan for that to be future work, maybe for someone else. Reviewed By: lattner, vsk, fhahn, dexonsmith Differential Revision: https://reviews.llvm.org/D51664
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
|