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 | 35710d18fe769a73d0661bad23ba9b6883d57ecc (patch) | |
| tree | ac241c80a084172f8ddf3612c50118d346914093 /clang/lib/CodeGen | |
| parent | 2907b0085c5b995d6c3e3be4520686d209e387c7 (diff) | |
| download | bcm5719-llvm-35710d18fe769a73d0661bad23ba9b6883d57ecc.tar.gz bcm5719-llvm-35710d18fe769a73d0661bad23ba9b6883d57ecc.zip | |
emit better codegen for ||/&&, shrinking expr.ll by another 240 lines.
This happens for stuff like this:
x = cond1 || cond2 || cond3 || cond4;
llvm-svn: 59123
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 50 | 
1 files changed, 31 insertions, 19 deletions
| diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index c8e1aa58a53..a3964ee2fc2 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/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. | 

