forked from OSchip/llvm-project
[InlineCost] Do not take INT_MAX when Cost is negative
Summary: visitSwitchInst should not take INT_MAX when Cost is negative. Instead of INT_MAX , we also use a valid upperbound cost when overflow occurs in Cost. Reviewers: hans, echristo, dmgreen Reviewed By: dmgreen Subscribers: mcrosier, javed.absar, llvm-commits, eraman Differential Revision: https://reviews.llvm.org/D34436 llvm-svn: 306118
This commit is contained in:
parent
eaf0051ba3
commit
506cfb7ab7
|
@ -1022,12 +1022,15 @@ bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {
|
||||||
// inlining those. It will prevent inlining in cases where the optimization
|
// inlining those. It will prevent inlining in cases where the optimization
|
||||||
// does not (yet) fire.
|
// does not (yet) fire.
|
||||||
|
|
||||||
|
// Maximum valid cost increased in this function.
|
||||||
|
int CostUpperBound = INT_MAX - InlineConstants::InstrCost - 1;
|
||||||
|
|
||||||
// Exit early for a large switch, assuming one case needs at least one
|
// Exit early for a large switch, assuming one case needs at least one
|
||||||
// instruction.
|
// instruction.
|
||||||
// FIXME: This is not true for a bit test, but ignore such case for now to
|
// FIXME: This is not true for a bit test, but ignore such case for now to
|
||||||
// save compile-time.
|
// save compile-time.
|
||||||
int64_t CostLowerBound =
|
int64_t CostLowerBound =
|
||||||
std::min((int64_t)INT_MAX,
|
std::min((int64_t)CostUpperBound,
|
||||||
(int64_t)SI.getNumCases() * InlineConstants::InstrCost + Cost);
|
(int64_t)SI.getNumCases() * InlineConstants::InstrCost + Cost);
|
||||||
|
|
||||||
if (CostLowerBound > Threshold) {
|
if (CostLowerBound > Threshold) {
|
||||||
|
@ -1044,7 +1047,8 @@ bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {
|
||||||
if (JumpTableSize) {
|
if (JumpTableSize) {
|
||||||
int64_t JTCost = (int64_t)JumpTableSize * InlineConstants::InstrCost +
|
int64_t JTCost = (int64_t)JumpTableSize * InlineConstants::InstrCost +
|
||||||
4 * InlineConstants::InstrCost;
|
4 * InlineConstants::InstrCost;
|
||||||
Cost = std::min((int64_t)INT_MAX, JTCost + Cost);
|
|
||||||
|
Cost = std::min((int64_t)CostUpperBound, JTCost + Cost);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1068,10 +1072,12 @@ bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {
|
||||||
Cost += NumCaseCluster * 2 * InlineConstants::InstrCost;
|
Cost += NumCaseCluster * 2 * InlineConstants::InstrCost;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int64_t ExpectedNumberOfCompare = 3 * (uint64_t)NumCaseCluster / 2 - 1;
|
|
||||||
uint64_t SwitchCost =
|
int64_t ExpectedNumberOfCompare = 3 * (int64_t)NumCaseCluster / 2 - 1;
|
||||||
|
int64_t SwitchCost =
|
||||||
ExpectedNumberOfCompare * 2 * InlineConstants::InstrCost;
|
ExpectedNumberOfCompare * 2 * InlineConstants::InstrCost;
|
||||||
Cost = std::min((uint64_t)INT_MAX, SwitchCost + Cost);
|
|
||||||
|
Cost = std::min((int64_t)CostUpperBound, SwitchCost + Cost);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,3 +121,40 @@ define i32 @caller_jumptable(i32 %a, i32 %b, i32* %P) {
|
||||||
ret i32 %r
|
ret i32 %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
define internal i32 @callee_negativeCost(i32 %t) {
|
||||||
|
entry:
|
||||||
|
switch i32 %t, label %sw.default [
|
||||||
|
i32 1, label %sw.bb
|
||||||
|
i32 0, label %sw.bb1
|
||||||
|
i32 42, label %sw.bb2
|
||||||
|
i32 43, label %sw.bb3
|
||||||
|
]
|
||||||
|
|
||||||
|
sw.bb: ; preds = %entry
|
||||||
|
br label %cleanup
|
||||||
|
|
||||||
|
sw.bb1: ; preds = %entry
|
||||||
|
br label %cleanup
|
||||||
|
|
||||||
|
sw.bb2: ; preds = %entry
|
||||||
|
br label %cleanup
|
||||||
|
|
||||||
|
sw.bb3: ; preds = %entry
|
||||||
|
br label %cleanup
|
||||||
|
|
||||||
|
sw.default: ; preds = %entry
|
||||||
|
br label %cleanup
|
||||||
|
|
||||||
|
cleanup: ; preds = %sw.default, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb
|
||||||
|
%retval.0 = phi i32 [ 1, %sw.default ], [ 3, %sw.bb3 ], [ 2, %sw.bb2 ], [ 0, %sw.bb1 ], [ 0, %sw.bb ]
|
||||||
|
ret i32 %retval.0
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @caller_negativeCost(i32 %t) {
|
||||||
|
; CHECK-LABEL: @caller_negativeCost(
|
||||||
|
; CHECK-NOT: call i32 @callee_negativeCost
|
||||||
|
entry:
|
||||||
|
%call = call i32 @callee_negativeCost(i32 %t)
|
||||||
|
ret i32 %call
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue