[SimplifyCFG] Common code sinking: relax restriction on non-uncond predecessors
While we have a known profitability issue for sinking in presence of non-unconditional predecessors, there isn't any known issues for having multiple such non-unconditional predecessors, so said restriction appears to be artificial. Lift it.
This commit is contained in:
@@ -1988,15 +1988,13 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
|
||||
// [ end ]
|
||||
//
|
||||
SmallVector<BasicBlock*,4> UnconditionalPreds;
|
||||
Instruction *Cond = nullptr;
|
||||
for (auto *B : predecessors(BB)) {
|
||||
auto *T = B->getTerminator();
|
||||
if (isa<BranchInst>(T) && cast<BranchInst>(T)->isUnconditional())
|
||||
UnconditionalPreds.push_back(B);
|
||||
else if ((isa<BranchInst>(T) || isa<SwitchInst>(T)) && !Cond)
|
||||
Cond = T;
|
||||
bool AllPredsAreUnconditional = false;
|
||||
for (auto *PredBB : predecessors(BB)) {
|
||||
auto *PredBr = dyn_cast<BranchInst>(PredBB->getTerminator());
|
||||
if (PredBr && PredBr->isUnconditional())
|
||||
UnconditionalPreds.push_back(PredBB);
|
||||
else
|
||||
return false;
|
||||
AllPredsAreUnconditional = true;
|
||||
}
|
||||
if (UnconditionalPreds.size() < 2)
|
||||
return false;
|
||||
@@ -2063,7 +2061,7 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
if (Cond) {
|
||||
if (AllPredsAreUnconditional) {
|
||||
// It is always legal to sink common instructions from unconditional
|
||||
// predecessors. However, if not all predecessors are unconditional,
|
||||
// this transformation might be pessimizing. So as a rule of thumb,
|
||||
|
||||
@@ -1538,14 +1538,11 @@ define void @multiple_cond_preds(i1 %c0, i1 %c1, i1 %c2) {
|
||||
; CHECK-NEXT: br i1 [[C0:%.*]], label [[DISPATCH1:%.*]], label [[DISPATCH2:%.*]]
|
||||
; CHECK: dispatch1:
|
||||
; CHECK-NEXT: call void @direct_callee2()
|
||||
; CHECK-NEXT: br i1 [[C1:%.*]], label [[UNCOND_PRED0:%.*]], label [[END:%.*]]
|
||||
; CHECK-NEXT: br i1 [[C1:%.*]], label [[END_SINK_SPLIT:%.*]], label [[END:%.*]]
|
||||
; CHECK: dispatch2:
|
||||
; CHECK-NEXT: call void @direct_callee3()
|
||||
; CHECK-NEXT: br i1 [[C2:%.*]], label [[UNCOND_PRED1:%.*]], label [[END]]
|
||||
; CHECK: uncond_pred0:
|
||||
; CHECK-NEXT: call void @direct_callee()
|
||||
; CHECK-NEXT: br label [[END]]
|
||||
; CHECK: uncond_pred1:
|
||||
; CHECK-NEXT: br i1 [[C2:%.*]], label [[END_SINK_SPLIT]], label [[END]]
|
||||
; CHECK: end.sink.split:
|
||||
; CHECK-NEXT: call void @direct_callee()
|
||||
; CHECK-NEXT: br label [[END]]
|
||||
; CHECK: end:
|
||||
|
||||
Reference in New Issue
Block a user