Recognize while(1) and avoid extra blocks.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42811 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel 2007-10-09 20:51:27 +00:00
Родитель a2c534223d
Коммит 2c30d8fee8
2 изменённых файлов: 78 добавлений и 4 удалений

Просмотреть файл

@ -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);

62
test/CodeGen/whilestmt.c Normal file
Просмотреть файл

@ -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;
}