diff options
author | Reid Kleckner <rnk@google.com> | 2020-02-18 14:33:54 -0800 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2020-02-18 14:44:24 -0800 |
commit | 0c2b09a9b6246aebd301ad75b5d78ac1e7daa9c4 (patch) | |
tree | 78e0ee3538d98817390b8f9513108b835dcd7191 /llvm/lib/IR/BasicBlock.cpp | |
parent | cf4574299a279beeb8acb894583962ec0f41286c (diff) | |
download | llvm-0c2b09a9b6246aebd301ad75b5d78ac1e7daa9c4.zip llvm-0c2b09a9b6246aebd301ad75b5d78ac1e7daa9c4.tar.gz llvm-0c2b09a9b6246aebd301ad75b5d78ac1e7daa9c4.tar.bz2 |
[IR] Lazily number instructions for local dominance queries
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
Diffstat (limited to 'llvm/lib/IR/BasicBlock.cpp')
-rw-r--r-- | llvm/lib/IR/BasicBlock.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp index d9a9536..679c72f 100644 --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -33,6 +33,10 @@ LLVMContext &BasicBlock::getContext() const { return getType()->getContext(); } +template <> void llvm::invalidateParentIListOrdering(BasicBlock *BB) { + BB->invalidateOrders(); +} + // Explicit instantiation of SymbolTableListTraits since some of the methods // are not in the public header file... template class llvm::SymbolTableListTraits<Instruction>; @@ -61,6 +65,8 @@ void BasicBlock::insertInto(Function *NewParent, BasicBlock *InsertBefore) { } BasicBlock::~BasicBlock() { + validateInstrOrdering(); + // If the address of the block is taken and it is being deleted (e.g. because // it is dead), this means that there is either a dangling constant expr // hanging off the block, or an undefined use of the block (source code @@ -506,3 +512,29 @@ BasicBlock::iterator llvm::skipDebugIntrinsics(BasicBlock::iterator It) { ++It; return It; } + +void BasicBlock::renumberInstructions() { + unsigned Order = 0; + for (Instruction &I : *this) + I.Order = Order++; + + // Set the bit to indicate that the instruction order valid and cached. + BasicBlockBits Bits = getBasicBlockBits(); + Bits.InstrOrderValid = true; + setBasicBlockBits(Bits); +} + +#ifndef NDEBUG +/// In asserts builds, this checks the numbering. In non-asserts builds, it +/// is defined as an inline function returning true in BasicBlock.h. +void BasicBlock::validateInstrOrdering() const { + if (!isInstrOrderValid()) + return; + const Instruction *Prev = nullptr; + for (const Instruction &I : *this) { + assert((!Prev || Prev->comesBefore(&I)) && + "cached instruction ordering is incorrect"); + Prev = &I; + } +} +#endif |