[LICM] Use DomTreeUpdater version of SplitBlockPredecessors, nfc (#107190)

The DominatorTree version is marked for deprecation, so we use the
DomTreeUpdater version. We also update sinkRegion() to iterate over
basic blocks instead of DomTreeNodes. The loop body calls
SplitBlockPredecessors. The DTU version calls
DomTreeUpdater::apply_updates(), which may call DominatorTree::reset().
This invalidates the worklist of DomTreeNodes to iterate over.
This commit is contained in:
Joshua Cao
2024-09-29 21:28:45 -07:00
committed by GitHub
parent 6f3c15163f
commit 0bc98349c8
3 changed files with 17 additions and 15 deletions

View File

@@ -224,9 +224,9 @@ bool promoteLoopAccessesToScalars(
bool AllowSpeculation, bool HasReadsOutsideSet);
/// Does a BFS from a given node to all of its children inside a given loop.
/// The returned vector of nodes includes the starting point.
SmallVector<DomTreeNode *, 16> collectChildrenInLoop(DomTreeNode *N,
const Loop *CurLoop);
/// The returned vector of basic blocks includes the starting point.
SmallVector<BasicBlock *, 16>
collectChildrenInLoop(DominatorTree *DT, DomTreeNode *N, const Loop *CurLoop);
/// Returns the instructions that use values defined in the loop.
SmallVector<Instruction *, 8> findDefsUsedOutsideOfLoop(Loop *L);

View File

@@ -44,6 +44,7 @@
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/GuardUtils.h"
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
#include "llvm/Analysis/Loads.h"
@@ -65,9 +66,9 @@
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/PatternMatch.h"
@@ -567,12 +568,11 @@ bool llvm::sinkRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
// We want to visit children before parents. We will enqueue all the parents
// before their children in the worklist and process the worklist in reverse
// order.
SmallVector<DomTreeNode *, 16> Worklist = collectChildrenInLoop(N, CurLoop);
SmallVector<BasicBlock *, 16> Worklist =
collectChildrenInLoop(DT, N, CurLoop);
bool Changed = false;
for (DomTreeNode *DTN : reverse(Worklist)) {
BasicBlock *BB = DTN->getBlock();
// Only need to process the contents of this block if it is not part of a
for (BasicBlock *BB : reverse(Worklist)) {
// subloop (which would already have been processed).
if (inSubLoop(BB, CurLoop, LI))
continue;
@@ -1603,13 +1603,14 @@ static void splitPredecessorsOfLoopExit(PHINode *PN, DominatorTree *DT,
//
const auto &BlockColors = SafetyInfo->getBlockColors();
SmallSetVector<BasicBlock *, 8> PredBBs(pred_begin(ExitBB), pred_end(ExitBB));
DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
while (!PredBBs.empty()) {
BasicBlock *PredBB = *PredBBs.begin();
assert(CurLoop->contains(PredBB) &&
"Expect all predecessors are in the loop");
if (PN->getBasicBlockIndex(PredBB) >= 0) {
BasicBlock *NewPred = SplitBlockPredecessors(
ExitBB, PredBB, ".split.loop.exit", DT, LI, MSSAU, true);
ExitBB, PredBB, ".split.loop.exit", &DTU, LI, MSSAU, true);
// Since we do not allow splitting EH-block with BlockColors in
// canSplitPredecessors(), we can simply assign predecessor's color to
// the new block.

View File

@@ -445,21 +445,22 @@ TransformationMode llvm::hasLICMVersioningTransformation(const Loop *L) {
}
/// Does a BFS from a given node to all of its children inside a given loop.
/// The returned vector of nodes includes the starting point.
SmallVector<DomTreeNode *, 16>
llvm::collectChildrenInLoop(DomTreeNode *N, const Loop *CurLoop) {
SmallVector<DomTreeNode *, 16> Worklist;
/// The returned vector of basic blocks includes the starting point.
SmallVector<BasicBlock *, 16> llvm::collectChildrenInLoop(DominatorTree *DT,
DomTreeNode *N,
const Loop *CurLoop) {
SmallVector<BasicBlock *, 16> Worklist;
auto AddRegionToWorklist = [&](DomTreeNode *DTN) {
// Only include subregions in the top level loop.
BasicBlock *BB = DTN->getBlock();
if (CurLoop->contains(BB))
Worklist.push_back(DTN);
Worklist.push_back(DTN->getBlock());
};
AddRegionToWorklist(N);
for (size_t I = 0; I < Worklist.size(); I++) {
for (DomTreeNode *Child : Worklist[I]->children())
for (DomTreeNode *Child : DT->getNode(Worklist[I])->children())
AddRegionToWorklist(Child);
}