зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
a2c534223d
Коммит
2c30d8fee8
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
Загрузка…
Ссылка в новой задаче