[cfe-commits] r59034 - in /cfe/trunk/lib/CodeGen: CGExprScalar.cpp CGStmt.cpp CodeGenFunction.cpp CodeGenFunction.h

Chris Lattner sabre at nondot.org
Mon Nov 10 23:41:27 PST 2008


Author: lattner
Date: Tue Nov 11 01:41:27 2008
New Revision: 59034

URL: http://llvm.org/viewvc/llvm-project?rev=59034&view=rev
Log:
short circuit && and || when possible.  This substantially reduces
the size of the -O0 output on some cases.  For example, on expr.c from
176.gcc, it shrinks the .ll file from 43164 to 42835 lines, and removed
references to two external symbols.

Modified:
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CGStmt.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=59034&r1=59033&r2=59034&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Tue Nov 11 01:41:27 2008
@@ -1028,6 +1028,20 @@
 Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
   Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS());
   
+  if (llvm::ConstantInt *LHSCst = dyn_cast<llvm::ConstantInt>(LHSCond)) {
+    // If we have 0 && RHS, see if we can elide RHS, if so, just return LHSCond.
+    if (LHSCst->getZExtValue() == 0) {
+      if (!CGF.ContainsLabel(E->getRHS()))
+        // Elide RHS, return 0
+        return llvm::Constant::getNullValue(CGF.LLVMIntTy);
+    } else {
+      // If we have 1 && X, just emit X without inserting the control flow.
+      Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
+      // ZExt result to int.
+      return Builder.CreateZExt(RHSCond, CGF.LLVMIntTy, "land.ext");
+    }
+  }
+  
   llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("land_cont");
   llvm::BasicBlock *RHSBlock = llvm::BasicBlock::Create("land_rhs");
   
@@ -1055,6 +1069,20 @@
 Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
   Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS());
   
+  if (llvm::ConstantInt *LHSCst = dyn_cast<llvm::ConstantInt>(LHSCond)) {
+    // If we have 1 || RHS, see if we can elide RHS, if so, just return LHSCond.
+    if (LHSCst->getZExtValue() != 0) {
+      if (!CGF.ContainsLabel(E->getRHS()))
+        // Elide RHS, return 1
+        return llvm::ConstantInt::get(CGF.LLVMIntTy, 1);
+    } else {
+      // If we have 0 || X, just emit X without inserting the control flow.
+      Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
+      // ZExt result to int.
+      return Builder.CreateZExt(RHSCond, CGF.LLVMIntTy, "lor.ext");
+    }
+  }
+  
   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor_cont");
   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor_rhs");
   

Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=59034&r1=59033&r2=59034&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Tue Nov 11 01:41:27 2008
@@ -217,34 +217,6 @@
   EmitDummyBlock();
 }
 
-/// ContainsLabel - Return true if the statement contains a label in it.  If
-/// this statement is not executed normally, it not containing a label means
-/// that we can just remove the code.
-static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false) {
-  // If this is a label, we have to emit the code, consider something like:
-  // if (0) {  ...  foo:  bar(); }  goto foo;
-  if (isa<LabelStmt>(S))
-    return true;
-  
-  // If this is a case/default statement, and we haven't seen a switch, we have
-  // to emit the code.
-  if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
-    return true;
-
-  // If this is a switch statement, we want to ignore cases below it.
-  if (isa<SwitchStmt>(S))
-    IgnoreCaseStmts = true;
-  
-  // Scan subexpressions for verboten labels.
-  for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
-       I != E; ++I)
-    if (ContainsLabel(*I, IgnoreCaseStmts))
-      return true;
-
-  return false;
-}
-
-
 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.

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=59034&r1=59033&r2=59034&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue Nov 11 01:41:27 2008
@@ -163,6 +163,36 @@
   return false;
 }
 
+/// ContainsLabel - Return true if the statement contains a label in it.  If
+/// this statement is not executed normally, it not containing a label means
+/// that we can just remove the code.
+bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) {
+  // Null statement, not a label!
+  if (S == 0) return false;
+  
+  // If this is a label, we have to emit the code, consider something like:
+  // if (0) {  ...  foo:  bar(); }  goto foo;
+  if (isa<LabelStmt>(S))
+    return true;
+  
+  // If this is a case/default statement, and we haven't seen a switch, we have
+  // to emit the code.
+  if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
+    return true;
+  
+  // If this is a switch statement, we want to ignore cases below it.
+  if (isa<SwitchStmt>(S))
+    IgnoreCaseStmts = true;
+  
+  // Scan subexpressions for verboten labels.
+  for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
+       I != E; ++I)
+    if (ContainsLabel(*I, IgnoreCaseStmts))
+      return true;
+  
+  return false;
+}
+
 /// getCGRecordLayout - Return record layout info.
 const CGRecordLayout *CodeGenFunction::getCGRecordLayout(CodeGenTypes &CGT,
                                                          QualType Ty) {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=59034&r1=59033&r2=59034&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Nov 11 01:41:27 2008
@@ -513,7 +513,13 @@
   //                             Internal Helpers
   //===--------------------------------------------------------------------===//
  
+  /// ContainsLabel - Return true if the statement contains a label in it.  If
+  /// this statement is not executed normally, it not containing a label means
+  /// that we can just remove the code.
+  static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false);
+  
 private:
+  
   /// EmitIndirectSwitches - Emit code for all of the switch
   /// instructions in IndirectSwitches.
   void EmitIndirectSwitches();





More information about the cfe-commits mailing list