diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-02-25 23:21:37 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-02-25 23:21:37 +0000 |
commit | 2fa975c94027c6565cb112ffcf93c05b22922c0e (patch) | |
tree | c0e528d69d11f01ba7649a9ddc92ab7c8d899cd0 /lib/AST/ExprConstant.cpp | |
parent | faf4ef62b6a4f5b0638e4fb7f77c33a8935bd003 (diff) |
Revert r151460 as it is not enough to address the issue.
Original log:
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@151464 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 90 |
1 files changed, 38 insertions, 52 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 224f88cfc2..0cb8e80871 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -406,7 +406,7 @@ namespace { /// certain things in certain situations. struct EvalInfo { ASTContext &Ctx; - +CCValue WVal; /// EvalStatus - Contains information about the evaluation. Expr::EvalStatus &EvalStatus; @@ -1205,10 +1205,10 @@ static bool HandleConversionToBool(const CCValue &Val, bool &Result) { static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info) { assert(E->isRValue() && "missing lvalue-to-rvalue conv in bool condition"); - CCValue Val; - if (!Evaluate(Val, Info, E)) + //CCValue Val; + if (!Evaluate(Info.WVal, Info, E)) return false; - return HandleConversionToBool(Val, Result); + return HandleConversionToBool(Info.WVal, Result); } template<typename T> @@ -4095,9 +4095,6 @@ 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); @@ -4498,50 +4495,6 @@ 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); @@ -4551,7 +4504,40 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { return Visit(E->getRHS()); } - assert(!E->isLogicalOp() && "Logical ops not handled separately?"); + 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; + } QualType LHSTy = E->getLHS()->getType(); QualType RHSTy = E->getRHS()->getType(); |