2525#include " llvm/IR/BasicBlock.h"
2626#include " llvm/IR/CallSite.h"
2727#include " llvm/IR/DerivedTypes.h"
28+ #include " llvm/IR/DomTreeUpdater.h"
29+ #include " llvm/IR/Dominators.h"
2830#include " llvm/IR/Function.h"
2931#include " llvm/IR/IRBuilder.h"
3032#include " llvm/IR/InstVisitor.h"
@@ -112,6 +114,7 @@ class PGOMemOPSizeOptLegacyPass : public FunctionPass {
112114 AU.addRequired <BlockFrequencyInfoWrapperPass>();
113115 AU.addRequired <OptimizationRemarkEmitterWrapperPass>();
114116 AU.addPreserved <GlobalsAAWrapperPass>();
117+ AU.addPreserved <DominatorTreeWrapperPass>();
115118 }
116119};
117120} // end anonymous namespace
@@ -133,8 +136,8 @@ namespace {
133136class MemOPSizeOpt : public InstVisitor <MemOPSizeOpt> {
134137public:
135138 MemOPSizeOpt (Function &Func, BlockFrequencyInfo &BFI,
136- OptimizationRemarkEmitter &ORE)
137- : Func(Func), BFI(BFI), ORE(ORE), Changed(false ) {
139+ OptimizationRemarkEmitter &ORE, DominatorTree *DT )
140+ : Func(Func), BFI(BFI), ORE(ORE), DT(DT), Changed(false ) {
138141 ValueDataArray =
139142 llvm::make_unique<InstrProfValueData[]>(MemOPMaxVersion + 2 );
140143 // Get the MemOPSize range information from option MemOPSizeRange,
@@ -170,6 +173,7 @@ class MemOPSizeOpt : public InstVisitor<MemOPSizeOpt> {
170173 Function &Func;
171174 BlockFrequencyInfo &BFI;
172175 OptimizationRemarkEmitter &ORE;
176+ DominatorTree *DT;
173177 bool Changed;
174178 std::vector<MemIntrinsic *> WorkList;
175179 // Start of the previse range.
@@ -336,15 +340,16 @@ bool MemOPSizeOpt::perform(MemIntrinsic *MI) {
336340 LLVM_DEBUG (dbgs () << *BB << " \n " );
337341 auto OrigBBFreq = BFI.getBlockFreq (BB);
338342
339- BasicBlock *DefaultBB = SplitBlock (BB, MI);
343+ BasicBlock *DefaultBB = SplitBlock (BB, MI, DT );
340344 BasicBlock::iterator It (*MI);
341345 ++It;
342346 assert (It != DefaultBB->end ());
343- BasicBlock *MergeBB = SplitBlock (DefaultBB, &(*It));
347+ BasicBlock *MergeBB = SplitBlock (DefaultBB, &(*It), DT );
344348 MergeBB->setName (" MemOP.Merge" );
345349 BFI.setBlockFreq (MergeBB, OrigBBFreq.getFrequency ());
346350 DefaultBB->setName (" MemOP.Default" );
347351
352+ DomTreeUpdater DTU (DT, DomTreeUpdater::UpdateStrategy::Eager);
348353 auto &Ctx = Func.getContext ();
349354 IRBuilder<> IRB (BB);
350355 BB->getTerminator ()->eraseFromParent ();
@@ -361,6 +366,10 @@ bool MemOPSizeOpt::perform(MemIntrinsic *MI) {
361366
362367 LLVM_DEBUG (dbgs () << " \n\n == Basic Block After==\n " );
363368
369+ std::vector<DominatorTree::UpdateType> Updates;
370+ if (DT)
371+ Updates.reserve (2 * SizeIds.size ());
372+
364373 for (uint64_t SizeId : SizeIds) {
365374 BasicBlock *CaseBB = BasicBlock::Create (
366375 Ctx, Twine (" MemOP.Case." ) + Twine (SizeId), &Func, DefaultBB);
@@ -375,8 +384,15 @@ bool MemOPSizeOpt::perform(MemIntrinsic *MI) {
375384 IRBuilder<> IRBCase (CaseBB);
376385 IRBCase.CreateBr (MergeBB);
377386 SI->addCase (CaseSizeId, CaseBB);
387+ if (DT) {
388+ Updates.push_back ({DominatorTree::Insert, CaseBB, MergeBB});
389+ Updates.push_back ({DominatorTree::Insert, BB, CaseBB});
390+ }
378391 LLVM_DEBUG (dbgs () << *CaseBB << " \n " );
379392 }
393+ DTU.applyUpdates (Updates);
394+ Updates.clear ();
395+
380396 setProfMetadata (Func.getParent (), SI, CaseCounts, MaxCount);
381397
382398 LLVM_DEBUG (dbgs () << *BB << " \n " );
@@ -397,13 +413,14 @@ bool MemOPSizeOpt::perform(MemIntrinsic *MI) {
397413} // namespace
398414
399415static bool PGOMemOPSizeOptImpl (Function &F, BlockFrequencyInfo &BFI,
400- OptimizationRemarkEmitter &ORE) {
416+ OptimizationRemarkEmitter &ORE,
417+ DominatorTree *DT) {
401418 if (DisableMemOPOPT)
402419 return false ;
403420
404421 if (F.hasFnAttribute (Attribute::OptimizeForSize))
405422 return false ;
406- MemOPSizeOpt MemOPSizeOpt (F, BFI, ORE);
423+ MemOPSizeOpt MemOPSizeOpt (F, BFI, ORE, DT );
407424 MemOPSizeOpt.perform ();
408425 return MemOPSizeOpt.isChanged ();
409426}
@@ -412,7 +429,9 @@ bool PGOMemOPSizeOptLegacyPass::runOnFunction(Function &F) {
412429 BlockFrequencyInfo &BFI =
413430 getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI ();
414431 auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE ();
415- return PGOMemOPSizeOptImpl (F, BFI, ORE);
432+ auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
433+ DominatorTree *DT = DTWP ? &DTWP->getDomTree () : nullptr ;
434+ return PGOMemOPSizeOptImpl (F, BFI, ORE, DT);
416435}
417436
418437namespace llvm {
@@ -422,11 +441,13 @@ PreservedAnalyses PGOMemOPSizeOpt::run(Function &F,
422441 FunctionAnalysisManager &FAM) {
423442 auto &BFI = FAM.getResult <BlockFrequencyAnalysis>(F);
424443 auto &ORE = FAM.getResult <OptimizationRemarkEmitterAnalysis>(F);
425- bool Changed = PGOMemOPSizeOptImpl (F, BFI, ORE);
444+ auto *DT = FAM.getCachedResult <DominatorTreeAnalysis>(F);
445+ bool Changed = PGOMemOPSizeOptImpl (F, BFI, ORE, DT);
426446 if (!Changed)
427447 return PreservedAnalyses::all ();
428448 auto PA = PreservedAnalyses ();
429449 PA.preserve <GlobalsAA>();
450+ PA.preserve <DominatorTreeAnalysis>();
430451 return PA;
431452}
432453} // namespace llvm
0 commit comments