mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-26 13:10:34 +00:00
Teach ScalarEvolution how to analyze loops with multiple exit
blocks, and also exit blocks with multiple conditions (combined with (bitwise) ands and ors). It's often infeasible to compute an exact trip count in such cases, but a useful upper bound can often be found. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73866 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
743ab498d8
commit
a334aa7a10
@ -348,6 +348,31 @@ namespace llvm {
|
||||
/// loop will iterate.
|
||||
BackedgeTakenInfo ComputeBackedgeTakenCount(const Loop *L);
|
||||
|
||||
/// ComputeBackedgeTakenCountFromExit - Compute the number of times the
|
||||
/// backedge of the specified loop will execute if it exits via the
|
||||
/// specified block.
|
||||
BackedgeTakenInfo ComputeBackedgeTakenCountFromExit(const Loop *L,
|
||||
BasicBlock *ExitingBlock);
|
||||
|
||||
/// ComputeBackedgeTakenCountFromExitCond - Compute the number of times the
|
||||
/// backedge of the specified loop will execute if its exit condition
|
||||
/// were a conditional branch of ExitCond, TBB, and FBB.
|
||||
BackedgeTakenInfo
|
||||
ComputeBackedgeTakenCountFromExitCond(const Loop *L,
|
||||
Value *ExitCond,
|
||||
BasicBlock *TBB,
|
||||
BasicBlock *FBB);
|
||||
|
||||
/// ComputeBackedgeTakenCountFromExitCondICmp - Compute the number of
|
||||
/// times the backedge of the specified loop will execute if its exit
|
||||
/// condition were a conditional branch of the ICmpInst ExitCond, TBB,
|
||||
/// and FBB.
|
||||
BackedgeTakenInfo
|
||||
ComputeBackedgeTakenCountFromExitCondICmp(const Loop *L,
|
||||
ICmpInst *ExitCond,
|
||||
BasicBlock *TBB,
|
||||
BasicBlock *FBB);
|
||||
|
||||
/// ComputeLoadConstantCompareBackedgeTakenCount - Given an exit condition
|
||||
/// of 'icmp op load X, cst', try to see if we can compute the trip count.
|
||||
SCEVHandle
|
||||
@ -520,6 +545,12 @@ namespace llvm {
|
||||
/// specified signed integer value and return a SCEV for the constant.
|
||||
SCEVHandle getIntegerSCEV(int Val, const Type *Ty);
|
||||
|
||||
/// getUMaxFromMismatchedTypes - Promote the operands to the wider of
|
||||
/// the types using zero-extension, and then perform a umax operation
|
||||
/// with them.
|
||||
SCEVHandle getUMaxFromMismatchedTypes(const SCEVHandle &LHS,
|
||||
const SCEVHandle &RHS);
|
||||
|
||||
/// hasSCEV - Return true if the SCEV for this value has already been
|
||||
/// computed.
|
||||
bool hasSCEV(Value *V) const;
|
||||
|
@ -2128,6 +2128,22 @@ ScalarEvolution::getTruncateOrNoop(const SCEVHandle &V, const Type *Ty) {
|
||||
return getTruncateExpr(V, Ty);
|
||||
}
|
||||
|
||||
/// getUMaxFromMismatchedTypes - Promote the operands to the wider of
|
||||
/// the types using zero-extension, and then perform a umax operation
|
||||
/// with them.
|
||||
SCEVHandle ScalarEvolution::getUMaxFromMismatchedTypes(const SCEVHandle &LHS,
|
||||
const SCEVHandle &RHS) {
|
||||
SCEVHandle PromotedLHS = LHS;
|
||||
SCEVHandle PromotedRHS = RHS;
|
||||
|
||||
if (getTypeSizeInBits(LHS->getType()) > getTypeSizeInBits(RHS->getType()))
|
||||
PromotedRHS = getZeroExtendExpr(RHS, LHS->getType());
|
||||
else
|
||||
PromotedLHS = getNoopOrZeroExtend(LHS, RHS->getType());
|
||||
|
||||
return getUMaxExpr(PromotedLHS, PromotedRHS);
|
||||
}
|
||||
|
||||
/// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value for
|
||||
/// the specified instruction and replaces any references to the symbolic value
|
||||
/// SymName with the specified value. This is used during PHI resolution.
|
||||
@ -2723,9 +2739,13 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
|
||||
|
||||
// Update the value in the map.
|
||||
Pair.first->second = ItCount;
|
||||
} else if (isa<PHINode>(L->getHeader()->begin())) {
|
||||
// Only count loops that have phi nodes as not being computable.
|
||||
++NumTripCountsNotComputed;
|
||||
} else {
|
||||
if (ItCount.Max != CouldNotCompute)
|
||||
// Update the value in the map.
|
||||
Pair.first->second = ItCount;
|
||||
if (isa<PHINode>(L->getHeader()->begin()))
|
||||
// Only count loops that have phi nodes as not being computable.
|
||||
++NumTripCountsNotComputed;
|
||||
}
|
||||
|
||||
// Now that we know more about the trip count for this loop, forget any
|
||||
@ -2781,19 +2801,58 @@ void ScalarEvolution::forgetLoopPHIs(const Loop *L) {
|
||||
/// of the specified loop will execute.
|
||||
ScalarEvolution::BackedgeTakenInfo
|
||||
ScalarEvolution::ComputeBackedgeTakenCount(const Loop *L) {
|
||||
// If the loop has a non-one exit block count, we can't analyze it.
|
||||
BasicBlock *ExitBlock = L->getExitBlock();
|
||||
if (!ExitBlock)
|
||||
return CouldNotCompute;
|
||||
SmallVector<BasicBlock*, 8> ExitingBlocks;
|
||||
L->getExitingBlocks(ExitingBlocks);
|
||||
|
||||
// Okay, there is one exit block. Try to find the condition that causes the
|
||||
// loop to be exited.
|
||||
BasicBlock *ExitingBlock = L->getExitingBlock();
|
||||
if (!ExitingBlock)
|
||||
return CouldNotCompute; // More than one block exiting!
|
||||
// Examine all exits and pick the most conservative values.
|
||||
SCEVHandle BECount = CouldNotCompute;
|
||||
SCEVHandle MaxBECount = CouldNotCompute;
|
||||
bool CouldNotComputeBECount = false;
|
||||
bool CouldNotComputeMaxBECount = false;
|
||||
for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) {
|
||||
BackedgeTakenInfo NewBTI =
|
||||
ComputeBackedgeTakenCountFromExit(L, ExitingBlocks[i]);
|
||||
|
||||
// Okay, we've computed the exiting block. See what condition causes us to
|
||||
// exit.
|
||||
if (NewBTI.Exact == CouldNotCompute) {
|
||||
// We couldn't compute an exact value for this exit, so
|
||||
// we don't be able to compute an exact value for the loop.
|
||||
CouldNotComputeBECount = true;
|
||||
BECount = CouldNotCompute;
|
||||
} else if (!CouldNotComputeBECount) {
|
||||
if (BECount == CouldNotCompute)
|
||||
BECount = NewBTI.Exact;
|
||||
else {
|
||||
// TODO: More analysis could be done here. For example, a
|
||||
// loop with a short-circuiting && operator has an exact count
|
||||
// of the min of both sides.
|
||||
CouldNotComputeBECount = true;
|
||||
BECount = CouldNotCompute;
|
||||
}
|
||||
}
|
||||
if (NewBTI.Max == CouldNotCompute) {
|
||||
// We couldn't compute an maximum value for this exit, so
|
||||
// we don't be able to compute an maximum value for the loop.
|
||||
CouldNotComputeMaxBECount = true;
|
||||
MaxBECount = CouldNotCompute;
|
||||
} else if (!CouldNotComputeMaxBECount) {
|
||||
if (MaxBECount == CouldNotCompute)
|
||||
MaxBECount = NewBTI.Max;
|
||||
else
|
||||
MaxBECount = getUMaxFromMismatchedTypes(MaxBECount, NewBTI.Max);
|
||||
}
|
||||
}
|
||||
|
||||
return BackedgeTakenInfo(BECount, MaxBECount);
|
||||
}
|
||||
|
||||
/// ComputeBackedgeTakenCountFromExit - Compute the number of times the backedge
|
||||
/// of the specified loop will execute if it exits via the specified block.
|
||||
ScalarEvolution::BackedgeTakenInfo
|
||||
ScalarEvolution::ComputeBackedgeTakenCountFromExit(const Loop *L,
|
||||
BasicBlock *ExitingBlock) {
|
||||
|
||||
// Okay, we've chosen an exiting block. See what condition causes us to
|
||||
// exit at this block.
|
||||
//
|
||||
// FIXME: we should be able to handle switch instructions (with a single exit)
|
||||
BranchInst *ExitBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
|
||||
@ -2808,23 +2867,154 @@ ScalarEvolution::ComputeBackedgeTakenCount(const Loop *L) {
|
||||
// Currently we check for this by checking to see if the Exit branch goes to
|
||||
// the loop header. If so, we know it will always execute the same number of
|
||||
// times as the loop. We also handle the case where the exit block *is* the
|
||||
// loop header. This is common for un-rotated loops. More extensive analysis
|
||||
// could be done to handle more cases here.
|
||||
// loop header. This is common for un-rotated loops.
|
||||
//
|
||||
// If both of those tests fail, walk up the unique predecessor chain to the
|
||||
// header, stopping if there is an edge that doesn't exit the loop. If the
|
||||
// header is reached, the execution count of the branch will be equal to the
|
||||
// trip count of the loop.
|
||||
//
|
||||
// More extensive analysis could be done to handle more cases here.
|
||||
//
|
||||
if (ExitBr->getSuccessor(0) != L->getHeader() &&
|
||||
ExitBr->getSuccessor(1) != L->getHeader() &&
|
||||
ExitBr->getParent() != L->getHeader())
|
||||
return CouldNotCompute;
|
||||
|
||||
ICmpInst *ExitCond = dyn_cast<ICmpInst>(ExitBr->getCondition());
|
||||
ExitBr->getParent() != L->getHeader()) {
|
||||
// The simple checks failed, try climbing the unique predecessor chain
|
||||
// up to the header.
|
||||
bool Ok = false;
|
||||
for (BasicBlock *BB = ExitBr->getParent(); BB; ) {
|
||||
BasicBlock *Pred = BB->getUniquePredecessor();
|
||||
if (!Pred)
|
||||
return CouldNotCompute;
|
||||
TerminatorInst *PredTerm = Pred->getTerminator();
|
||||
for (unsigned i = 0, e = PredTerm->getNumSuccessors(); i != e; ++i) {
|
||||
BasicBlock *PredSucc = PredTerm->getSuccessor(i);
|
||||
if (PredSucc == BB)
|
||||
continue;
|
||||
// If the predecessor has a successor that isn't BB and isn't
|
||||
// outside the loop, assume the worst.
|
||||
if (L->contains(PredSucc))
|
||||
return CouldNotCompute;
|
||||
}
|
||||
if (Pred == L->getHeader()) {
|
||||
Ok = true;
|
||||
break;
|
||||
}
|
||||
BB = Pred;
|
||||
}
|
||||
if (!Ok)
|
||||
return CouldNotCompute;
|
||||
}
|
||||
|
||||
// Procede to the next level to examine the exit condition expression.
|
||||
return ComputeBackedgeTakenCountFromExitCond(L, ExitBr->getCondition(),
|
||||
ExitBr->getSuccessor(0),
|
||||
ExitBr->getSuccessor(1));
|
||||
}
|
||||
|
||||
/// ComputeBackedgeTakenCountFromExitCond - Compute the number of times the
|
||||
/// backedge of the specified loop will execute if its exit condition
|
||||
/// were a conditional branch of ExitCond, TBB, and FBB.
|
||||
ScalarEvolution::BackedgeTakenInfo
|
||||
ScalarEvolution::ComputeBackedgeTakenCountFromExitCond(const Loop *L,
|
||||
Value *ExitCond,
|
||||
BasicBlock *TBB,
|
||||
BasicBlock *FBB) {
|
||||
// Check if the controlling expression for this loop is an and or or. In
|
||||
// such cases, an exact backedge-taken count may be infeasible, but a
|
||||
// maximum count may still be feasible.
|
||||
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(ExitCond)) {
|
||||
if (BO->getOpcode() == Instruction::And) {
|
||||
// Recurse on the operands of the and.
|
||||
BackedgeTakenInfo BTI0 =
|
||||
ComputeBackedgeTakenCountFromExitCond(L, BO->getOperand(0), TBB, FBB);
|
||||
BackedgeTakenInfo BTI1 =
|
||||
ComputeBackedgeTakenCountFromExitCond(L, BO->getOperand(1), TBB, FBB);
|
||||
SCEVHandle BECount = CouldNotCompute;
|
||||
SCEVHandle MaxBECount = CouldNotCompute;
|
||||
if (L->contains(TBB)) {
|
||||
// Both conditions must be true for the loop to continue executing.
|
||||
// Choose the less conservative count.
|
||||
// TODO: Take the minimum of the exact counts.
|
||||
if (BTI0.Exact == BTI1.Exact)
|
||||
BECount = BTI0.Exact;
|
||||
// TODO: Take the minimum of the maximum counts.
|
||||
if (BTI0.Max == CouldNotCompute)
|
||||
MaxBECount = BTI1.Max;
|
||||
else if (BTI1.Max == CouldNotCompute)
|
||||
MaxBECount = BTI0.Max;
|
||||
else if (const SCEVConstant *C0 = dyn_cast<SCEVConstant>(BTI0.Max))
|
||||
if (const SCEVConstant *C1 = dyn_cast<SCEVConstant>(BTI1.Max))
|
||||
MaxBECount = getConstant(APIntOps::umin(C0->getValue()->getValue(),
|
||||
C1->getValue()->getValue()));
|
||||
} else {
|
||||
// Both conditions must be true for the loop to exit.
|
||||
assert(L->contains(FBB) && "Loop block has no successor in loop!");
|
||||
if (BTI0.Exact != CouldNotCompute && BTI1.Exact != CouldNotCompute)
|
||||
BECount = getUMaxFromMismatchedTypes(BTI0.Exact, BTI1.Exact);
|
||||
if (BTI0.Max != CouldNotCompute && BTI1.Max != CouldNotCompute)
|
||||
MaxBECount = getUMaxFromMismatchedTypes(BTI0.Max, BTI1.Max);
|
||||
}
|
||||
|
||||
return BackedgeTakenInfo(BECount, MaxBECount);
|
||||
}
|
||||
if (BO->getOpcode() == Instruction::Or) {
|
||||
// Recurse on the operands of the or.
|
||||
BackedgeTakenInfo BTI0 =
|
||||
ComputeBackedgeTakenCountFromExitCond(L, BO->getOperand(0), TBB, FBB);
|
||||
BackedgeTakenInfo BTI1 =
|
||||
ComputeBackedgeTakenCountFromExitCond(L, BO->getOperand(1), TBB, FBB);
|
||||
SCEVHandle BECount = CouldNotCompute;
|
||||
SCEVHandle MaxBECount = CouldNotCompute;
|
||||
if (L->contains(FBB)) {
|
||||
// Both conditions must be false for the loop to continue executing.
|
||||
// Choose the less conservative count.
|
||||
// TODO: Take the minimum of the exact counts.
|
||||
if (BTI0.Exact == BTI1.Exact)
|
||||
BECount = BTI0.Exact;
|
||||
// TODO: Take the minimum of the maximum counts.
|
||||
if (BTI0.Max == CouldNotCompute)
|
||||
MaxBECount = BTI1.Max;
|
||||
else if (BTI1.Max == CouldNotCompute)
|
||||
MaxBECount = BTI0.Max;
|
||||
else if (const SCEVConstant *C0 = dyn_cast<SCEVConstant>(BTI0.Max))
|
||||
if (const SCEVConstant *C1 = dyn_cast<SCEVConstant>(BTI1.Max))
|
||||
MaxBECount = getConstant(APIntOps::umin(C0->getValue()->getValue(),
|
||||
C1->getValue()->getValue()));
|
||||
} else {
|
||||
// Both conditions must be false for the loop to exit.
|
||||
assert(L->contains(TBB) && "Loop block has no successor in loop!");
|
||||
if (BTI0.Exact != CouldNotCompute && BTI1.Exact != CouldNotCompute)
|
||||
BECount = getUMaxFromMismatchedTypes(BTI0.Exact, BTI1.Exact);
|
||||
if (BTI0.Max != CouldNotCompute && BTI1.Max != CouldNotCompute)
|
||||
MaxBECount = getUMaxFromMismatchedTypes(BTI0.Max, BTI1.Max);
|
||||
}
|
||||
|
||||
return BackedgeTakenInfo(BECount, MaxBECount);
|
||||
}
|
||||
}
|
||||
|
||||
// With an icmp, it may be feasible to compute an exact backedge-taken count.
|
||||
// Procede to the next level to examine the icmp.
|
||||
if (ICmpInst *ExitCondICmp = dyn_cast<ICmpInst>(ExitCond))
|
||||
return ComputeBackedgeTakenCountFromExitCondICmp(L, ExitCondICmp, TBB, FBB);
|
||||
|
||||
// If it's not an integer or pointer comparison then compute it the hard way.
|
||||
if (ExitCond == 0)
|
||||
return ComputeBackedgeTakenCountExhaustively(L, ExitBr->getCondition(),
|
||||
ExitBr->getSuccessor(0) == ExitBlock);
|
||||
return ComputeBackedgeTakenCountExhaustively(L, ExitCond, !L->contains(TBB));
|
||||
}
|
||||
|
||||
/// ComputeBackedgeTakenCountFromExitCondICmp - Compute the number of times the
|
||||
/// backedge of the specified loop will execute if its exit condition
|
||||
/// were a conditional branch of the ICmpInst ExitCond, TBB, and FBB.
|
||||
ScalarEvolution::BackedgeTakenInfo
|
||||
ScalarEvolution::ComputeBackedgeTakenCountFromExitCondICmp(const Loop *L,
|
||||
ICmpInst *ExitCond,
|
||||
BasicBlock *TBB,
|
||||
BasicBlock *FBB) {
|
||||
|
||||
// If the condition was exit on true, convert the condition to exit on false
|
||||
ICmpInst::Predicate Cond;
|
||||
if (ExitBr->getSuccessor(1) == ExitBlock)
|
||||
if (!L->contains(FBB))
|
||||
Cond = ExitCond->getPredicate();
|
||||
else
|
||||
Cond = ExitCond->getInversePredicate();
|
||||
@ -2834,7 +3024,12 @@ ScalarEvolution::ComputeBackedgeTakenCount(const Loop *L) {
|
||||
if (Constant *RHS = dyn_cast<Constant>(ExitCond->getOperand(1))) {
|
||||
SCEVHandle ItCnt =
|
||||
ComputeLoadConstantCompareBackedgeTakenCount(LI, RHS, L, Cond);
|
||||
if (!isa<SCEVCouldNotCompute>(ItCnt)) return ItCnt;
|
||||
if (!isa<SCEVCouldNotCompute>(ItCnt)) {
|
||||
unsigned BitWidth = getTypeSizeInBits(ItCnt->getType());
|
||||
return BackedgeTakenInfo(ItCnt,
|
||||
isa<SCEVConstant>(ItCnt) ? ItCnt :
|
||||
getConstant(APInt::getMaxValue(BitWidth)-1));
|
||||
}
|
||||
}
|
||||
|
||||
SCEVHandle LHS = getSCEV(ExitCond->getOperand(0));
|
||||
@ -2912,8 +3107,7 @@ ScalarEvolution::ComputeBackedgeTakenCount(const Loop *L) {
|
||||
break;
|
||||
}
|
||||
return
|
||||
ComputeBackedgeTakenCountExhaustively(L, ExitCond,
|
||||
ExitBr->getSuccessor(0) == ExitBlock);
|
||||
ComputeBackedgeTakenCountExhaustively(L, ExitCond, !L->contains(TBB));
|
||||
}
|
||||
|
||||
static ConstantInt *
|
||||
|
48
test/Analysis/ScalarEvolution/trip-count5.ll
Normal file
48
test/Analysis/ScalarEvolution/trip-count5.ll
Normal file
@ -0,0 +1,48 @@
|
||||
; RUN: llvm-as < %s | opt -analyze -scalar-evolution -disable-output > %t
|
||||
; RUN: grep sext %t | count 2
|
||||
; RUN: not grep {(sext} %t
|
||||
|
||||
; ScalarEvolution should be able to compute a maximum trip count
|
||||
; value sufficient to fold away both sext casts.
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
|
||||
|
||||
define float @t(float* %pTmp1, float* %peakWeight, float* %nrgReducePeakrate, i32 %bim) nounwind {
|
||||
entry:
|
||||
%tmp3 = load float* %peakWeight, align 4 ; <float> [#uses=2]
|
||||
%tmp2538 = icmp sgt i32 %bim, 0 ; <i1> [#uses=1]
|
||||
br i1 %tmp2538, label %bb.nph, label %bb4
|
||||
|
||||
bb.nph: ; preds = %entry
|
||||
br label %bb
|
||||
|
||||
bb: ; preds = %bb1, %bb.nph
|
||||
%distERBhi.036 = phi float [ %tmp10, %bb1 ], [ 0.000000e+00, %bb.nph ] ; <float> [#uses=1]
|
||||
%hiPart.035 = phi i32 [ %tmp12, %bb1 ], [ 0, %bb.nph ] ; <i32> [#uses=2]
|
||||
%peakCount.034 = phi float [ %tmp19, %bb1 ], [ %tmp3, %bb.nph ] ; <float> [#uses=1]
|
||||
%tmp6 = sext i32 %hiPart.035 to i64 ; <i64> [#uses=1]
|
||||
%tmp7 = getelementptr float* %pTmp1, i64 %tmp6 ; <float*> [#uses=1]
|
||||
%tmp8 = load float* %tmp7, align 4 ; <float> [#uses=1]
|
||||
%tmp10 = fadd float %tmp8, %distERBhi.036 ; <float> [#uses=3]
|
||||
%tmp12 = add i32 %hiPart.035, 1 ; <i32> [#uses=3]
|
||||
%tmp15 = sext i32 %tmp12 to i64 ; <i64> [#uses=1]
|
||||
%tmp16 = getelementptr float* %peakWeight, i64 %tmp15 ; <float*> [#uses=1]
|
||||
%tmp17 = load float* %tmp16, align 4 ; <float> [#uses=1]
|
||||
%tmp19 = fadd float %tmp17, %peakCount.034 ; <float> [#uses=2]
|
||||
br label %bb1
|
||||
|
||||
bb1: ; preds = %bb
|
||||
%tmp21 = fcmp olt float %tmp10, 2.500000e+00 ; <i1> [#uses=1]
|
||||
%tmp25 = icmp slt i32 %tmp12, %bim ; <i1> [#uses=1]
|
||||
%tmp27 = and i1 %tmp21, %tmp25 ; <i1> [#uses=1]
|
||||
br i1 %tmp27, label %bb, label %bb1.bb4_crit_edge
|
||||
|
||||
bb1.bb4_crit_edge: ; preds = %bb1
|
||||
br label %bb4
|
||||
|
||||
bb4: ; preds = %bb1.bb4_crit_edge, %entry
|
||||
%distERBhi.0.lcssa = phi float [ %tmp10, %bb1.bb4_crit_edge ], [ 0.000000e+00, %entry ] ; <float> [#uses=1]
|
||||
%peakCount.0.lcssa = phi float [ %tmp19, %bb1.bb4_crit_edge ], [ %tmp3, %entry ] ; <float> [#uses=1]
|
||||
%tmp31 = fdiv float %peakCount.0.lcssa, %distERBhi.0.lcssa ; <float> [#uses=1]
|
||||
ret float %tmp31
|
||||
}
|
Loading…
Reference in New Issue
Block a user