Revert "[GuardWidening] Improve analysis of potential widening into hotter block"

This reverts commit 8d2885c2ef.

I accidentally introduced an infinite loop in this patch, will return when this is fixed.
This commit is contained in:
Max Kazantsev 2023-03-21 22:18:40 +07:00
parent 53e9a5ddc0
commit 68685a7f6a
2 changed files with 36 additions and 56 deletions

View File

@ -460,55 +460,27 @@ GuardWideningImpl::computeWideningScore(Instruction *DominatedInstr,
if (HoistingOutOfLoop)
return WS_Positive;
// For a given basic block \p BB, return its successor which is guaranteed or
// highly likely will be taken as its successor.
auto GetLikelySuccessor = [](const BasicBlock * BB)->const BasicBlock * {
if (auto *UniqueSucc = BB->getUniqueSuccessor())
return UniqueSucc;
auto *Term = BB->getTerminator();
Value *Cond = nullptr;
const BasicBlock *IfTrue = nullptr, *IfFalse = nullptr;
using namespace PatternMatch;
if (!match(Term, m_Br(m_Value(Cond), m_BasicBlock(IfTrue),
m_BasicBlock(IfFalse))))
return nullptr;
// For constant conditions, only one dynamical successor is possible
if (auto *ConstCond = dyn_cast<ConstantInt>(Cond))
return ConstCond->isAllOnesValue() ? IfTrue : IfFalse;
// If one of successors ends with deopt, another one is likely.
if (IfFalse->getPostdominatingDeoptimizeCall())
return IfTrue;
if (IfTrue->getPostdominatingDeoptimizeCall())
return IfFalse;
// TODO: Use branch frequency metatada to allow hoisting through non-deopt
// branches?
return nullptr;
};
// Returns true if we might be hoisting above explicit control flow into a
// considerably hotter block. Note that this completely ignores implicit
// control flow (guards, calls which throw, etc...). That choice appears
// arbitrary (we assume that implicit control flow exits are all rare).
auto MaybeHoistingToHotterBlock = [&]() {
const auto *DominatingBlock = DominatingGuard->getParent();
const auto *DominatedBlock = DominatedInstr->getParent();
// Descent as low as we can, always taking the likely successor.
while (DominatedBlock != DominatingBlock)
if (auto *LikelySucc = GetLikelySuccessor(DominatingBlock))
DominatingBlock = LikelySucc;
else
break;
// Returns true if we might be hoisting above explicit control flow. Note
// that this completely ignores implicit control flow (guards, calls which
// throw, etc...). That choice appears arbitrary.
auto MaybeHoistingOutOfIf = [&]() {
auto *DominatingBlock = DominatingGuard->getParent();
auto *DominatedBlock = DominatedInstr->getParent();
if (isGuardAsWidenableBranch(DominatingGuard))
DominatingBlock = cast<BranchInst>(DominatingGuard)->getSuccessor(0);
// Same Block?
if (DominatedBlock == DominatingBlock)
return false;
// Obvious successor (common loop header/preheader case)
if (DominatedBlock == DominatingBlock->getUniqueSuccessor())
return false;
// TODO: diamond, triangle cases
if (!PDT) return true;
return !PDT->dominates(DominatedBlock, DominatingBlock);
};
return MaybeHoistingToHotterBlock() ? WS_IllegalOrNegative : WS_Neutral;
return MaybeHoistingOutOfIf() ? WS_IllegalOrNegative : WS_Neutral;
}
bool GuardWideningImpl::canBeHoistedTo(

View File

@ -42,26 +42,30 @@ define void @test_01(i32 %a, i32 %b, i32 %c, i32 %d) {
; BRANCH_FORM-NEXT: entry:
; BRANCH_FORM-NEXT: br label [[LOOP:%.*]]
; BRANCH_FORM: loop:
; BRANCH_FORM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ]
; BRANCH_FORM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[GUARDED5:%.*]] ]
; BRANCH_FORM-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; BRANCH_FORM-NEXT: [[C1:%.*]] = icmp ult i32 [[IV]], [[A]]
; BRANCH_FORM-NEXT: [[C2:%.*]] = icmp ult i32 [[IV]], [[B]]
; BRANCH_FORM-NEXT: [[WIDE_CHK:%.*]] = and i1 [[C1]], [[C2]]
; BRANCH_FORM-NEXT: [[C3:%.*]] = icmp ult i32 [[IV]], [[C]]
; BRANCH_FORM-NEXT: [[WIDE_CHK13:%.*]] = and i1 [[WIDE_CHK]], [[C3]]
; BRANCH_FORM-NEXT: [[C4:%.*]] = icmp ult i32 [[IV]], [[D]]
; BRANCH_FORM-NEXT: [[WIDE_CHK14:%.*]] = and i1 [[WIDE_CHK13]], [[C4]]
; BRANCH_FORM-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
; BRANCH_FORM-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK14]], [[WIDENABLE_COND]]
; BRANCH_FORM-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
; BRANCH_FORM-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
; BRANCH_FORM-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
; BRANCH_FORM: deopt:
; BRANCH_FORM-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
; BRANCH_FORM-NEXT: ret void
; BRANCH_FORM: guarded:
; BRANCH_FORM-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
; BRANCH_FORM-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[C2]], [[WIDENABLE_COND3]]
; BRANCH_FORM-NEXT: [[C3:%.*]] = icmp ult i32 [[IV]], [[C]]
; BRANCH_FORM-NEXT: [[C4:%.*]] = icmp ult i32 [[IV]], [[D]]
; BRANCH_FORM-NEXT: [[WIDE_CHK13:%.*]] = and i1 [[C3]], [[C4]]
; BRANCH_FORM-NEXT: [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition()
; BRANCH_FORM-NEXT: [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[C3]], [[WIDENABLE_COND7]]
; BRANCH_FORM-NEXT: [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[WIDE_CHK13]], [[WIDENABLE_COND7]]
; BRANCH_FORM-NEXT: br i1 [[EXIPLICIT_GUARD_COND8]], label [[GUARDED5]], label [[DEOPT6:%.*]], !prof [[PROF0]]
; BRANCH_FORM: deopt6:
; BRANCH_FORM-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
; BRANCH_FORM-NEXT: ret void
; BRANCH_FORM: guarded5:
; BRANCH_FORM-NEXT: [[WIDENABLE_COND11:%.*]] = call i1 @llvm.experimental.widenable.condition()
; BRANCH_FORM-NEXT: [[EXIPLICIT_GUARD_COND12:%.*]] = and i1 [[C4]], [[WIDENABLE_COND11]]
; BRANCH_FORM-NEXT: [[LOOP_COND:%.*]] = call i1 @cond()
@ -74,26 +78,30 @@ define void @test_01(i32 %a, i32 %b, i32 %c, i32 %d) {
; BRANCH_FORM_LICM-NEXT: entry:
; BRANCH_FORM_LICM-NEXT: br label [[LOOP:%.*]]
; BRANCH_FORM_LICM: loop:
; BRANCH_FORM_LICM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ]
; BRANCH_FORM_LICM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[GUARDED5:%.*]] ]
; BRANCH_FORM_LICM-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; BRANCH_FORM_LICM-NEXT: [[C1:%.*]] = icmp ult i32 [[IV]], [[A]]
; BRANCH_FORM_LICM-NEXT: [[C2:%.*]] = icmp ult i32 [[IV]], [[B]]
; BRANCH_FORM_LICM-NEXT: [[WIDE_CHK:%.*]] = and i1 [[C1]], [[C2]]
; BRANCH_FORM_LICM-NEXT: [[C3:%.*]] = icmp ult i32 [[IV]], [[C]]
; BRANCH_FORM_LICM-NEXT: [[WIDE_CHK13:%.*]] = and i1 [[WIDE_CHK]], [[C3]]
; BRANCH_FORM_LICM-NEXT: [[C4:%.*]] = icmp ult i32 [[IV]], [[D]]
; BRANCH_FORM_LICM-NEXT: [[WIDE_CHK14:%.*]] = and i1 [[WIDE_CHK13]], [[C4]]
; BRANCH_FORM_LICM-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
; BRANCH_FORM_LICM-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK14]], [[WIDENABLE_COND]]
; BRANCH_FORM_LICM-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
; BRANCH_FORM_LICM-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
; BRANCH_FORM_LICM-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
; BRANCH_FORM_LICM: deopt:
; BRANCH_FORM_LICM-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
; BRANCH_FORM_LICM-NEXT: ret void
; BRANCH_FORM_LICM: guarded:
; BRANCH_FORM_LICM-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
; BRANCH_FORM_LICM-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[C2]], [[WIDENABLE_COND3]]
; BRANCH_FORM_LICM-NEXT: [[C3:%.*]] = icmp ult i32 [[IV]], [[C]]
; BRANCH_FORM_LICM-NEXT: [[C4:%.*]] = icmp ult i32 [[IV]], [[D]]
; BRANCH_FORM_LICM-NEXT: [[WIDE_CHK13:%.*]] = and i1 [[C3]], [[C4]]
; BRANCH_FORM_LICM-NEXT: [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition()
; BRANCH_FORM_LICM-NEXT: [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[C3]], [[WIDENABLE_COND7]]
; BRANCH_FORM_LICM-NEXT: [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[WIDE_CHK13]], [[WIDENABLE_COND7]]
; BRANCH_FORM_LICM-NEXT: br i1 [[EXIPLICIT_GUARD_COND8]], label [[GUARDED5]], label [[DEOPT6:%.*]], !prof [[PROF0]]
; BRANCH_FORM_LICM: deopt6:
; BRANCH_FORM_LICM-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
; BRANCH_FORM_LICM-NEXT: ret void
; BRANCH_FORM_LICM: guarded5:
; BRANCH_FORM_LICM-NEXT: [[WIDENABLE_COND11:%.*]] = call i1 @llvm.experimental.widenable.condition()
; BRANCH_FORM_LICM-NEXT: [[EXIPLICIT_GUARD_COND12:%.*]] = and i1 [[C4]], [[WIDENABLE_COND11]]
; BRANCH_FORM_LICM-NEXT: [[LOOP_COND:%.*]] = call i1 @cond()