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

Chris Lattner sabre at nondot.org
Wed Nov 12 00:04:59 PST 2008


Author: lattner
Date: Wed Nov 12 02:04:58 2008
New Revision: 59113

URL: http://llvm.org/viewvc/llvm-project?rev=59113&view=rev
Log:
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.

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=59113&r1=59112&r2=59113&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Wed Nov 12 02:04:58 2008
@@ -1111,31 +1111,29 @@
 
 Value *ScalarExprEmitter::
 VisitConditionalOperator(const ConditionalOperator *E) {
-  // Evaluate the conditional, then convert it to bool.  We do this explicitly
-  // because we need the unconverted value if this is a GNU ?: expression with
-  // missing middle value.
-  Value *CondVal = CGF.EmitScalarExpr(E->getCond());
-
-  // If the condition folded to a constant, try to elide the dead side.  We
-  // can't do this if the dead side contains a label.
-  if (llvm::ConstantInt *CondCI = dyn_cast<llvm::ConstantInt>(CondVal)) {
+  // If the condition constant folds and can be elided, try to avoid emitting
+  // the condition and the dead arm.
+  if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getCond())){
     Expr *Live = E->getLHS(), *Dead = E->getRHS();
-    if (CondCI->isZero())
+    if (Cond == -1)
       std::swap(Live, Dead);
-    if (!Dead || !CGF.ContainsLabel(Dead)) {
-      // Emit the live side.
-      if (Live)
-        return Visit(Live);
-      // Perform promotions, to handle cases like "short ?: int"
-      return EmitScalarConversion(CondVal, E->getCond()->getType(),
-                                  E->getType());
-    }   
+    
+    // If the dead side doesn't have labels we need, and if the Live side isn't
+    // the gnu missing ?: extension (which we could handle, but don't bother
+    // to), just emit the Live part.
+    if ((!Dead || !CGF.ContainsLabel(Dead)) &&  // No labels in dead part
+        Live)                                   // Live part isn't missing.
+      return Visit(Live);
   }
   
   llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.?");
   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.:");
   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.cont");
-  
+
+  // Evaluate the conditional, then convert it to bool.  We do this explicitly
+  // because we need the unconverted value if this is a GNU ?: expression with
+  // missing middle value.
+  Value *CondVal = CGF.EmitScalarExpr(E->getCond());
   Value *CondBoolVal =CGF.EmitScalarConversion(CondVal, E->getCond()->getType(),
                                                CGF.getContext().BoolTy);
   Builder.CreateCondBr(CondBoolVal, LHSBlock, RHSBlock);

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Wed Nov 12 02:04:58 2008
@@ -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 @@
   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 @@
   // 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 @@
   // 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

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Nov 12 02:04:58 2008
@@ -15,6 +15,7 @@
 #include "CodeGenModule.h"
 #include "CGDebugInfo.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/AST/APValue.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "llvm/Support/CFG.h"
@@ -186,6 +187,90 @@
   return false;
 }
 
+
+/// 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.
+int CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond) {
+  APValue V;
+  if (!Cond->tryEvaluate(V, getContext()))
+    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()) == 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()) == 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()) == -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()) == -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);
+}
+
 /// 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=59113&r1=59112&r2=59113&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Nov 12 02:04:58 2008
@@ -563,9 +563,19 @@
   /// that we can just remove the code.
   static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false);
   
-private:
+  /// 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.
+  int ConstantFoldsToSimpleInteger(const Expr *Cond);
+    
+  /// 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 EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock,
-                            llvm::BasicBlock *FalseBlock);
+                          llvm::BasicBlock *FalseBlock);
+private:
   
   /// EmitIndirectSwitches - Emit code for all of the switch
   /// instructions in IndirectSwitches.





More information about the cfe-commits mailing list