]> granicus.if.org Git - clang/commitdiff
Wire up for statement CFG improvements for conditionals that are known.
authorMike Stump <mrs@apple.com>
Tue, 21 Jul 2009 01:12:51 +0000 (01:12 +0000)
committerMike Stump <mrs@apple.com>
Tue, 21 Jul 2009 01:12:51 +0000 (01:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76529 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CFG.cpp
test/Analysis/dead-stores.c

index 3dc364292e7cb1a197b738796233219d9e7499b4..01cb6cb7f6b30d4b146d52cb9ae7e1425a100b69 100644 (file)
@@ -863,10 +863,24 @@ CFGBlock* CFGBuilder::VisitGotoStmt(GotoStmt* G) {
 }
 
 CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
-  // "for" is a control-flow statement.  Thus we stop processing the current
-  // block.
+  // See if this is a known constant.
+  bool KnownTrue = false;
+  bool KnownFalse = false;
+  Expr::EvalResult Result;
+  if (F->getCond() && F->getCond()->Evaluate(Result, *Context)
+      && Result.Val.isInt()) {
+    if (Result.Val.getInt().getBoolValue())
+      KnownTrue = true;
+    else
+      KnownFalse = true;
+  }
+  if (F->getCond() == 0)
+    KnownTrue = true;
+
   CFGBlock* LoopSuccessor = NULL;
 
+  // "for" is a control-flow statement.  Thus we stop processing the current
+  // block.
   if (Block) {
     if (!FinishBlock(Block))
       return 0;
@@ -949,13 +963,21 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
         return 0;
     }
 
-    // This new body block is a successor to our "exit" condition block.
-    ExitConditionBlock->addSuccessor(BodyBlock);
+    if (KnownFalse)
+      ExitConditionBlock->addSuccessor(0);
+    else {
+      // This new body block is a successor to our "exit" condition block.
+      ExitConditionBlock->addSuccessor(BodyBlock);
+    }
   }
 
-  // Link up the condition block with the code that follows the loop.  (the
-  // false branch).
-  ExitConditionBlock->addSuccessor(LoopSuccessor);
+  if (KnownTrue)
+    ExitConditionBlock->addSuccessor(0);
+  else {
+    // Link up the condition block with the code that follows the loop.  (the
+    // false branch).
+    ExitConditionBlock->addSuccessor(LoopSuccessor);
+  }
 
   // If the loop contains initialization, create a new block for those
   // statements.  This block can also contain statements that precede the loop.
@@ -1099,9 +1121,6 @@ CFGBlock* CFGBuilder::VisitObjCAtTryStmt(ObjCAtTryStmt* S) {
 }
 
 CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
-  // "while" is a control-flow statement.  Thus we stop processing the current
-  // block.
-
   // See if this is a known constant.
   bool KnownTrue = false;
   bool KnownFalse = false;
@@ -1116,6 +1135,8 @@ CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
 
   CFGBlock* LoopSuccessor = NULL;
 
+  // "while" is a control-flow statement.  Thus we stop processing the current
+  // block.
   if (Block) {
     if (!FinishBlock(Block))
       return 0;
index 4798eb152a1d18dbd32cd431b80a939c6b424035..3233b974d6478f80f80023747a611702eafe55e5 100644 (file)
@@ -201,6 +201,9 @@ void f22() {
   int y10 = 4;
   int y11 = 4;
   int y12 = 4;
+  int y13 = 4;
+  int y14 = 4;
+  int y15 = 4;
 
   ++x; // expected-warning{{never read}}
   ++y1;
@@ -215,6 +218,9 @@ void f22() {
   ++y10;
   ++y11;
   ++y12;
+  ++y13;
+  ++y14;
+  ++y15;
 
   switch (j) {
   case 1:
@@ -282,5 +288,23 @@ void f22() {
     }
     (void)y12;
     break;
+  case 12:
+    for (;;) {
+      (void)y13;
+    }
+    (void)x;    
+    break;
+  case 13:
+    for (;1;) {
+      (void)y14;
+    }
+    (void)x;
+    break;
+  case 14:
+    for (;0;) {
+      (void)x;
+    }
+    (void)y15;
+    break;
   }
 }