]> granicus.if.org Git - clang/commitdiff
emit better codegen for ||/&&, shrinking expr.ll by another 240 lines.
authorChris Lattner <sabre@nondot.org>
Wed, 12 Nov 2008 08:38:24 +0000 (08:38 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 12 Nov 2008 08:38:24 +0000 (08:38 +0000)
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

lib/CodeGen/CGExprScalar.cpp

index c8e1aa58a5367f5c54c7294e918f2d480b4450d7..a3964ee2fc22ad696256d19e334649566132bad1 100644 (file)
@@ -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.