Skip to content

Commit efca1ca

Browse files
authored
Merge pull request #15495 from gottesmm/pr-f8d1bdd4feca6f9af1dd5746b016d839eb34bce1
[globalopt] Cleanup placeInitializers.
2 parents 977a0e0 + 5b630f2 commit efca1ca

File tree

1 file changed

+86
-61
lines changed

1 file changed

+86
-61
lines changed

lib/SILOptimizer/IPO/GlobalOpt.cpp

Lines changed: 86 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ class SILGlobalOpt {
117117

118118
/// Returns true if we think that \p CurBB is inside a loop.
119119
bool isInLoop(SILBasicBlock *CurBB);
120+
121+
/// Given that we are trying to place initializers in new locations, see if
122+
/// we can hoist the passed in apply \p AI out of any loops that it is
123+
/// currently within.
124+
ApplyInst *getHoistedApplyForInitializer(
125+
ApplyInst *AI, DominanceInfo *DT, SILFunction *InitF,
126+
SILFunction *ParentF,
127+
llvm::DenseMap<SILFunction *, ApplyInst *> &ParentFuncs);
128+
120129
void placeInitializers(SILFunction *InitF, ArrayRef<ApplyInst *> Calls);
121130

122131
/// Update UnhandledOnceCallee and InitializerCount by going through all
@@ -438,6 +447,48 @@ static bool isAvailabilityCheckOnDomPath(SILBasicBlock *From, SILBasicBlock *To,
438447
}
439448
}
440449

450+
ApplyInst *SILGlobalOpt::getHoistedApplyForInitializer(
451+
ApplyInst *AI, DominanceInfo *DT, SILFunction *InitF, SILFunction *ParentF,
452+
llvm::DenseMap<SILFunction *, ApplyInst *> &ParentFuncs) {
453+
auto PFI = ParentFuncs.find(ParentF);
454+
if (PFI == ParentFuncs.end()) {
455+
ParentFuncs[ParentF] = AI;
456+
457+
// It's the first time we found a call to InitF in this function, so we
458+
// try to hoist it out of any loop.
459+
return AI;
460+
}
461+
462+
// Found a replacement for this init call. Ensure the replacement dominates
463+
// the original call site.
464+
ApplyInst *CommonAI = PFI->second;
465+
assert(
466+
cast<FunctionRefInst>(CommonAI->getCallee())->getReferencedFunction() ==
467+
InitF &&
468+
"ill-formed global init call");
469+
SILBasicBlock *DomBB =
470+
DT->findNearestCommonDominator(AI->getParent(), CommonAI->getParent());
471+
472+
// We must not move initializers around availability-checks.
473+
if (isAvailabilityCheckOnDomPath(DomBB, CommonAI->getParent(), DT))
474+
return nullptr;
475+
476+
ApplyInst *Result = nullptr;
477+
if (DomBB != CommonAI->getParent()) {
478+
CommonAI->moveBefore(&*DomBB->begin());
479+
placeFuncRef(CommonAI, DT);
480+
481+
// Try to hoist the existing AI again if we move it to another block,
482+
// e.g. from a loop exit into the loop.
483+
Result = CommonAI;
484+
}
485+
486+
AI->replaceAllUsesWith(CommonAI);
487+
AI->eraseFromParent();
488+
HasChanged = true;
489+
return Result;
490+
}
491+
441492
/// Optimize placement of initializer calls given a list of calls to the
442493
/// same initializer. All original initialization points must be dominated by
443494
/// the final initialization calls.
@@ -455,72 +506,46 @@ void SILGlobalOpt::placeInitializers(SILFunction *InitF,
455506
assert(AI->getNumArguments() == 0 && "ill-formed global init call");
456507
assert(cast<FunctionRefInst>(AI->getCallee())->getReferencedFunction()
457508
== InitF && "wrong init call");
458-
459509
SILFunction *ParentF = AI->getFunction();
460510
DominanceInfo *DT = DA->get(ParentF);
461-
auto PFI = ParentFuncs.find(ParentF);
462-
ApplyInst *HoistAI = nullptr;
463-
if (PFI != ParentFuncs.end()) {
464-
// Found a replacement for this init call.
465-
// Ensure the replacement dominates the original call site.
466-
ApplyInst *CommonAI = PFI->second;
467-
assert(cast<FunctionRefInst>(CommonAI->getCallee())
468-
->getReferencedFunction() == InitF &&
469-
"ill-formed global init call");
470-
SILBasicBlock *DomBB =
471-
DT->findNearestCommonDominator(AI->getParent(), CommonAI->getParent());
472-
473-
// We must not move initializers around availability-checks.
474-
if (!isAvailabilityCheckOnDomPath(DomBB, CommonAI->getParent(), DT)) {
475-
if (DomBB != CommonAI->getParent()) {
476-
CommonAI->moveBefore(&*DomBB->begin());
477-
placeFuncRef(CommonAI, DT);
478-
479-
// Try to hoist the existing AI again if we move it to another block,
480-
// e.g. from a loop exit into the loop.
481-
HoistAI = CommonAI;
482-
}
483-
AI->replaceAllUsesWith(CommonAI);
484-
AI->eraseFromParent();
485-
HasChanged = true;
486-
}
487-
} else {
488-
ParentFuncs[ParentF] = AI;
489-
490-
// It's the first time we found a call to InitF in this function, so we
491-
// try to hoist it out of any loop.
492-
HoistAI = AI;
511+
ApplyInst *HoistAI =
512+
getHoistedApplyForInitializer(AI, DT, InitF, ParentF, ParentFuncs);
513+
514+
// If we were unable to find anything, just go onto the next apply.
515+
if (!HoistAI) {
516+
continue;
493517
}
494-
if (HoistAI) {
495-
// Move this call to the outermost loop preheader.
496-
SILBasicBlock *BB = HoistAI->getParent();
497-
typedef llvm::DomTreeNodeBase<SILBasicBlock> DomTreeNode;
498-
DomTreeNode *Node = DT->getNode(BB);
499-
while (Node) {
500-
SILBasicBlock *DomParentBB = Node->getBlock();
501-
if (isAvailabilityCheck(DomParentBB)) {
502-
DEBUG(llvm::dbgs() << " don't hoist above availability check at bb"
503-
<< DomParentBB->getDebugID() << "\n");
504-
break;
505-
}
506-
BB = DomParentBB;
507-
if (!isInLoop(BB))
508-
break;
509-
Node = Node->getIDom();
510-
}
511-
if (BB == HoistAI->getParent()) {
512-
// BB is either unreachable or not in a loop.
513-
DEBUG(llvm::dbgs() << " skipping (not in a loop): " << *HoistAI
514-
<< " in " << HoistAI->getFunction()->getName() << "\n");
515-
}
516-
else {
517-
DEBUG(llvm::dbgs() << " hoisting: " << *HoistAI
518-
<< " in " << HoistAI->getFunction()->getName() << "\n");
519-
HoistAI->moveBefore(&*BB->begin());
520-
placeFuncRef(HoistAI, DT);
521-
HasChanged = true;
518+
519+
// Otherwise, move this call to the outermost loop preheader.
520+
SILBasicBlock *BB = HoistAI->getParent();
521+
typedef llvm::DomTreeNodeBase<SILBasicBlock> DomTreeNode;
522+
DomTreeNode *Node = DT->getNode(BB);
523+
while (Node) {
524+
SILBasicBlock *DomParentBB = Node->getBlock();
525+
if (isAvailabilityCheck(DomParentBB)) {
526+
DEBUG(llvm::dbgs() << " don't hoist above availability check at bb"
527+
<< DomParentBB->getDebugID() << "\n");
528+
break;
522529
}
530+
BB = DomParentBB;
531+
if (!isInLoop(BB))
532+
break;
533+
Node = Node->getIDom();
523534
}
535+
536+
if (BB == HoistAI->getParent()) {
537+
// BB is either unreachable or not in a loop.
538+
DEBUG(llvm::dbgs() << " skipping (not in a loop): " << *HoistAI
539+
<< " in " << HoistAI->getFunction()->getName()
540+
<< "\n");
541+
continue;
542+
}
543+
544+
DEBUG(llvm::dbgs() << " hoisting: " << *HoistAI << " in "
545+
<< HoistAI->getFunction()->getName() << "\n");
546+
HoistAI->moveBefore(&*BB->begin());
547+
placeFuncRef(HoistAI, DT);
548+
HasChanged = true;
524549
}
525550
}
526551

0 commit comments

Comments
 (0)