diff options
author | Chris Lattner <sabre@nondot.org> | 2008-11-12 08:38:24 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-11-12 08:38:24 +0000 |
commit | f7b5ea9de3d043fa900ab8a8976a4c0eefc233b7 (patch) | |
tree | ea00e1a2629e4bdfa9c1cc9c85349041ac73641c /lib/CodeGen/CGExprScalar.cpp | |
parent | 20eb09d562b80420a3328be789547af354bf3e36 (diff) |
emit better codegen for ||/&&, shrinking expr.ll by another 240 lines.
This happens for stuff like this:
x = cond1 || cond2 || cond3 || cond4;
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59123 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index c8e1aa58a5..a3964ee2fc 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -22,6 +22,7 @@ #include "llvm/GlobalVariable.h" #include "llvm/Intrinsics.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/CFG.h" #include <cstdarg> using namespace clang; @@ -1035,22 +1036,27 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land_cont"); llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("land_rhs"); - Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS()); - Builder.CreateCondBr(LHSCond, RHSBlock, ContBlock); - llvm::BasicBlock *OrigBlock = Builder.GetInsertBlock(); + // Branch on the LHS first. If it is false, go to the failure (cont) block. + CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock); + + // Any edges into the ContBlock are now from an (indeterminate number of) + // edges from this first condition. All of these values will be false. Start + // setting up the PHI node in the Cont Block for this. + llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::Int1Ty, "", ContBlock); + PN->reserveOperandSpace(2); // Normal case, two inputs. + for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock); + PI != PE; ++PI) + PN->addIncoming(llvm::ConstantInt::getFalse(), *PI); CGF.EmitBlock(RHSBlock); Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); // Reaquire the RHS block, as there may be subblocks inserted. RHSBlock = Builder.GetInsertBlock(); + + // Emit an unconditional branch from this block to ContBlock. Insert an entry + // into the phi node for the edge with the value of RHSCond. CGF.EmitBlock(ContBlock); - - // Create a PHI node. If we just evaluted the LHS condition, the result is - // false. If we evaluated both, the result is the RHS condition. - llvm::PHINode *PN = Builder.CreatePHI(llvm::Type::Int1Ty, "land"); - PN->reserveOperandSpace(2); - PN->addIncoming(llvm::ConstantInt::getFalse(), OrigBlock); PN->addIncoming(RHSCond, RHSBlock); // ZExt result to int. @@ -1075,22 +1081,28 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor_cont"); llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor_rhs"); - Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS()); - Builder.CreateCondBr(LHSCond, ContBlock, RHSBlock); - llvm::BasicBlock *OrigBlock = Builder.GetInsertBlock(); - + // Branch on the LHS first. If it is true, go to the success (cont) block. + CGF.EmitBranchOnBoolExpr(E->getLHS(), ContBlock, RHSBlock); + + // Any edges into the ContBlock are now from an (indeterminate number of) + // edges from this first condition. All of these values will be true. Start + // setting up the PHI node in the Cont Block for this. + llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::Int1Ty, "", ContBlock); + PN->reserveOperandSpace(2); // Normal case, two inputs. + for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock); + PI != PE; ++PI) + PN->addIncoming(llvm::ConstantInt::getTrue(), *PI); + + // Emit the RHS condition as a bool value. CGF.EmitBlock(RHSBlock); Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); // Reaquire the RHS block, as there may be subblocks inserted. RHSBlock = Builder.GetInsertBlock(); - CGF.EmitBlock(ContBlock); - // Create a PHI node. If we just evaluted the LHS condition, the result is - // true. If we evaluated both, the result is the RHS condition. - llvm::PHINode *PN = Builder.CreatePHI(llvm::Type::Int1Ty, "lor"); - PN->reserveOperandSpace(2); - PN->addIncoming(llvm::ConstantInt::getTrue(), OrigBlock); + // Emit an unconditional branch from this block to ContBlock. Insert an entry + // into the phi node for the edge with the value of RHSCond. + CGF.EmitBlock(ContBlock); PN->addIncoming(RHSCond, RHSBlock); // ZExt result to int. |