summaryrefslogtreecommitdiffstats
path: root/clang/CodeGen/CGStmt.cpp
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2007-10-09 20:51:27 +0000
committerDevang Patel <dpatel@apple.com>2007-10-09 20:51:27 +0000
commit152f18f671fb787eda1b803e956725095fd7ffa3 (patch)
tree4b249cb70fc18c436f6d18a278e801af668eddc2 /clang/CodeGen/CGStmt.cpp
parentf8a76755df0cfa1cbb0adb7a5a53a287a37f0582 (diff)
downloadbcm5719-llvm-152f18f671fb787eda1b803e956725095fd7ffa3.tar.gz
bcm5719-llvm-152f18f671fb787eda1b803e956725095fd7ffa3.zip
Recognize while(1) and avoid extra blocks.
llvm-svn: 42811
Diffstat (limited to 'clang/CodeGen/CGStmt.cpp')
-rw-r--r--clang/CodeGen/CGStmt.cpp20
1 files changed, 16 insertions, 4 deletions
diff --git a/clang/CodeGen/CGStmt.cpp b/clang/CodeGen/CGStmt.cpp
index 226462b1259..3a55e04818b 100644
--- a/clang/CodeGen/CGStmt.cpp
+++ b/clang/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<llvm::ConstantInt>(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);
OpenPOWER on IntegriCloud