diff options
author | Chris Lattner <sabre@nondot.org> | 2008-11-12 08:04:58 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-11-12 08:04:58 +0000 |
commit | 31a0984b5cb4af99d2407c0f25bf5af68df681c6 (patch) | |
tree | e1752760f7afede860249245b9aab7ef37bc3fa3 /lib/CodeGen/CGStmt.cpp | |
parent | 210e0f57dbd10f6f2db60a9532a75d326b91fe0b (diff) |
Move EmitBranchOnBoolExpr and ConstantFoldsToSimpleInteger to
CodeGenFunction.cpp. Change VisitConditionalOperator to use
constant fold instead of codegen'ing a constant conditional.
Change ForStmt to use EmitBranchOnBoolExpr, this shrinks
expr.c very slightly to 40239 lines.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59113 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGStmt.cpp')
-rw-r--r-- | lib/CodeGen/CGStmt.cpp | 98 |
1 files changed, 6 insertions, 92 deletions
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index 551a4c040b..88da20d4e8 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -14,7 +14,6 @@ #include "CGDebugInfo.h" #include "CodeGenModule.h" #include "CodeGenFunction.h" -#include "clang/AST/APValue.h" #include "clang/AST/StmtVisitor.h" #include "clang/Basic/TargetInfo.h" #include "llvm/InlineAsm.h" @@ -224,98 +223,13 @@ void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) { Builder.ClearInsertionPoint(); } - -/// 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. -static int ConstantFoldsToSimpleInteger(const Expr *Cond, ASTContext &Ctx) { - APValue V; - if (!Cond->tryEvaluate(V, Ctx)) - return 0; // Not foldable. - - if (CodeGenFunction::ContainsLabel(Cond)) - return 0; // Contains a label. - - return V.getInt().getBoolValue() ? 1 : -1; -} - - -/// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if -/// statement) to the specified blocks. Based on the condition, this might try -/// to simplify the codegen of the conditional based on the branch. -/// -void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, - llvm::BasicBlock *TrueBlock, - llvm::BasicBlock *FalseBlock) { - if (const ParenExpr *PE = dyn_cast<ParenExpr>(Cond)) - return EmitBranchOnBoolExpr(PE->getSubExpr(), TrueBlock, FalseBlock); - - if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) { - // Handle X && Y in a condition. - if (CondBOp->getOpcode() == BinaryOperator::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(), getContext()) == 1) { - // 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(), getContext()) == 1) { - // br(X && 1) -> br(X). - return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock); - } - - // Emit the LHS as a conditional. If the LHS conditional is false, we - // want to jump to the FalseBlock. - llvm::BasicBlock *LHSTrue = createBasicBlock("land_lhs_true"); - EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock); - EmitBlock(LHSTrue); - - EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); - return; - } else if (CondBOp->getOpcode() == BinaryOperator::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(), getContext()) == -1) { - // 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(), getContext()) == -1) { - // br(X || 0) -> br(X). - return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock); - } - - // Emit the LHS as a conditional. If the LHS conditional is true, we - // want to jump to the TrueBlock. - llvm::BasicBlock *LHSFalse = createBasicBlock("lor_lhs_false"); - EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse); - EmitBlock(LHSFalse); - - EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); - return; - } - - } - - // Emit the code with the fully general case. - llvm::Value *CondV = EvaluateExprAsBool(Cond); - Builder.CreateCondBr(CondV, TrueBlock, FalseBlock); -} - - void CodeGenFunction::EmitIfStmt(const IfStmt &S) { // C99 6.8.4.1: The first substatement is executed if the expression compares // unequal to 0. The condition must be a scalar type. // If the condition constant folds and can be elided, try to avoid emitting // the condition and the dead arm of the if/else. - if (int Cond = ConstantFoldsToSimpleInteger(S.getCond(), getContext())) { + if (int Cond = ConstantFoldsToSimpleInteger(S.getCond())) { // Figure out which block (then or else) is executed. const Stmt *Executed = S.getThen(), *Skipped = S.getElse(); if (Cond == -1) // Condition false? @@ -382,7 +296,7 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) { // As long as the condition is true, go to the loop body. if (EmitBoolCondBranch) Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); - + // Store the blocks to use for break and continue. BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader)); @@ -476,13 +390,13 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) { // Evaluate the condition if present. If not, treat it as a non-zero-constant // according to 6.8.5.3p2, aka, true. if (S.getCond()) { + // As long as the condition is true, iterate the loop. + llvm::BasicBlock *ForBody = createBasicBlock("forbody"); + // C99 6.8.5p2/p4: The first substatement is executed if the expression // compares unequal to 0. The condition must be a scalar type. - llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); + EmitBranchOnBoolExpr(S.getCond(), ForBody, AfterFor); - // As long as the condition is true, iterate the loop. - llvm::BasicBlock *ForBody = createBasicBlock("forbody"); - Builder.CreateCondBr(BoolCondVal, ForBody, AfterFor); EmitBlock(ForBody); } else { // Treat it as a non-zero constant. Don't even create a new block for the |