From: Mike Stump Date: Tue, 21 Jul 2009 01:27:50 +0000 (+0000) Subject: Wire up CFG improvements for do { } while () when the condition is known. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8f9893a2beeacd5149bd2d3d4c6e130516915068;p=clang Wire up CFG improvements for do { } while () when the condition is known. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76530 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 01cb6cb7f6..258f67e1d5 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -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. diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c index 3233b974d6..5f14010e5f 100644 --- a/test/Analysis/dead-stores.c +++ b/test/Analysis/dead-stores.c @@ -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; } }