]> granicus.if.org Git - clang/commitdiff
Wire up CFG improvements for do { } while () when the condition is known.
authorMike Stump <mrs@apple.com>
Tue, 21 Jul 2009 01:27:50 +0000 (01:27 +0000)
committerMike Stump <mrs@apple.com>
Tue, 21 Jul 2009 01:27:50 +0000 (01:27 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76530 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 01cb6cb7f6b30d4b146d52cb9ae7e1425a100b69..258f67e1d525fae9c5955cf1d29a01999ae62f59 100644 (file)
@@ -1256,11 +1256,22 @@ CFGBlock* CFGBuilder::VisitObjCAtThrowStmt(ObjCAtThrowStmt* S) {
 }
 
 CFGBlock *CFGBuilder::VisitDoStmt(DoStmt* D) {
-  // "do...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;
+  Expr::EvalResult Result;
+  if (D->getCond()->Evaluate(Result, *Context)
+      && Result.Val.isInt()) {
+    if (Result.Val.getInt().getBoolValue())
+      KnownTrue = true;
+    else
+      KnownFalse = true;
+  }
 
   CFGBlock* LoopSuccessor = NULL;
 
+  // "do...while" is a control-flow statement.  Thus we stop processing the
+  // current block.
   if (Block) {
     if (!FinishBlock(Block))
       return 0;
@@ -1330,13 +1341,21 @@ CFGBlock *CFGBuilder::VisitDoStmt(DoStmt* D) {
     CFGBlock *LoopBackBlock = createBlock();
     LoopBackBlock->setLoopTarget(D);
 
-    // Add the loop body entry as a successor to the condition.
-    ExitConditionBlock->addSuccessor(LoopBackBlock);
+    if (KnownFalse)
+      ExitConditionBlock->addSuccessor(0);
+    else {
+      // Add the loop body entry as a successor to the condition.
+      ExitConditionBlock->addSuccessor(LoopBackBlock);
+    }
   }
 
-  // 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);
+  }
 
   // There can be no more statements in the body block(s) since we loop back to
   // the body.  NULL out Block to force lazy creation of another block.
index 3233b974d6478f80f80023747a611702eafe55e5..5f14010e5f777daa136b1363efe5577ca32fe43c 100644 (file)
@@ -204,6 +204,9 @@ void f22() {
   int y13 = 4;
   int y14 = 4;
   int y15 = 4;
+  int y16 = 4;
+  int y17 = 4;
+  int y18 = 4;
 
   ++x; // expected-warning{{never read}}
   ++y1;
@@ -221,6 +224,9 @@ void f22() {
   ++y13;
   ++y14;
   ++y15;
+  ++y16;
+  ++y17;
+  ++y18;
 
   switch (j) {
   case 1:
@@ -277,34 +283,46 @@ void f22() {
     (void)y10;
     break;
   case 10:
-    while (1) {
-      (void)y11;
+    while (0) {
+      (void)x;
     }
-    (void)x;
+    (void)y11;
     break;
   case 11:
-    while (0) {
-      (void)x;
+    while (1) {
+      (void)y12;
     }
-    (void)y12;
+    (void)x;
     break;
   case 12:
-    for (;;) {
+    do {
       (void)y13;
+    } while (0);
+    (void)y14;
+    break;
+  case 13:
+    do {
+      (void)y15;
+    } while (1);
+    (void)x;
+    break;
+  case 14:
+    for (;;) {
+      (void)y16;
     }
     (void)x;    
     break;
-  case 13:
+  case 15:
     for (;1;) {
-      (void)y14;
+      (void)y17;
     }
     (void)x;
     break;
-  case 14:
+  case 16:
     for (;0;) {
       (void)x;
     }
-    (void)y15;
+    (void)y18;
     break;
   }
 }