summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2008-11-11 09:41:28 +0000
committerDaniel Dunbar <daniel@zuster.org>2008-11-11 09:41:28 +0000
commitc56e67644f705e0728b802447d82902db2305c75 (patch)
treee7f314727a0895560c281fe217096f1074f94585 /clang/lib/CodeGen
parenta0821bf8a2a386d24dbe3a51b3fdd74304b3104f (diff)
downloadbcm5719-llvm-c56e67644f705e0728b802447d82902db2305c75.tar.gz
bcm5719-llvm-c56e67644f705e0728b802447d82902db2305c75.zip
Add CodeGenFunction::EmitBranch.
- Emits an unconditional branch, with extra logic to avoid generating spurious branches out of dummy blocks. llvm-svn: 59037
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGExprAgg.cpp6
-rw-r--r--clang/lib/CodeGen/CGExprComplex.cpp4
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp4
-rw-r--r--clang/lib/CodeGen/CGObjCMac.cpp2
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp60
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h5
6 files changed, 40 insertions, 41 deletions
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index b7139456b77..f531d3676f0 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -242,14 +242,12 @@ void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
assert(E->getLHS() && "Must have LHS for aggregate value");
Visit(E->getLHS());
- Builder.CreateBr(ContBlock);
- LHSBlock = Builder.GetInsertBlock();
+ CGF.EmitBranch(ContBlock);
CGF.EmitBlock(RHSBlock);
Visit(E->getRHS());
- Builder.CreateBr(ContBlock);
- RHSBlock = Builder.GetInsertBlock();
+ CGF.EmitBranch(ContBlock);
CGF.EmitBlock(ContBlock);
}
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index d12d355ee70..92226620269 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -479,14 +479,14 @@ VisitConditionalOperator(const ConditionalOperator *E) {
assert(E->getLHS() && "Must have LHS for complex value");
ComplexPairTy LHS = Visit(E->getLHS());
- Builder.CreateBr(ContBlock);
LHSBlock = Builder.GetInsertBlock();
+ CGF.EmitBranch(ContBlock);
CGF.EmitBlock(RHSBlock);
ComplexPairTy RHS = Visit(E->getRHS());
- Builder.CreateBr(ContBlock);
RHSBlock = Builder.GetInsertBlock();
+ CGF.EmitBranch(ContBlock);
CGF.EmitBlock(ContBlock);
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 4a179383577..465574187aa 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -1139,14 +1139,14 @@ VisitConditionalOperator(const ConditionalOperator *E) {
else // Perform promotions, to handle cases like "short ?: int"
LHS = EmitScalarConversion(CondVal, E->getCond()->getType(), E->getType());
- Builder.CreateBr(ContBlock);
LHSBlock = Builder.GetInsertBlock();
+ CGF.EmitBranch(ContBlock);
CGF.EmitBlock(RHSBlock);
Value *RHS = Visit(E->getRHS());
- Builder.CreateBr(ContBlock);
RHSBlock = Builder.GetInsertBlock();
+ CGF.EmitBranch(ContBlock);
CGF.EmitBlock(ContBlock);
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 903e92dfc2d..8722e15dc0c 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1725,7 +1725,7 @@ void CodeGenFunction::EmitJumpThroughFinally(ObjCEHEntry *E,
bool ExecuteTryExit) {
llvm::BasicBlock *Src = Builder.GetInsertBlock();
- if (isDummyBlock(Src))
+ if (!Src || isDummyBlock(Src))
return;
// Find the destination code for this block. We always use 0 for the
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index b042261ec38..f2088f416d5 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -149,22 +149,30 @@ RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
}
void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB) {
- // Emit a branch from this block to the next one if this was a real block. If
- // this was just a fall-through block after a terminator, don't emit it.
- llvm::BasicBlock *LastBB = Builder.GetInsertBlock();
-
- if (LastBB->getTerminator()) {
- // If the previous block is already terminated, don't touch it.
- } else if (isDummyBlock(LastBB)) {
+ // Fall out of the current block (if necessary).
+ EmitBranch(BB);
+ CurFn->getBasicBlockList().push_back(BB);
+ Builder.SetInsertPoint(BB);
+}
+
+void CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) {
+ // Emit a branch from the current block to the target one if this
+ // was a real block. If this was just a fall-through block after a
+ // terminator, don't emit it.
+ llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
+
+ if (!CurBB || CurBB->getTerminator()) {
+ // If there is no insert point or the previous block is already
+ // terminated, don't touch it.
+ } else if (isDummyBlock(CurBB)) {
// If the last block was an empty placeholder, remove it now.
// TODO: cache and reuse these.
- LastBB->eraseFromParent();
+ CurBB->eraseFromParent();
+ Builder.ClearInsertionPoint();
} else {
// Otherwise, create a fall-through branch.
- Builder.CreateBr(BB);
+ Builder.CreateBr(Target);
}
- CurFn->getBasicBlockList().push_back(BB);
- Builder.SetInsertPoint(BB);
}
void CodeGenFunction::EmitDummyBlock() {
@@ -189,7 +197,7 @@ void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
return;
}
- Builder.CreateBr(getBasicBlockForLabel(S.getLabel()));
+ EmitBranch(getBasicBlockForLabel(S.getLabel()));
// Emit a block after the branch so that dead code after a goto has some place
// to go.
@@ -252,25 +260,13 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
// Emit the 'then' code.
EmitBlock(ThenBlock);
EmitStmt(S.getThen());
- llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (isDummyBlock(BB)) {
- BB->eraseFromParent();
- Builder.SetInsertPoint(ThenBlock);
- } else {
- Builder.CreateBr(ContBlock);
- }
+ EmitBranch(ContBlock);
// Emit the 'else' code if present.
if (const Stmt *Else = S.getElse()) {
EmitBlock(ElseBlock);
EmitStmt(Else);
- llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (isDummyBlock(BB)) {
- BB->eraseFromParent();
- Builder.SetInsertPoint(ElseBlock);
- } else {
- Builder.CreateBr(ContBlock);
- }
+ EmitBranch(ContBlock);
}
// Emit the continuation block for code after the if.
@@ -314,7 +310,7 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
BreakContinueStack.pop_back();
// Cycle to the condition.
- Builder.CreateBr(LoopHeader);
+ EmitBranch(LoopHeader);
// Emit the exit block.
EmitBlock(ExitBlock);
@@ -433,7 +429,7 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) {
}
// Finally, branch back up to the condition for the next iteration.
- Builder.CreateBr(CondBlock);
+ EmitBranch(CondBlock);
// Emit the fall-through block.
EmitBlock(AfterFor);
@@ -447,7 +443,7 @@ void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) {
} else {
StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false);
}
- Builder.CreateBr(ReturnBlock);
+ EmitBranch(ReturnBlock);
// Emit a block after the branch so that dead code after a return has some
// place to go.
@@ -487,7 +483,7 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
}
}
- Builder.CreateBr(ReturnBlock);
+ EmitBranch(ReturnBlock);
// Emit a block after the branch so that dead code after a return has some
// place to go.
@@ -504,7 +500,7 @@ void CodeGenFunction::EmitBreakStmt() {
assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!");
llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock;
- Builder.CreateBr(Block);
+ EmitBranch(Block);
EmitDummyBlock();
}
@@ -512,7 +508,7 @@ void CodeGenFunction::EmitContinueStmt() {
assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock;
- Builder.CreateBr(Block);
+ EmitBranch(Block);
EmitDummyBlock();
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 04d64e4ee13..d482086e1a1 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -226,6 +226,11 @@ public:
void EmitBlock(llvm::BasicBlock *BB);
+ /// EmitBranch - Emit a branch to the specified basic block from the
+ /// current insert block, taking care to avoid creation of branches
+ /// from dummy blocks.
+ void EmitBranch(llvm::BasicBlock *Block);
+
/// EmitDummyBlock - Emit a new block which will never be branched
/// to. This is used to satisfy the invariant that codegen always
/// has an active unterminated block to dump code into.
OpenPOWER on IntegriCloud