[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:
parent
bea7080fe3
commit
be40b8ec4e
3 changed files with 58 additions and 0 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue