@@ -36,25 +36,18 @@ using namespace llvm;
3636
3737namespace {
3838
39- void updateDomTreeForScalableExpansion (DominatorTree *DT, BasicBlock *Preheader,
40- BasicBlock *Loop, BasicBlock *Exit) {
41- DT->addNewBlock (Loop, Preheader);
42- DT->changeImmediateDominator (Exit, Loop);
43- assert (DT->verify (DominatorTree::VerificationLevel::Fast));
44- }
45-
4639// / Expand a reduction on a scalable vector into a loop
4740// / that iterates over one element after the other.
4841Value *expandScalableReduction (IRBuilderBase &Builder, IntrinsicInst *II,
4942 Value *Acc, Value *Vec,
5043 Instruction::BinaryOps BinOp,
51- DominatorTree *DT ) {
44+ DomTreeUpdater &DTU ) {
5245 ScalableVectorType *VecTy = cast<ScalableVectorType>(Vec->getType ());
5346
5447 // Split the original BB in two and create a new BB between them,
5548 // which will be a loop.
5649 BasicBlock *BeforeBB = II->getParent ();
57- BasicBlock *AfterBB = SplitBlock (BeforeBB, II, DT );
50+ BasicBlock *AfterBB = SplitBlock (BeforeBB, II, &DTU );
5851 BasicBlock *LoopBB = BasicBlock::Create (Builder.getContext (), " rdx.loop" ,
5952 BeforeBB->getParent (), AfterBB);
6053 BeforeBB->getTerminator ()->setSuccessor (0 , LoopBB);
@@ -87,9 +80,9 @@ Value *expandScalableReduction(IRBuilderBase &Builder, IntrinsicInst *II,
8780 Value *Done = Builder.CreateCmp (CmpInst::ICMP_EQ, IVInc, NumElts, " exitcond" );
8881 Builder.CreateCondBr (Done, AfterBB, LoopBB);
8982
90- if (DT)
91- updateDomTreeForScalableExpansion (DT, BeforeBB , LoopBB, AfterBB);
92-
83+ DTU. applyUpdates ({{DominatorTree::Insert, BeforeBB, LoopBB},
84+ {DominatorTree::Insert , LoopBB, AfterBB},
85+ {DominatorTree::Delete, BeforeBB, AfterBB}});
9386 return Rdx;
9487}
9588
@@ -99,7 +92,7 @@ Value *expandScalableReduction(IRBuilderBase &Builder, IntrinsicInst *II,
9992Value *expandScalableTreeReduction (
10093 IRBuilderBase &Builder, IntrinsicInst *II, std::optional<Value *> Acc,
10194 Value *Vec, Instruction::BinaryOps BinOp,
102- function_ref<bool (Constant *)> IsNeutralElement, DominatorTree *DT ,
95+ function_ref<bool (Constant *)> IsNeutralElement, DomTreeUpdater &DTU ,
10396 std::optional<unsigned> FixedVScale) {
10497 ScalableVectorType *VecTy = cast<ScalableVectorType>(Vec->getType ());
10598 ScalableVectorType *VecTyX2 = ScalableVectorType::get (
@@ -133,7 +126,7 @@ Value *expandScalableTreeReduction(
133126 // Split the original BB in two and create a new BB between them,
134127 // which will be a loop.
135128 BasicBlock *BeforeBB = II->getParent ();
136- BasicBlock *AfterBB = SplitBlock (BeforeBB, II, DT );
129+ BasicBlock *AfterBB = SplitBlock (BeforeBB, II, &DTU );
137130 BasicBlock *LoopBB = BasicBlock::Create (Builder.getContext (), " rdx.loop" ,
138131 BeforeBB->getParent (), AfterBB);
139132 BeforeBB->getTerminator ()->setSuccessor (0 , LoopBB);
@@ -186,15 +179,16 @@ Value *expandScalableTreeReduction(
186179 if (auto *C = dyn_cast<Constant>(*Acc); !C || !IsNeutralElement (C))
187180 FinalVal = Builder.CreateBinOp (BinOp, *Acc, FinalVal, " rdx.final" );
188181
189- if (DT)
190- updateDomTreeForScalableExpansion (DT, BeforeBB, LoopBB, AfterBB);
182+ DTU.applyUpdates ({{DominatorTree::Insert, BeforeBB, LoopBB},
183+ {DominatorTree::Insert, LoopBB, AfterBB},
184+ {DominatorTree::Delete, BeforeBB, AfterBB}});
191185
192186 return FinalVal;
193187}
194188
195189std::pair<bool , bool > expandReductions (Function &F,
196190 const TargetTransformInfo *TTI,
197- DominatorTree *DT ) {
191+ DomTreeUpdater &DTU ) {
198192 bool Changed = false , CFGChanged = false ;
199193 SmallVector<IntrinsicInst *, 4 > Worklist;
200194 for (auto &I : instructions (F)) {
@@ -270,9 +264,9 @@ std::pair<bool, bool> expandReductions(Function &F,
270264 llvm_unreachable (" Binop not handled" );
271265 }
272266 },
273- DT , FixedVScale);
267+ DTU , FixedVScale);
274268 else
275- Rdx = expandScalableReduction (Builder, II, Acc, Vec, RdxOpcode, DT );
269+ Rdx = expandScalableReduction (Builder, II, Acc, Vec, RdxOpcode, DTU );
276270 break ;
277271 }
278272
@@ -335,7 +329,7 @@ std::pair<bool, bool> expandReductions(Function &F,
335329 Rdx = expandScalableTreeReduction (
336330 Builder, II, std::nullopt , Vec, Instruction::BinaryOps (RdxOpcode),
337331 [](Constant *C) -> bool { llvm_unreachable (" No accumulator!" ); },
338- DT , FixedVScale);
332+ DTU , FixedVScale);
339333 break ;
340334 }
341335
@@ -363,6 +357,11 @@ std::pair<bool, bool> expandReductions(Function &F,
363357 II->eraseFromParent ();
364358 Changed = true ;
365359 }
360+
361+ if (DTU.hasDomTree () && DTU.hasPendingUpdates ()) {
362+ DTU.flush ();
363+ assert (DTU.getDomTree ().verify (DominatorTree::VerificationLevel::Fast));
364+ }
366365 return {CFGChanged, Changed};
367366}
368367
@@ -376,7 +375,9 @@ class ExpandReductions : public FunctionPass {
376375 bool runOnFunction (Function &F) override {
377376 const auto *TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI (F);
378377 auto *DTA = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
379- return expandReductions (F, TTI, DTA ? &DTA->getDomTree () : nullptr ).second ;
378+ DomTreeUpdater DTU (DTA ? &DTA->getDomTree () : nullptr ,
379+ DomTreeUpdater::UpdateStrategy::Lazy);
380+ return expandReductions (F, TTI, DTU).second ;
380381 }
381382
382383 void getAnalysisUsage (AnalysisUsage &AU) const override {
@@ -402,7 +403,8 @@ PreservedAnalyses ExpandReductionsPass::run(Function &F,
402403 FunctionAnalysisManager &AM) {
403404 const auto &TTI = AM.getResult <TargetIRAnalysis>(F);
404405 auto *DT = AM.getCachedResult <DominatorTreeAnalysis>(F);
405- auto [CFGChanged, Changed] = expandReductions (F, &TTI, DT);
406+ DomTreeUpdater DTU (DT, DomTreeUpdater::UpdateStrategy::Lazy);
407+ auto [CFGChanged, Changed] = expandReductions (F, &TTI, DTU);
406408 if (!Changed)
407409 return PreservedAnalyses::all ();
408410 PreservedAnalyses PA;
0 commit comments