[cfe-commits] r59033 - /cfe/trunk/lib/CodeGen/CGStmt.cpp

Chris Lattner sabre at nondot.org
Mon Nov 10 23:24:29 PST 2008


Author: lattner
Date: Tue Nov 11 01:24:28 2008
New Revision: 59033

URL: http://llvm.org/viewvc/llvm-project?rev=59033&view=rev
Log:
Make codegen smart enough to not emit the dead side of an if whose
condition is a constant.  This shrinks -O0 codegen by quite a bit
on some cases.

Modified:
    cfe/trunk/lib/CodeGen/CGStmt.cpp

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Tue Nov 11 01:24:28 2008
@@ -217,14 +217,56 @@
   EmitDummyBlock();
 }
 
-void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
-  // FIXME: It would probably be nice for us to skip emission of if
-  // (0) code here.
+/// 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.
   llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
   
+  // If we constant folded the condition to true or false, try to avoid emitting
+  // the dead arm at all.
+  if (llvm::ConstantInt *CondCst = dyn_cast<llvm::ConstantInt>(BoolCondVal)) {
+    // Figure out which block (then or else) is executed.
+    const Stmt *Executed = S.getThen(), *Skipped  = S.getElse();
+    if (!CondCst->getZExtValue())
+      std::swap(Executed, Skipped);
+
+    // If the skipped block has no labels in it, just emit the executed block.
+    // This avoids emitting dead code and simplifies the CFG substantially.
+    if (Skipped == 0 || !ContainsLabel(Skipped)) {
+      if (Executed)
+        EmitStmt(Executed);
+      return;
+    }
+  }
+  
   llvm::BasicBlock *ContBlock = createBasicBlock("ifend");
   llvm::BasicBlock *ThenBlock = createBasicBlock("ifthen");
   llvm::BasicBlock *ElseBlock = ContBlock;
@@ -851,7 +893,8 @@
         if (ConvertType(InputExpr->getType())->isSingleValueType()) {
           Arg = EmitScalarExpr(InputExpr);
         } else {
-          ErrorUnsupported(&S, "asm statement passing multiple-value types as inputs");
+          ErrorUnsupported(&S,
+                      "asm statement passing multiple-value types as inputs");
         }
       } else {
         LValue Dest = EmitLValue(InputExpr);
@@ -891,7 +934,8 @@
       if (ConvertType(InputExpr->getType())->isSingleValueType()) {
         Arg = EmitScalarExpr(InputExpr);
       } else {
-        ErrorUnsupported(&S, "asm statement passing multiple-value types as inputs");
+        ErrorUnsupported(&S,
+                        "asm statement passing multiple-value types as inputs");
       }
     } else {
       LValue Dest = EmitLValue(InputExpr);





More information about the cfe-commits mailing list