From: Devang Patel Date: Tue, 9 Oct 2007 20:51:27 +0000 (+0000) Subject: Recognize while(1) and avoid extra blocks. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2c30d8fee8981ca4f20a477456dae1b722b53f1d;p=clang Recognize while(1) and avoid extra blocks. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42811 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/CodeGen/CGStmt.cpp b/CodeGen/CGStmt.cpp index 226462b125..3a55e04818 100644 --- a/CodeGen/CGStmt.cpp +++ b/CodeGen/CGStmt.cpp @@ -169,9 +169,13 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) { // of the controlling expression takes place before each execution of the loop // body. llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); - - // TODO: while(1) is common, avoid extra exit blocks, etc. Be sure + + // while(1) is common, avoid extra exit blocks. Be sure // to correctly handle break/continue though. + bool EmitBoolCondBranch = true; + if (llvm::ConstantInt *C = dyn_cast(BoolCondVal)) + if (C->isOne()) + EmitBoolCondBranch = false; // Create an exit block for when the condition fails, create a block for the // body of the loop. @@ -179,7 +183,8 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) { llvm::BasicBlock *LoopBody = new llvm::BasicBlock("whilebody"); // As long as the condition is true, go to the loop body. - Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); + if (EmitBoolCondBranch) + Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); // Store the blocks to use for break and continue. BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader)); @@ -195,6 +200,14 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) { // Emit the exit block. EmitBlock(ExitBlock); + + // If LoopHeader is a simple forwarding block then eliminate it. + if (!EmitBoolCondBranch + && &LoopHeader->front() == LoopHeader->getTerminator()) { + LoopHeader->replaceAllUsesWith(LoopBody); + LoopHeader->getTerminator()->eraseFromParent(); + LoopHeader->eraseFromParent(); + } } void CodeGenFunction::EmitDoStmt(const DoStmt &S) { @@ -231,7 +244,6 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S) { if (C->isZero()) EmitBoolCondBranch = false; - // As long as the condition is true, iterate the loop. if (EmitBoolCondBranch) Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo); diff --git a/test/CodeGen/whilestmt.c b/test/CodeGen/whilestmt.c new file mode 100644 index 0000000000..8ded265d0c --- /dev/null +++ b/test/CodeGen/whilestmt.c @@ -0,0 +1,62 @@ +// RUN: clang %s -emit-llvm + +int bar(); +int foo() { + int i; + i = 1 + 2; + while(1) { + i = bar(); + i = bar(); + }; + return i; +} + + +int foo1() { + int i; + i = 1 + 2; + while(1) { + i = bar(); + if (i == 42) + break; + i = bar(); + }; + return i; +} + + +int foo2() { + int i; + i = 1 + 2; + while(1) { + i = bar(); + if (i == 42) + continue; + i = bar(); + }; + return i; +} + + +int foo3() { + int i; + i = 1 + 2; + while(1) { + i = bar(); + if (i == 42) + break; + }; + return i; +} + + +int foo4() { + int i; + i = 1 + 2; + while(1) { + i = bar(); + if (i == 42) + continue; + }; + return i; +}