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
|
||||
// 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
|
||||
// instruction.
|
||||
// FIXME: This is not true for a bit test, but ignore such case for now to
|
||||
// save compile-time.
|
||||
int64_t CostLowerBound =
|
||||
std::min((int64_t)INT_MAX,
|
||||
std::min((int64_t)CostUpperBound,
|
||||
(int64_t)SI.getNumCases() * InlineConstants::InstrCost + Cost);
|
||||
|
||||
if (CostLowerBound > Threshold) {
|
||||
|
@ -1044,7 +1047,8 @@ bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {
|
|||
if (JumpTableSize) {
|
||||
int64_t JTCost = (int64_t)JumpTableSize * InlineConstants::InstrCost +
|
||||
4 * InlineConstants::InstrCost;
|
||||
Cost = std::min((int64_t)INT_MAX, JTCost + Cost);
|
||||
|
||||
Cost = std::min((int64_t)CostUpperBound, JTCost + Cost);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1068,10 +1072,12 @@ bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {
|
|||
Cost += NumCaseCluster * 2 * InlineConstants::InstrCost;
|
||||
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;
|
||||
Cost = std::min((uint64_t)INT_MAX, SwitchCost + Cost);
|
||||
|
||||
Cost = std::min((int64_t)CostUpperBound, SwitchCost + Cost);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,3 +121,40 @@ define i32 @caller_jumptable(i32 %a, i32 %b, i32* %P) {
|
|||
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