diff options
author | Alexis Engelke <engelke@in.tum.de> | 2024-07-30 20:25:18 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-30 20:25:18 +0200 |
commit | 9f75270ceb3a0a3fb9b97980031a59652b7d5473 (patch) | |
tree | de4b2f0330f6f20c4a32cbbbcef6a5481bb41777 /llvm/lib/IR/Function.cpp | |
parent | d067062a42b0ce591f03c15cb76fe0fb27d1d9c1 (diff) | |
download | llvm-9f75270ceb3a0a3fb9b97980031a59652b7d5473.zip llvm-9f75270ceb3a0a3fb9b97980031a59652b7d5473.tar.gz llvm-9f75270ceb3a0a3fb9b97980031a59652b7d5473.tar.bz2 |
[IR] Add per-function numbers to basic blocks (#101052)
Every basic block that is linked into a function now has a unique
number, which can be queried using getNumber(). Numbers are densely
allocated, but not re-assigned on block removal for stability. Block
numbers are intended to be fairly stable and only be updated when
removing a several basic blocks to make sure the numbering doesn't
become too sparse.
To reduce holes in the numbering, renumberBlocks() can be called to
re-assign numbers in block order.
Additionally, getMaxBlockNumber() returns a value larger than the
largest block number, intended to pre-allocate/resize vectors.
Furthermore, this introduces the concept of a "block number epoch" --
an integer that changes after every renumbering. This is useful for
identifying use of block numbers after renumbering: on initialization,
the current epoch is stored, and on all subsequent accesses, equality
with the current epoch can be asserted.
I added a validate method to catch cases where something goes wrong,
even if I can't really imagine how invalid numbers can occur. But I
think it's better to be safe and rule out this potential source of bugs
when more things depend on the numbering.
Previous discussion in:
https://discourse.llvm.org/t/rfc-add-auxiliary-field-for-per-pass-custom-data-to-basicblock/80229
Diffstat (limited to 'llvm/lib/IR/Function.cpp')
-rw-r--r-- | llvm/lib/IR/Function.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 9b0dd5f..69520fd 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -13,6 +13,7 @@ #include "llvm/IR/Function.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" @@ -85,6 +86,27 @@ static cl::opt<int> NonGlobalValueMaxNameSize( extern cl::opt<bool> UseNewDbgInfoFormat; +void Function::renumberBlocks() { + validateBlockNumbers(); + + NextBlockNum = 0; + for (auto &BB : *this) + BB.Number = NextBlockNum++; + BlockNumEpoch++; +} + +void Function::validateBlockNumbers() const { +#ifndef NDEBUG + BitVector Numbers(NextBlockNum); + for (const auto &BB : *this) { + unsigned Num = BB.getNumber(); + assert(Num < NextBlockNum && "out of range block number"); + assert(!Numbers[Num] && "duplicate block numbers"); + Numbers.set(Num); + } +#endif +} + void Function::convertToNewDbgValues() { IsNewDbgInfoFormat = true; for (auto &BB : *this) { @@ -509,6 +531,8 @@ Function::Function(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, } Function::~Function() { + validateBlockNumbers(); + dropAllReferences(); // After this it is safe to delete instructions. // Delete all of the method arguments and unlink from symbol table... |