[CycleInfo] Index using block numbers instead of pointers (#187500)
Replace the DenseMap from block pointer to cycle with a vector indexed by block number, which makes the lookup more efficient.
This commit is contained in:
parent
5ae5f9df42
commit
70bb9e2452
@ -313,13 +313,34 @@ void GenericCycleInfo<ContextT>::moveTopLevelCycleToNewParent(CycleT *NewParent,
|
||||
Child->clearCache();
|
||||
}
|
||||
|
||||
template <typename ContextT>
|
||||
void GenericCycleInfo<ContextT>::verifyBlockNumberEpoch(
|
||||
const FunctionT *Fn) const {
|
||||
assert(BlockNumberEpoch ==
|
||||
GraphTraits<const FunctionT *>::getNumberEpoch(Fn) &&
|
||||
"CycleInfo used with outdated block number epoch");
|
||||
}
|
||||
|
||||
template <typename ContextT>
|
||||
void GenericCycleInfo<ContextT>::addToBlockMap(BlockT *Block, CycleT *Cycle) {
|
||||
// The caller should ensure that BlockMap is large enough.
|
||||
verifyBlockNumberEpoch(Block->getParent());
|
||||
unsigned Number = GraphTraits<BlockT *>::getNumber(Block);
|
||||
BlockMap[Number] = Cycle;
|
||||
}
|
||||
|
||||
template <typename ContextT>
|
||||
void GenericCycleInfo<ContextT>::addBlockToCycle(BlockT *Block, CycleT *Cycle) {
|
||||
// Make sure BlockMap is large enough for the new block.
|
||||
unsigned Number = GraphTraits<BlockT *>::getNumber(Block);
|
||||
if (Number >= BlockMap.size())
|
||||
BlockMap.resize(GraphTraits<FunctionT *>::getMaxNumber(Block->getParent()));
|
||||
|
||||
// FixMe: Appending NewBlock is fine as a set of blocks in a cycle. When
|
||||
// printing, cycle NewBlock is at the end of list but it should be in the
|
||||
// middle to represent actual traversal of a cycle.
|
||||
Cycle->appendBlock(Block);
|
||||
BlockMap.try_emplace(Block, Cycle);
|
||||
addToBlockMap(Block, Cycle);
|
||||
|
||||
CycleT *ParentCycle = Cycle->getParentCycle();
|
||||
while (ParentCycle) {
|
||||
@ -361,7 +382,7 @@ void GenericCycleInfoCompute<ContextT>::run(FunctionT *F) {
|
||||
std::unique_ptr<CycleT> NewCycle = std::make_unique<CycleT>();
|
||||
NewCycle->appendEntry(HeaderCandidate);
|
||||
NewCycle->appendBlock(HeaderCandidate);
|
||||
Info.BlockMap.try_emplace(HeaderCandidate, NewCycle.get());
|
||||
Info.addToBlockMap(HeaderCandidate, NewCycle.get());
|
||||
|
||||
// Helper function to process (non-back-edge) predecessors of a discovered
|
||||
// block and either add them to the worklist or recognize that the given
|
||||
@ -417,7 +438,7 @@ void GenericCycleInfoCompute<ContextT>::run(FunctionT *F) {
|
||||
<< Info.Context.print(BlockParent->getHeader()) << "\n");
|
||||
}
|
||||
} else {
|
||||
Info.BlockMap.try_emplace(Block, NewCycle.get());
|
||||
Info.addToBlockMap(Block, NewCycle.get());
|
||||
assert(!is_contained(NewCycle->Blocks, Block));
|
||||
NewCycle->Blocks.insert(Block);
|
||||
ProcessPredecessors(Block);
|
||||
@ -508,6 +529,8 @@ template <typename ContextT>
|
||||
void GenericCycleInfo<ContextT>::compute(FunctionT &F) {
|
||||
GenericCycleInfoCompute<ContextT> Compute(*this);
|
||||
Context = ContextT(&F);
|
||||
BlockNumberEpoch = GraphTraits<FunctionT *>::getNumberEpoch(&F);
|
||||
BlockMap.resize(GraphTraits<FunctionT *>::getMaxNumber(&F));
|
||||
|
||||
LLVM_DEBUG(errs() << "Computing cycles for function: " << F.getName()
|
||||
<< "\n");
|
||||
@ -534,7 +557,9 @@ void GenericCycleInfo<ContextT>::splitCriticalEdge(BlockT *Pred, BlockT *Succ,
|
||||
template <typename ContextT>
|
||||
auto GenericCycleInfo<ContextT>::getCycle(const BlockT *Block) const
|
||||
-> CycleT * {
|
||||
return BlockMap.lookup(Block);
|
||||
verifyBlockNumberEpoch(Block->getParent());
|
||||
unsigned Number = GraphTraits<const BlockT *>::getNumber(Block);
|
||||
return Number < BlockMap.size() ? BlockMap[Number] : nullptr;
|
||||
}
|
||||
|
||||
/// \brief Find the innermost cycle containing both given cycles.
|
||||
@ -608,9 +633,9 @@ void GenericCycleInfo<ContextT>::verifyCycleNest(bool VerifyFull) const {
|
||||
Cycle->verifyCycleNest();
|
||||
// Check the block map entries for blocks contained in this cycle.
|
||||
for (BlockT *BB : Cycle->blocks()) {
|
||||
auto MapIt = BlockMap.find(BB);
|
||||
assert(MapIt != BlockMap.end());
|
||||
assert(Cycle->contains(MapIt->second));
|
||||
CycleT *CycleInBlockMap = getCycle(BB);
|
||||
assert(CycleInBlockMap != nullptr);
|
||||
assert(Cycle->contains(CycleInBlockMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,9 +266,10 @@ public:
|
||||
|
||||
private:
|
||||
ContextT Context;
|
||||
unsigned BlockNumberEpoch;
|
||||
|
||||
/// Map basic blocks to their inner-most containing cycle.
|
||||
DenseMap<BlockT *, CycleT *> BlockMap;
|
||||
/// Map basic block numbers to their inner-most containing cycle.
|
||||
SmallVector<CycleT *> BlockMap;
|
||||
|
||||
/// Top-level cycles discovered by any DFS.
|
||||
///
|
||||
@ -282,6 +283,9 @@ private:
|
||||
/// the subtree.
|
||||
void moveTopLevelCycleToNewParent(CycleT *NewParent, CycleT *Child);
|
||||
|
||||
void verifyBlockNumberEpoch(const FunctionT *Fn) const;
|
||||
void addToBlockMap(BlockT *Block, CycleT *Cycle);
|
||||
|
||||
public:
|
||||
GenericCycleInfo() = default;
|
||||
GenericCycleInfo(GenericCycleInfo &&) = default;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user