[llvm] r310545 - [LVI] Fix LVI compile time regression around constantFoldUser()
Hiroshi Yamauchi via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 9 19:23:14 PDT 2017
Author: yamauchi
Date: Wed Aug 9 19:23:14 2017
New Revision: 310545
URL: http://llvm.org/viewvc/llvm-project?rev=310545&view=rev
Log:
[LVI] Fix LVI compile time regression around constantFoldUser()
Summary:
Avoid checking each operand and calling getValueFromCondition() before calling
constantFoldUser() when the instruction type isn't supported by
constantFoldUser().
This fixes a large compile time regression in an internal build.
Reviewers: sanjoy
Reviewed By: sanjoy
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D36552
Modified:
llvm/trunk/lib/Analysis/LazyValueInfo.cpp
Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=310545&r1=310544&r2=310545&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Wed Aug 9 19:23:14 2017
@@ -1370,23 +1370,32 @@ static bool usesOperand(User *Usr, Value
return find(Usr->operands(), Op) != Usr->op_end();
}
-// Check if Val can be simplified to an integer constant when the value of one
+// Return true if the instruction type of Val is supported by
+// constantFoldUser(). Currently CastInst and BinaryOperator only. Call this
+// before calling constantFoldUser() to find out if it's even worth attempting
+// to call it.
+static bool isOperationFoldable(User *Usr) {
+ return isa<CastInst>(Usr) || isa<BinaryOperator>(Usr);
+}
+
+// Check if Usr can be simplified to an integer constant when the value of one
// of its operands Op is an integer constant OpConstVal. If so, return it as an
// lattice value range with a single element or otherwise return an overdefined
// lattice value.
-static LVILatticeVal constantFoldUser(Value *Val, Value *Op,
+static LVILatticeVal constantFoldUser(User *Usr, Value *Op,
const APInt &OpConstVal,
const DataLayout &DL) {
+ assert(isOperationFoldable(Usr) && "Precondition");
Constant* OpConst = Constant::getIntegerValue(Op->getType(), OpConstVal);
- // Check if Val can be simplified to a constant.
- if (auto *CI = dyn_cast<CastInst>(Val)) {
+ // Check if Usr can be simplified to a constant.
+ if (auto *CI = dyn_cast<CastInst>(Usr)) {
assert(CI->getOperand(0) == Op && "Operand 0 isn't Op");
if (auto *C = dyn_cast_or_null<ConstantInt>(
SimplifyCastInst(CI->getOpcode(), OpConst,
CI->getDestTy(), DL))) {
return LVILatticeVal::getRange(ConstantRange(C->getValue()));
}
- } else if (auto *BO = dyn_cast<BinaryOperator>(Val)) {
+ } else if (auto *BO = dyn_cast<BinaryOperator>(Usr)) {
bool Op0Match = BO->getOperand(0) == Op;
bool Op1Match = BO->getOperand(1) == Op;
assert((Op0Match || Op1Match) &&
@@ -1434,7 +1443,10 @@ static bool getEdgeValueLocal(Value *Val
if (User *Usr = dyn_cast<User>(Val)) {
assert(Result.isOverdefined() && "Result isn't overdefined");
- if (isa<IntegerType>(Val->getType())) {
+ // Check with isOperationFoldable() first to avoid linearly iterating
+ // over the operands unnecessarily which can be expensive for
+ // instructions with many operands.
+ if (isa<IntegerType>(Usr->getType()) && isOperationFoldable(Usr)) {
const DataLayout &DL = BBTo->getModule()->getDataLayout();
if (usesOperand(Usr, Condition)) {
// If Val has Condition as an operand and Val can be folded into a
@@ -1445,7 +1457,7 @@ static bool getEdgeValueLocal(Value *Val
// %Val = and i1 %Condition, true.
// br %Condition, label %then, label %else
APInt ConditionVal(1, isTrueDest ? 1 : 0);
- Result = constantFoldUser(Val, Condition, ConditionVal, DL);
+ Result = constantFoldUser(Usr, Condition, ConditionVal, DL);
} else {
// If one of Val's operand has an inferred value, we may be able to
// infer the value of Val.
@@ -1459,7 +1471,7 @@ static bool getEdgeValueLocal(Value *Val
LVILatticeVal OpLatticeVal =
getValueFromCondition(Op, Condition, isTrueDest);
if (Optional<APInt> OpConst = OpLatticeVal.asConstantInteger()) {
- Result = constantFoldUser(Val, Op, OpConst.getValue(), DL);
+ Result = constantFoldUser(Usr, Op, OpConst.getValue(), DL);
break;
}
}
@@ -1477,15 +1489,16 @@ static bool getEdgeValueLocal(Value *Val
Value *Condition = SI->getCondition();
if (!isa<IntegerType>(Val->getType()))
return false;
- bool ValUsesCondition = false;
+ bool ValUsesConditionAndMayBeFoldable = false;
if (Condition != Val) {
// Check if Val has Condition as an operand.
if (User *Usr = dyn_cast<User>(Val))
- ValUsesCondition = usesOperand(Usr, Condition);
- if (!ValUsesCondition)
+ ValUsesConditionAndMayBeFoldable = isOperationFoldable(Usr) &&
+ usesOperand(Usr, Condition);
+ if (!ValUsesConditionAndMayBeFoldable)
return false;
}
- assert((Condition == Val || ValUsesCondition) &&
+ assert((Condition == Val || ValUsesConditionAndMayBeFoldable) &&
"Condition != Val nor Val doesn't use Condition");
bool DefaultCase = SI->getDefaultDest() == BBTo;
@@ -1495,10 +1508,11 @@ static bool getEdgeValueLocal(Value *Val
for (auto Case : SI->cases()) {
APInt CaseValue = Case.getCaseValue()->getValue();
ConstantRange EdgeVal(CaseValue);
- if (ValUsesCondition) {
+ if (ValUsesConditionAndMayBeFoldable) {
+ User *Usr = cast<User>(Val);
const DataLayout &DL = BBTo->getModule()->getDataLayout();
LVILatticeVal EdgeLatticeVal =
- constantFoldUser(Val, Condition, CaseValue, DL);
+ constantFoldUser(Usr, Condition, CaseValue, DL);
if (EdgeLatticeVal.isOverdefined())
return false;
EdgeVal = EdgeLatticeVal.getConstantRange();
More information about the llvm-commits
mailing list