diff options
| author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-02-25 21:38:16 +0000 |
|---|---|---|
| committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-02-25 21:38:16 +0000 |
| commit | 70f9eb571e01c27f0745da7f8af621f88f181301 (patch) | |
| tree | f793f4d2bb76d9dbe6f356f06cc95b8b89cadb23 /clang/lib | |
| parent | 908d2bebaf8a9a3c52082e81a8d65ab82ee933c2 (diff) | |
| download | bcm5719-llvm-70f9eb571e01c27f0745da7f8af621f88f181301.tar.gz bcm5719-llvm-70f9eb571e01c27f0745da7f8af621f88f181301.zip | |
When evaluating integer expressions handle logical operators outside
VisitBinaryOperator() to reduce stack pressure for source with huge number
of logical operators.
Fixes rdar://10913206.
llvm-svn: 151460
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 82 |
1 files changed, 48 insertions, 34 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 44e41864f0b..224f88cfc2a 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/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(); |

