@@ -149,14 +149,14 @@ static void recordCondition(CallSite CS, BasicBlock *From, BasicBlock *To,
149
149
150
150
// / Record ICmp conditions relevant to any argument in CS following Pred's
151
151
// / single predecessors. If there are conflicting conditions along a path, like
152
- // / x == 1 and x == 0, the first condition will be used.
152
+ // / x == 1 and x == 0, the first condition will be used. We stop once we reach
153
+ // / an edge to StopAt.
153
154
static void recordConditions (CallSite CS, BasicBlock *Pred,
154
- ConditionsTy &Conditions) {
155
- recordCondition (CS, Pred, CS.getInstruction ()->getParent (), Conditions);
155
+ ConditionsTy &Conditions, BasicBlock *StopAt) {
156
156
BasicBlock *From = Pred;
157
157
BasicBlock *To = Pred;
158
158
SmallPtrSet<BasicBlock *, 4 > Visited;
159
- while (!Visited.count (From->getSinglePredecessor ()) &&
159
+ while (To != StopAt && !Visited.count (From->getSinglePredecessor ()) &&
160
160
(From = From->getSinglePredecessor ())) {
161
161
recordCondition (CS, From, To, Conditions);
162
162
Visited.insert (From);
@@ -302,7 +302,7 @@ static void copyMustTailReturn(BasicBlock *SplitBB, Instruction *CI,
302
302
static void splitCallSite (
303
303
CallSite CS,
304
304
const SmallVectorImpl<std::pair<BasicBlock *, ConditionsTy>> &Preds,
305
- DominatorTree * DT) {
305
+ DominatorTree & DT) {
306
306
Instruction *Instr = CS.getInstruction ();
307
307
BasicBlock *TailBB = Instr->getParent ();
308
308
bool IsMustTailCall = CS.isMustTailCall ();
@@ -327,7 +327,7 @@ static void splitCallSite(
327
327
BasicBlock *PredBB = Preds[i].first ;
328
328
BasicBlock *SplitBlock = DuplicateInstructionsInSplitBetween (
329
329
TailBB, PredBB, &*std::next (Instr->getIterator ()), ValueToValueMaps[i],
330
- DT);
330
+ & DT);
331
331
assert (SplitBlock && " Unexpected new basic block split." );
332
332
333
333
Instruction *NewCI =
@@ -438,7 +438,7 @@ static bool isPredicatedOnPHI(CallSite CS) {
438
438
return false ;
439
439
}
440
440
441
- static bool tryToSplitOnPHIPredicatedArgument (CallSite CS, DominatorTree * DT) {
441
+ static bool tryToSplitOnPHIPredicatedArgument (CallSite CS, DominatorTree & DT) {
442
442
if (!isPredicatedOnPHI (CS))
443
443
return false ;
444
444
@@ -449,15 +449,25 @@ static bool tryToSplitOnPHIPredicatedArgument(CallSite CS, DominatorTree *DT) {
449
449
return true ;
450
450
}
451
451
452
- static bool tryToSplitOnPredicatedArgument (CallSite CS, DominatorTree * DT) {
452
+ static bool tryToSplitOnPredicatedArgument (CallSite CS, DominatorTree & DT) {
453
453
auto Preds = getTwoPredecessors (CS.getInstruction ()->getParent ());
454
454
if (Preds[0 ] == Preds[1 ])
455
455
return false ;
456
456
457
+ // We can stop recording conditions once we reached the immediate dominator
458
+ // for the block containing the call site. Conditions in predecessors of the
459
+ // that node will be the same for all paths to the call site and splitting
460
+ // is not beneficial.
461
+ auto *CSDTNode = DT.getNode (CS.getInstruction ()->getParent ());
462
+ BasicBlock *StopAt = CSDTNode ? CSDTNode->getIDom ()->getBlock () : nullptr ;
463
+
457
464
SmallVector<std::pair<BasicBlock *, ConditionsTy>, 2 > PredsCS;
458
465
for (auto *Pred : make_range (Preds.rbegin (), Preds.rend ())) {
459
466
ConditionsTy Conditions;
460
- recordConditions (CS, Pred, Conditions);
467
+ // Record condition on edge BB(CS) <- Pred
468
+ recordCondition (CS, Pred, CS.getInstruction ()->getParent (), Conditions);
469
+ // Record conditions followng Pred's single predecessors.
470
+ recordConditions (CS, Pred, Conditions, StopAt);
461
471
PredsCS.push_back ({Pred, Conditions});
462
472
}
463
473
@@ -466,20 +476,32 @@ static bool tryToSplitOnPredicatedArgument(CallSite CS, DominatorTree *DT) {
466
476
}))
467
477
return false ;
468
478
479
+ // Record common conditions starting from StopAt. Those conditions hold for
480
+ // all paths to CS. Adding them gives the inliner a better chance at inlining
481
+ // CS.
482
+ ConditionsTy CommonConditions;
483
+ if (StopAt)
484
+ recordConditions (CS, StopAt, CommonConditions, nullptr );
485
+ if (!CommonConditions.empty ())
486
+ for (auto &Pred : PredsCS) {
487
+ Pred.second .insert (Pred.second .end (), CommonConditions.begin (),
488
+ CommonConditions.end ());
489
+ }
490
+
469
491
splitCallSite (CS, PredsCS, DT);
470
492
return true ;
471
493
}
472
494
473
495
static bool tryToSplitCallSite (CallSite CS, TargetTransformInfo &TTI,
474
- DominatorTree * DT) {
496
+ DominatorTree & DT) {
475
497
if (!CS.arg_size () || !canSplitCallSite (CS, TTI))
476
498
return false ;
477
499
return tryToSplitOnPredicatedArgument (CS, DT) ||
478
500
tryToSplitOnPHIPredicatedArgument (CS, DT);
479
501
}
480
502
481
503
static bool doCallSiteSplitting (Function &F, TargetLibraryInfo &TLI,
482
- TargetTransformInfo &TTI, DominatorTree * DT) {
504
+ TargetTransformInfo &TTI, DominatorTree & DT) {
483
505
bool Changed = false ;
484
506
for (Function::iterator BI = F.begin (), BE = F.end (); BI != BE;) {
485
507
BasicBlock &BB = *BI++;
@@ -524,6 +546,7 @@ struct CallSiteSplittingLegacyPass : public FunctionPass {
524
546
void getAnalysisUsage (AnalysisUsage &AU) const override {
525
547
AU.addRequired <TargetLibraryInfoWrapperPass>();
526
548
AU.addRequired <TargetTransformInfoWrapperPass>();
549
+ AU.addRequired <DominatorTreeWrapperPass>();
527
550
AU.addPreserved <DominatorTreeWrapperPass>();
528
551
FunctionPass::getAnalysisUsage (AU);
529
552
}
@@ -534,9 +557,8 @@ struct CallSiteSplittingLegacyPass : public FunctionPass {
534
557
535
558
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI ();
536
559
auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI (F);
537
- auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
538
- return doCallSiteSplitting (F, TLI, TTI,
539
- DTWP ? &DTWP->getDomTree () : nullptr );
560
+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
561
+ return doCallSiteSplitting (F, TLI, TTI, DT);
540
562
}
541
563
};
542
564
} // namespace
@@ -546,6 +568,7 @@ INITIALIZE_PASS_BEGIN(CallSiteSplittingLegacyPass, "callsite-splitting",
546
568
" Call-site splitting" , false , false )
547
569
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
548
570
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
571
+ INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
549
572
INITIALIZE_PASS_END(CallSiteSplittingLegacyPass, " callsite-splitting" ,
550
573
" Call-site splitting" , false , false )
551
574
FunctionPass *llvm::createCallSiteSplittingPass() {
@@ -556,7 +579,7 @@ PreservedAnalyses CallSiteSplittingPass::run(Function &F,
556
579
FunctionAnalysisManager &AM) {
557
580
auto &TLI = AM.getResult <TargetLibraryAnalysis>(F);
558
581
auto &TTI = AM.getResult <TargetIRAnalysis>(F);
559
- auto * DT = AM.getCachedResult <DominatorTreeAnalysis>(F);
582
+ auto & DT = AM.getResult <DominatorTreeAnalysis>(F);
560
583
561
584
if (!doCallSiteSplitting (F, TLI, TTI, DT))
562
585
return PreservedAnalyses::all ();
0 commit comments