Wire up CFG improvements for __builtin_choose_expr.
authorMike Stump <mrs@apple.com>
Tue, 21 Jul 2009 01:46:17 +0000 (01:46 +0000)
committerMike Stump <mrs@apple.com>
Tue, 21 Jul 2009 01:46:17 +0000 (01:46 +0000)
llvm-svn: 76531

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

index 258f67e..79ca811 100644 (file)
@@ -521,6 +521,18 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, bool alwaysAdd) {
 }
 
 CFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C) {
+  // See if this is a known constant.
+  bool KnownTrue = false;
+  bool KnownFalse = false;
+  Expr::EvalResult Result;
+  if (C->getCond()->Evaluate(Result, *Context)
+      && Result.Val.isInt()) {
+    if (Result.Val.getInt().getBoolValue())
+      KnownTrue = true;
+    else
+      KnownFalse = true;
+  }
+
   CFGBlock* ConfluenceBlock = Block ? Block : createBlock();
   ConfluenceBlock->appendStmt(C);
   if (!FinishBlock(ConfluenceBlock))
@@ -539,8 +551,14 @@ CFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C) {
     return 0;
   
   Block = createBlock(false);
-  Block->addSuccessor(LHSBlock);
-  Block->addSuccessor(RHSBlock);
+  if (KnownFalse)
+    Block->addSuccessor(0);
+  else
+    Block->addSuccessor(LHSBlock);
+  if (KnownTrue)
+    Block->addSuccessor(0);
+  else
+    Block->addSuccessor(RHSBlock);
   Block->setTerminator(C);
   return addStmt(C->getCond());  
 }
index 5f14010..f3ff145 100644 (file)
@@ -207,6 +207,8 @@ void f22() {
   int y16 = 4;
   int y17 = 4;
   int y18 = 4;
+  int y19 = 4;
+  int y20 = 4;
 
   ++x; // expected-warning{{never read}}
   ++y1;
@@ -227,6 +229,8 @@ void f22() {
   ++y16;
   ++y17;
   ++y18;
+  ++y19;
+  ++y20;
 
   switch (j) {
   case 1:
@@ -324,5 +328,13 @@ void f22() {
     }
     (void)y18;
     break;
+  case 17:
+    __builtin_choose_expr(0, (void)x, ((void)y19, ({ return; })));
+    (void)x;
+    break;
+  case 19:
+    __builtin_choose_expr(1, ((void)y20, ({ return; })), (void)x);
+    (void)x;
+    break;
   }
 }