summaryrefslogtreecommitdiffstats
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-02-25 21:38:16 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-02-25 21:38:16 +0000
commit8ed20910d8b5c35d28c5cbe7e9170d40837192dd (patch)
treeaf58a5a7a4654ed30f16111b3dc7f3b6b66b756c /lib/AST/ExprConstant.cpp
parentd1dc3aa25797301788f1c4f30f769b1d9e1fb22a (diff)
When evaluating integer expressions handle logical operators outside
VisitBinaryOperator() to reduce stack pressure for source with huge number of logical operators. Fixes rdar://10913206. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151460 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r--lib/AST/ExprConstant.cpp82
1 files changed, 48 insertions, 34 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 44e41864f0..224f88cfc2 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -4095,6 +4095,9 @@ public:
}
bool VisitCallExpr(const CallExpr *E);
+ bool VisitBinLAnd(const BinaryOperator *E);
+ bool VisitBinLOr(const BinaryOperator *E);
+ bool VisitBinLogicalOp(const BinaryOperator *E);
bool VisitBinaryOperator(const BinaryOperator *E);
bool VisitOffsetOfExpr(const OffsetOfExpr *E);
bool VisitUnaryOperator(const UnaryOperator *E);
@@ -4495,6 +4498,50 @@ static APSInt CheckedIntArithmetic(EvalInfo &Info, const Expr *E,
return Result;
}
+// Handle logical operators outside VisitBinaryOperator() to reduce
+// stack pressure for source with huge number of logical operators.
+bool IntExprEvaluator::VisitBinLAnd(const BinaryOperator *E) {
+ return VisitBinLogicalOp(E);
+}
+bool IntExprEvaluator::VisitBinLOr(const BinaryOperator *E) {
+ return VisitBinLogicalOp(E);
+}
+
+bool IntExprEvaluator::VisitBinLogicalOp(const BinaryOperator *E) {
+ // These need to be handled specially because the operands aren't
+ // necessarily integral nor evaluated.
+ bool lhsResult, rhsResult;
+
+ if (EvaluateAsBooleanCondition(E->getLHS(), lhsResult, Info)) {
+ // We were able to evaluate the LHS, see if we can get away with not
+ // evaluating the RHS: 0 && X -> 0, 1 || X -> 1
+ if (lhsResult == (E->getOpcode() == BO_LOr))
+ return Success(lhsResult, E);
+
+ if (EvaluateAsBooleanCondition(E->getRHS(), rhsResult, Info)) {
+ if (E->getOpcode() == BO_LOr)
+ return Success(lhsResult || rhsResult, E);
+ else
+ return Success(lhsResult && rhsResult, E);
+ }
+ } else {
+ // Since we weren't able to evaluate the left hand side, it
+ // must have had side effects.
+ Info.EvalStatus.HasSideEffects = true;
+
+ // Suppress diagnostics from this arm.
+ SpeculativeEvaluationRAII Speculative(Info);
+ if (EvaluateAsBooleanCondition(E->getRHS(), rhsResult, Info)) {
+ // We can't evaluate the LHS; however, sometimes the result
+ // is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
+ if (rhsResult == (E->getOpcode() == BO_LOr))
+ return Success(rhsResult, E);
+ }
+ }
+
+ return false;
+}
+
bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
if (E->isAssignmentOp())
return Error(E);
@@ -4504,40 +4551,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
return Visit(E->getRHS());
}
- if (E->isLogicalOp()) {
- // These need to be handled specially because the operands aren't
- // necessarily integral nor evaluated.
- bool lhsResult, rhsResult;
-
- if (EvaluateAsBooleanCondition(E->getLHS(), lhsResult, Info)) {
- // We were able to evaluate the LHS, see if we can get away with not
- // evaluating the RHS: 0 && X -> 0, 1 || X -> 1
- if (lhsResult == (E->getOpcode() == BO_LOr))
- return Success(lhsResult, E);
-
- if (EvaluateAsBooleanCondition(E->getRHS(), rhsResult, Info)) {
- if (E->getOpcode() == BO_LOr)
- return Success(lhsResult || rhsResult, E);
- else
- return Success(lhsResult && rhsResult, E);
- }
- } else {
- // Since we weren't able to evaluate the left hand side, it
- // must have had side effects.
- Info.EvalStatus.HasSideEffects = true;
-
- // Suppress diagnostics from this arm.
- SpeculativeEvaluationRAII Speculative(Info);
- if (EvaluateAsBooleanCondition(E->getRHS(), rhsResult, Info)) {
- // We can't evaluate the LHS; however, sometimes the result
- // is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
- if (rhsResult == (E->getOpcode() == BO_LOr))
- return Success(rhsResult, E);
- }
- }
-
- return false;
- }
+ assert(!E->isLogicalOp() && "Logical ops not handled separately?");
QualType LHSTy = E->getLHS()->getType();
QualType RHSTy = E->getRHS()->getType();