mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 06:10:12 +00:00
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:
parent
53e9a5ddc0
commit
68685a7f6a
@ -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(
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user