From 05f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4e Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Tue, 9 Oct 2007 20:33:39 +0000 Subject: [PATCH] Recognize "do {} while (0)" idiom and avoid extra basic blocks. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42808 91177308-0d34-0410-b5e6-96231b3b80d8 --- CodeGen/CGStmt.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/CodeGen/CGStmt.cpp b/CodeGen/CGStmt.cpp index 8412ece2ed..226462b125 100644 --- a/CodeGen/CGStmt.cpp +++ b/CodeGen/CGStmt.cpp @@ -198,9 +198,6 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) { } void CodeGenFunction::EmitDoStmt(const DoStmt &S) { - // TODO: "do {} while (0)" is common in macros, avoid extra blocks. Be sure - // to correctly handle break/continue though. - // Emit the body for the loop, insert it, which will create an uncond br to // it. llvm::BasicBlock *LoopBody = new llvm::BasicBlock("dobody"); @@ -226,12 +223,28 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S) { // C99 6.8.5p2/p4: The first substatement is executed if the expression // compares unequal to 0. The condition must be a scalar type. llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); - + + // "do {} while (0)" is common in macros, avoid extra blocks. Be sure + // to correctly handle break/continue though. + bool EmitBoolCondBranch = true; + if (llvm::ConstantInt *C = dyn_cast(BoolCondVal)) + if (C->isZero()) + EmitBoolCondBranch = false; + + // As long as the condition is true, iterate the loop. - Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo); + if (EmitBoolCondBranch) + Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo); // Emit the exit block. EmitBlock(AfterDo); + + // If DoCond is a simple forwarding block then eliminate it. + if (!EmitBoolCondBranch && &DoCond->front() == DoCond->getTerminator()) { + DoCond->replaceAllUsesWith(AfterDo); + DoCond->getTerminator()->eraseFromParent(); + DoCond->eraseFromParent(); + } } void CodeGenFunction::EmitForStmt(const ForStmt &S) { -- 2.40.0