[BOLT] Give BinaryBasicBlock a GraphTraits block number (#207899)

LoopInfoBase (and DominatorTreeBase) keep a DenseMap fallback for block
types whose GraphTraits lacks getNumber() (#103400); BOLT's
BinaryLoopInfo is one of the last two users.

BinaryBasicBlock already carries a dense [0, size) index (getIndex(),
assigned by updateBBIndices()). Expose it as the GraphTraits node
number, mirroring llvm::BasicBlock/Function.

This makes `GraphHasNodeNumbers<BinaryBasicBlock *>` true, moving BOLT's
LoopInfo and DominatorTree onto the number-indexed (SmallVector) path.
Prerequisite for requiring GraphHasNodeNumbers in LoopInfoBase.

Aided by Claude Opus 4.8
This commit is contained in:
Fangrui Song 2026-07-08 23:46:17 -07:00 committed by GitHub
parent bea7080fe3
commit be40b8ec4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 58 additions and 0 deletions

View file

@ -980,8 +980,14 @@ template <> struct GraphTraits<bolt::BinaryBasicBlock *> {
return N->succ_begin();
}
static inline ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
static unsigned getNumber(const bolt::BinaryBasicBlock *BB) {
return BB->getIndex();
}
};
static_assert(GraphHasNodeNumbers<bolt::BinaryBasicBlock *>,
"GraphTraits getNumber() not detected");
template <> struct GraphTraits<const bolt::BinaryBasicBlock *> {
using NodeRef = const bolt::BinaryBasicBlock *;
using ChildIteratorType = bolt::BinaryBasicBlock::const_succ_iterator;
@ -991,8 +997,14 @@ template <> struct GraphTraits<const bolt::BinaryBasicBlock *> {
return N->succ_begin();
}
static inline ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
static unsigned getNumber(const bolt::BinaryBasicBlock *BB) {
return BB->getIndex();
}
};
static_assert(GraphHasNodeNumbers<const bolt::BinaryBasicBlock *>,
"GraphTraits getNumber() not detected");
template <> struct GraphTraits<Inverse<bolt::BinaryBasicBlock *>> {
using NodeRef = bolt::BinaryBasicBlock *;
using ChildIteratorType = bolt::BinaryBasicBlock::pred_iterator;
@ -1003,8 +1015,14 @@ template <> struct GraphTraits<Inverse<bolt::BinaryBasicBlock *>> {
return N->pred_begin();
}
static inline ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
static unsigned getNumber(const bolt::BinaryBasicBlock *BB) {
return BB->getIndex();
}
};
static_assert(GraphHasNodeNumbers<Inverse<bolt::BinaryBasicBlock *>>,
"GraphTraits getNumber() not detected");
template <> struct GraphTraits<Inverse<const bolt::BinaryBasicBlock *>> {
using NodeRef = const bolt::BinaryBasicBlock *;
using ChildIteratorType = bolt::BinaryBasicBlock::const_pred_iterator;
@ -1015,8 +1033,14 @@ template <> struct GraphTraits<Inverse<const bolt::BinaryBasicBlock *>> {
return N->pred_begin();
}
static inline ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
static unsigned getNumber(const bolt::BinaryBasicBlock *BB) {
return BB->getIndex();
}
};
static_assert(GraphHasNodeNumbers<Inverse<const bolt::BinaryBasicBlock *>>,
"GraphTraits getNumber() not detected");
} // namespace llvm
#endif

View file

@ -279,6 +279,10 @@ private:
std::unique_ptr<BinaryLoopInfo> BLI;
std::unique_ptr<BinaryDominatorTree> BDT;
/// Epoch for basic block indices, bumped by updateBBIndices(). See
/// getBlockNumberEpoch().
unsigned BlockNumberEpoch = 0;
/// All labels in the function that are referenced via relocations from
/// data objects. Typically these are jump table destinations and computed
/// goto labels.
@ -833,6 +837,11 @@ public:
BinaryBasicBlock &front() { return *BasicBlocks.front(); }
const BinaryBasicBlock & back() const { return *BasicBlocks.back(); }
BinaryBasicBlock & back() { return *BasicBlocks.back(); }
/// Epoch bumped whenever basic block indices are reassigned by
/// updateBBIndices(), so number-indexed structures (LoopInfo, DominatorTree)
/// can detect stale block numbers. See BinaryBasicBlock::getIndex().
unsigned getBlockNumberEpoch() const { return BlockNumberEpoch; }
inline iterator_range<iterator> blocks() {
return iterator_range<iterator>(begin(), end());
}
@ -2652,6 +2661,12 @@ struct GraphTraits<bolt::BinaryFunction *>
return nodes_iterator(F->end());
}
static size_t size(bolt::BinaryFunction *F) { return F->size(); }
static unsigned getMaxNumber(const bolt::BinaryFunction *F) {
return F->size();
}
static unsigned getNumberEpoch(const bolt::BinaryFunction *F) {
return F->getBlockNumberEpoch();
}
};
template <>
@ -2672,6 +2687,12 @@ struct GraphTraits<const bolt::BinaryFunction *>
return nodes_iterator(F->end());
}
static size_t size(const bolt::BinaryFunction *F) { return F->size(); }
static unsigned getMaxNumber(const bolt::BinaryFunction *F) {
return F->size();
}
static unsigned getNumberEpoch(const bolt::BinaryFunction *F) {
return F->getBlockNumberEpoch();
}
};
template <>
@ -2680,6 +2701,12 @@ struct GraphTraits<Inverse<bolt::BinaryFunction *>>
static NodeRef getEntryNode(Inverse<bolt::BinaryFunction *> G) {
return G.Graph->getLayout().block_front();
}
static unsigned getMaxNumber(const bolt::BinaryFunction *F) {
return F->size();
}
static unsigned getNumberEpoch(const bolt::BinaryFunction *F) {
return F->getBlockNumberEpoch();
}
};
template <>
@ -2688,6 +2715,12 @@ struct GraphTraits<Inverse<const bolt::BinaryFunction *>>
static NodeRef getEntryNode(Inverse<const bolt::BinaryFunction *> G) {
return G.Graph->getLayout().block_front();
}
static unsigned getMaxNumber(const bolt::BinaryFunction *F) {
return F->size();
}
static unsigned getNumberEpoch(const bolt::BinaryFunction *F) {
return F->getBlockNumberEpoch();
}
};
} // namespace llvm

View file

@ -4124,6 +4124,7 @@ BinaryFunction::iterator BinaryFunction::insertBasicBlocks(
void BinaryFunction::updateBBIndices(const unsigned StartIndex) {
for (unsigned I = StartIndex; I < BasicBlocks.size(); ++I)
BasicBlocks[I]->Index = I;
++BlockNumberEpoch;
}
void BinaryFunction::updateCFIState(BinaryBasicBlock *Start,