diff options
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index f1b72863ca..ca478707ef 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -408,22 +408,23 @@ bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) { } -/// ConstantFoldsToSimpleInteger - If the sepcified expression does not fold to -/// a constant, or if it does but contains a label, return 0. If it constant -/// folds to 'true' and does not contain a label, return 1, if it constant folds -/// to 'false' and does not contain a label, return -1. -int CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond) { +/// ConstantFoldsToSimpleInteger - If the specified expression does not fold +/// to a constant, or if it does but contains a label, return false. If it +/// constant folds return true and set the boolean result in Result. +bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond, + bool &ResultBool) { // FIXME: Rename and handle conversion of other evaluatable things // to bool. Expr::EvalResult Result; if (!Cond->Evaluate(Result, getContext()) || !Result.Val.isInt() || Result.HasSideEffects) - return 0; // Not foldable, not integer or not fully evaluatable. + return false; // Not foldable, not integer or not fully evaluatable. if (CodeGenFunction::ContainsLabel(Cond)) - return 0; // Contains a label. + return false; // Contains a label. - return Result.Val.getInt().getBoolValue() ? 1 : -1; + ResultBool = Result.Val.getInt().getBoolValue(); + return true; } @@ -442,14 +443,17 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, if (CondBOp->getOpcode() == BO_LAnd) { // If we have "1 && X", simplify the code. "0 && X" would have constant // folded if the case was simple enough. - if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == 1) { + bool ConstantBool; + if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) && + ConstantBool) { // br(1 && X) -> br(X). return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); } // If we have "X && 1", simplify the code to use an uncond branch. // "X && 0" would have been constant folded to 0. - if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == 1) { + if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) && + ConstantBool) { // br(X && 1) -> br(X). return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock); } @@ -468,17 +472,22 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, eval.end(*this); return; - } else if (CondBOp->getOpcode() == BO_LOr) { + } + + if (CondBOp->getOpcode() == BO_LOr) { // If we have "0 || X", simplify the code. "1 || X" would have constant // folded if the case was simple enough. - if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == -1) { + bool ConstantBool; + if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) && + !ConstantBool) { // br(0 || X) -> br(X). return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); } // If we have "X || 0", simplify the code to use an uncond branch. // "X || 1" would have been constant folded to 1. - if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == -1) { + if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) && + !ConstantBool) { // br(X || 0) -> br(X). return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock); } |