summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp275
1 files changed, 141 insertions, 134 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp
index efde380..b72725e 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp
@@ -79,11 +79,8 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
// Expression emitters don't handle unreachable blocks yet, so look for one
// explicitly here. This handles the common case of a call to a noreturn
// function.
- // We can't erase blocks with an associated cleanup size here since the
- // memory might be reused, leaving the old cleanup info pointing at a new
- // block.
if (llvm::BasicBlock *CurBB = Builder.GetInsertBlock()) {
- if (CurBB->empty() && CurBB->use_empty() && !BlockScopes.count(CurBB)) {
+ if (CurBB->empty() && CurBB->use_empty()) {
CurBB->eraseFromParent();
Builder.ClearInsertionPoint();
}
@@ -159,7 +156,7 @@ RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
}
// Keep track of the current cleanup stack depth.
- CleanupScope Scope(*this);
+ RunCleanupsScope Scope(*this);
for (CompoundStmt::const_body_iterator I = S.body_begin(),
E = S.body_end()-GetLast; I != E; ++I)
@@ -198,7 +195,7 @@ void CodeGenFunction::SimplifyForwardingBlocks(llvm::BasicBlock *BB) {
// If there is a cleanup stack, then we it isn't worth trying to
// simplify this block (we would need to remove it from the scope map
// and cleanup entry).
- if (!CleanupEntries.empty())
+ if (!EHStack.empty())
return;
// Can only simplify direct branches.
@@ -221,18 +218,6 @@ void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB, bool IsFinished) {
return;
}
- // If necessary, associate the block with the cleanup stack size.
- if (!CleanupEntries.empty()) {
- // Check if the basic block has already been inserted.
- BlockScopeMap::iterator I = BlockScopes.find(BB);
- if (I != BlockScopes.end()) {
- assert(I->second == CleanupEntries.size() - 1);
- } else {
- BlockScopes[BB] = CleanupEntries.size() - 1;
- CleanupEntries.back().Blocks.push_back(BB);
- }
- }
-
// Place the block after the current block, if possible, or else at
// the end of the function.
if (CurBB && CurBB->getParent())
@@ -259,8 +244,35 @@ void CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) {
Builder.ClearInsertionPoint();
}
+CodeGenFunction::JumpDest
+CodeGenFunction::getJumpDestForLabel(const LabelStmt *S) {
+ JumpDest &Dest = LabelMap[S];
+ if (Dest.Block) return Dest;
+
+ // Create, but don't insert, the new block.
+ Dest.Block = createBasicBlock(S->getName());
+ Dest.ScopeDepth = EHScopeStack::stable_iterator::invalid();
+ return Dest;
+}
+
void CodeGenFunction::EmitLabel(const LabelStmt &S) {
- EmitBlock(getBasicBlockForLabel(&S));
+ JumpDest &Dest = LabelMap[&S];
+
+ // If we didn't needed a forward reference to this label, just go
+ // ahead and create a destination at the current scope.
+ if (!Dest.Block) {
+ Dest = getJumpDestInCurrentScope(S.getName());
+
+ // Otherwise, we need to give this label a target depth and remove
+ // it from the branch-fixups list.
+ } else {
+ assert(!Dest.ScopeDepth.isValid() && "already emitted label!");
+ Dest.ScopeDepth = EHStack.stable_begin();
+
+ EHStack.resolveBranchFixups(Dest.Block);
+ }
+
+ EmitBlock(Dest.Block);
}
@@ -276,7 +288,7 @@ void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
if (HaveInsertPoint())
EmitStopPoint(&S);
- EmitBranchThroughCleanup(getBasicBlockForLabel(S.getLabel()));
+ EmitBranchThroughCleanup(getJumpDestForLabel(S.getLabel()));
}
@@ -301,7 +313,7 @@ void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) {
void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
// C99 6.8.4.1: The first substatement is executed if the expression compares
// unequal to 0. The condition must be a scalar type.
- CleanupScope ConditionScope(*this);
+ RunCleanupsScope ConditionScope(*this);
if (S.getConditionVariable())
EmitLocalBlockVarDecl(*S.getConditionVariable());
@@ -318,7 +330,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
// This avoids emitting dead code and simplifies the CFG substantially.
if (!ContainsLabel(Skipped)) {
if (Executed) {
- CleanupScope ExecutedScope(*this);
+ RunCleanupsScope ExecutedScope(*this);
EmitStmt(Executed);
}
return;
@@ -337,7 +349,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
// Emit the 'then' code.
EmitBlock(ThenBlock);
{
- CleanupScope ThenScope(*this);
+ RunCleanupsScope ThenScope(*this);
EmitStmt(S.getThen());
}
EmitBranch(ContBlock);
@@ -346,7 +358,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
if (const Stmt *Else = S.getElse()) {
EmitBlock(ElseBlock);
{
- CleanupScope ElseScope(*this);
+ RunCleanupsScope ElseScope(*this);
EmitStmt(Else);
}
EmitBranch(ContBlock);
@@ -357,20 +369,17 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
}
void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
- // Emit the header for the loop, insert it, which will create an uncond br to
- // it.
- llvm::BasicBlock *LoopHeader = createBasicBlock("while.cond");
- EmitBlock(LoopHeader);
-
- // Create an exit block for when the condition fails, create a block for the
- // body of the loop.
- llvm::BasicBlock *ExitBlock = createBasicBlock("while.end");
- llvm::BasicBlock *LoopBody = createBasicBlock("while.body");
- llvm::BasicBlock *CleanupBlock = 0;
- llvm::BasicBlock *EffectiveExitBlock = ExitBlock;
+ // Emit the header for the loop, which will also become
+ // the continue target.
+ JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond");
+ EmitBlock(LoopHeader.Block);
+
+ // Create an exit block for when the condition fails, which will
+ // also become the break target.
+ JumpDest LoopExit = getJumpDestInCurrentScope("while.end");
// Store the blocks to use for break and continue.
- BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader));
+ BreakContinueStack.push_back(BreakContinue(LoopExit, LoopHeader));
// C++ [stmt.while]p2:
// When the condition of a while statement is a declaration, the
@@ -379,18 +388,10 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
// [...]
// The object created in a condition is destroyed and created
// with each iteration of the loop.
- CleanupScope ConditionScope(*this);
+ RunCleanupsScope ConditionScope(*this);
- if (S.getConditionVariable()) {
+ if (S.getConditionVariable())
EmitLocalBlockVarDecl(*S.getConditionVariable());
-
- // If this condition variable requires cleanups, create a basic
- // block to handle those cleanups.
- if (ConditionScope.requiresCleanups()) {
- CleanupBlock = createBasicBlock("while.cleanup");
- EffectiveExitBlock = CleanupBlock;
- }
- }
// Evaluate the conditional in the while header. C99 6.8.5.1: The
// evaluation of the controlling expression takes place before each
@@ -405,61 +406,63 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
EmitBoolCondBranch = false;
// As long as the condition is true, go to the loop body.
- if (EmitBoolCondBranch)
- Builder.CreateCondBr(BoolCondVal, LoopBody, EffectiveExitBlock);
+ llvm::BasicBlock *LoopBody = createBasicBlock("while.body");
+ if (EmitBoolCondBranch) {
+ llvm::BasicBlock *ExitBlock = LoopExit.Block;
+ if (ConditionScope.requiresCleanups())
+ ExitBlock = createBasicBlock("while.exit");
+
+ Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
+
+ if (ExitBlock != LoopExit.Block) {
+ EmitBlock(ExitBlock);
+ EmitBranchThroughCleanup(LoopExit);
+ }
+ }
- // Emit the loop body.
+ // Emit the loop body. We have to emit this in a cleanup scope
+ // because it might be a singleton DeclStmt.
{
- CleanupScope BodyScope(*this);
+ RunCleanupsScope BodyScope(*this);
EmitBlock(LoopBody);
EmitStmt(S.getBody());
}
BreakContinueStack.pop_back();
- if (CleanupBlock) {
- // If we have a cleanup block, jump there to perform cleanups
- // before looping.
- EmitBranch(CleanupBlock);
+ // Immediately force cleanup.
+ ConditionScope.ForceCleanup();
- // Emit the cleanup block, performing cleanups for the condition
- // and then jumping to either the loop header or the exit block.
- EmitBlock(CleanupBlock);
- ConditionScope.ForceCleanup();
- Builder.CreateCondBr(BoolCondVal, LoopHeader, ExitBlock);
- } else {
- // Cycle to the condition.
- EmitBranch(LoopHeader);
- }
+ // Branch to the loop header again.
+ EmitBranch(LoopHeader.Block);
// Emit the exit block.
- EmitBlock(ExitBlock, true);
-
+ EmitBlock(LoopExit.Block, true);
// The LoopHeader typically is just a branch if we skipped emitting
// a branch, try to erase it.
- if (!EmitBoolCondBranch && !CleanupBlock)
- SimplifyForwardingBlocks(LoopHeader);
+ if (!EmitBoolCondBranch)
+ SimplifyForwardingBlocks(LoopHeader.Block);
}
void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
- // Emit the body for the loop, insert it, which will create an uncond br to
- // it.
- llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
- llvm::BasicBlock *AfterDo = createBasicBlock("do.end");
- EmitBlock(LoopBody);
-
- llvm::BasicBlock *DoCond = createBasicBlock("do.cond");
+ JumpDest LoopExit = getJumpDestInCurrentScope("do.end");
+ JumpDest LoopCond = getJumpDestInCurrentScope("do.cond");
// Store the blocks to use for break and continue.
- BreakContinueStack.push_back(BreakContinue(AfterDo, DoCond));
+ BreakContinueStack.push_back(BreakContinue(LoopExit, LoopCond));
- // Emit the body of the loop into the block.
- EmitStmt(S.getBody());
+ // Emit the body of the loop.
+ llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
+ EmitBlock(LoopBody);
+ {
+ RunCleanupsScope BodyScope(*this);
+ EmitStmt(S.getBody());
+ }
BreakContinueStack.pop_back();
- EmitBlock(DoCond);
+ EmitBlock(LoopCond.Block);
// C99 6.8.5.2: "The evaluation of the controlling expression takes place
// after each execution of the loop body."
@@ -478,47 +481,49 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
// As long as the condition is true, iterate the loop.
if (EmitBoolCondBranch)
- Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo);
+ Builder.CreateCondBr(BoolCondVal, LoopBody, LoopExit.Block);
// Emit the exit block.
- EmitBlock(AfterDo);
+ EmitBlock(LoopExit.Block);
// The DoCond block typically is just a branch if we skipped
// emitting a branch, try to erase it.
if (!EmitBoolCondBranch)
- SimplifyForwardingBlocks(DoCond);
+ SimplifyForwardingBlocks(LoopCond.Block);
}
void CodeGenFunction::EmitForStmt(const ForStmt &S) {
- CleanupScope ForScope(*this);
+ JumpDest LoopExit = getJumpDestInCurrentScope("for.end");
+
+ RunCleanupsScope ForScope(*this);
// Evaluate the first part before the loop.
if (S.getInit())
EmitStmt(S.getInit());
// Start the loop with a block that tests the condition.
- llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
- llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
- llvm::BasicBlock *IncBlock = 0;
- llvm::BasicBlock *CondCleanup = 0;
- llvm::BasicBlock *EffectiveExitBlock = AfterFor;
+ // If there's an increment, the continue scope will be overwritten
+ // later.
+ JumpDest Continue = getJumpDestInCurrentScope("for.cond");
+ llvm::BasicBlock *CondBlock = Continue.Block;
EmitBlock(CondBlock);
// Create a cleanup scope for the condition variable cleanups.
- CleanupScope ConditionScope(*this);
+ RunCleanupsScope ConditionScope(*this);
llvm::Value *BoolCondVal = 0;
if (S.getCond()) {
// If the for statement has a condition scope, emit the local variable
// declaration.
+ llvm::BasicBlock *ExitBlock = LoopExit.Block;
if (S.getConditionVariable()) {
EmitLocalBlockVarDecl(*S.getConditionVariable());
-
- if (ConditionScope.requiresCleanups()) {
- CondCleanup = createBasicBlock("for.cond.cleanup");
- EffectiveExitBlock = CondCleanup;
- }
}
+
+ // If there are any cleanups between here and the loop-exit scope,
+ // create a block to stage a loop exit along.
+ if (ForScope.requiresCleanups())
+ ExitBlock = createBasicBlock("for.cond.cleanup");
// As long as the condition is true, iterate the loop.
llvm::BasicBlock *ForBody = createBasicBlock("for.body");
@@ -526,7 +531,12 @@ void CodeGenFunction::EmitForStmt(const ForStmt &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.
BoolCondVal = EvaluateExprAsBool(S.getCond());
- Builder.CreateCondBr(BoolCondVal, ForBody, EffectiveExitBlock);
+ Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock);
+
+ if (ExitBlock != LoopExit.Block) {
+ EmitBlock(ExitBlock);
+ EmitBranchThroughCleanup(LoopExit);
+ }
EmitBlock(ForBody);
} else {
@@ -535,17 +545,15 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) {
}
// If the for loop doesn't have an increment we can just use the
- // condition as the continue block.
- llvm::BasicBlock *ContinueBlock;
+ // condition as the continue block. Otherwise we'll need to create
+ // a block for it (in the current scope, i.e. in the scope of the
+ // condition), and that we will become our continue block.
if (S.getInc())
- ContinueBlock = IncBlock = createBasicBlock("for.inc");
- else
- ContinueBlock = CondBlock;
+ Continue = getJumpDestInCurrentScope("for.inc");
// Store the blocks to use for break and continue.
- BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock));
+ BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
- // If the condition is true, execute the body of the for stmt.
CGDebugInfo *DI = getDebugInfo();
if (DI) {
DI->setLocation(S.getSourceRange().getBegin());
@@ -555,37 +563,30 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) {
{
// Create a separate cleanup scope for the body, in case it is not
// a compound statement.
- CleanupScope BodyScope(*this);
+ RunCleanupsScope BodyScope(*this);
EmitStmt(S.getBody());
}
// If there is an increment, emit it next.
if (S.getInc()) {
- EmitBlock(IncBlock);
+ EmitBlock(Continue.Block);
EmitStmt(S.getInc());
}
BreakContinueStack.pop_back();
-
- // Finally, branch back up to the condition for the next iteration.
- if (CondCleanup) {
- // Branch to the cleanup block.
- EmitBranch(CondCleanup);
-
- // Emit the cleanup block, which branches back to the loop body or
- // outside of the for statement once it is done.
- EmitBlock(CondCleanup);
- ConditionScope.ForceCleanup();
- Builder.CreateCondBr(BoolCondVal, CondBlock, AfterFor);
- } else
- EmitBranch(CondBlock);
+
+ ConditionScope.ForceCleanup();
+ EmitBranch(CondBlock);
+
+ ForScope.ForceCleanup();
+
if (DI) {
DI->setLocation(S.getSourceRange().getEnd());
DI->EmitRegionEnd(CurFn, Builder);
}
// Emit the fall-through block.
- EmitBlock(AfterFor, true);
+ EmitBlock(LoopExit.Block, true);
}
void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) {
@@ -631,7 +632,7 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
} else if (FnRetTy->isReferenceType()) {
// If this function returns a reference, take the address of the expression
// rather than the value.
- RValue Result = EmitReferenceBindingToExpr(RV, false);
+ RValue Result = EmitReferenceBindingToExpr(RV, /*InitializedDecl=*/0);
Builder.CreateStore(Result.getScalarVal(), ReturnValue);
} else if (!hasAggregateLLVMType(RV->getType())) {
Builder.CreateStore(EmitScalarExpr(RV), ReturnValue);
@@ -666,7 +667,7 @@ void CodeGenFunction::EmitBreakStmt(const BreakStmt &S) {
if (HaveInsertPoint())
EmitStopPoint(&S);
- llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock;
+ JumpDest Block = BreakContinueStack.back().BreakBlock;
EmitBranchThroughCleanup(Block);
}
@@ -679,7 +680,7 @@ void CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) {
if (HaveInsertPoint())
EmitStopPoint(&S);
- llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock;
+ JumpDest Block = BreakContinueStack.back().ContinueBlock;
EmitBranchThroughCleanup(Block);
}
@@ -788,7 +789,9 @@ void CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) {
}
void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
- CleanupScope ConditionScope(*this);
+ JumpDest SwitchExit = getJumpDestInCurrentScope("sw.epilog");
+
+ RunCleanupsScope ConditionScope(*this);
if (S.getConditionVariable())
EmitLocalBlockVarDecl(*S.getConditionVariable());
@@ -803,7 +806,6 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
// statement. We also need to create a default block now so that
// explicit case ranges tests can have a place to jump to on
// failure.
- llvm::BasicBlock *NextBlock = createBasicBlock("sw.epilog");
llvm::BasicBlock *DefaultBlock = createBasicBlock("sw.default");
SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock);
CaseRangeBlock = DefaultBlock;
@@ -813,12 +815,11 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
// All break statements jump to NextBlock. If BreakContinueStack is non empty
// then reuse last ContinueBlock.
- llvm::BasicBlock *ContinueBlock = 0;
+ JumpDest OuterContinue;
if (!BreakContinueStack.empty())
- ContinueBlock = BreakContinueStack.back().ContinueBlock;
+ OuterContinue = BreakContinueStack.back().ContinueBlock;
- // Ensure any vlas created between there and here, are undone
- BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock));
+ BreakContinueStack.push_back(BreakContinue(SwitchExit, OuterContinue));
// Emit switch body.
EmitStmt(S.getBody());
@@ -829,15 +830,22 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
// been chained on top.
SwitchInsn->setSuccessor(0, CaseRangeBlock);
- // If a default was never emitted then reroute any jumps to it and
- // discard.
+ // If a default was never emitted:
if (!DefaultBlock->getParent()) {
- DefaultBlock->replaceAllUsesWith(NextBlock);
- delete DefaultBlock;
+ // If we have cleanups, emit the default block so that there's a
+ // place to jump through the cleanups from.
+ if (ConditionScope.requiresCleanups()) {
+ EmitBlock(DefaultBlock);
+
+ // Otherwise, just forward the default block to the switch end.
+ } else {
+ DefaultBlock->replaceAllUsesWith(SwitchExit.Block);
+ delete DefaultBlock;
+ }
}
// Emit continuation.
- EmitBlock(NextBlock, true);
+ EmitBlock(SwitchExit.Block, true);
SwitchInsn = SavedSwitchInsn;
CaseRangeBlock = SavedCRBlock;
@@ -1066,8 +1074,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
getContext().getTypeSize(InputTy)) {
// Use ptrtoint as appropriate so that we can do our extension.
if (isa<llvm::PointerType>(Arg->getType()))
- Arg = Builder.CreatePtrToInt(Arg,
- llvm::IntegerType::get(VMContext, LLVMPointerWidth));
+ Arg = Builder.CreatePtrToInt(Arg, IntPtrTy);
const llvm::Type *OutputTy = ConvertType(OutputType);
if (isa<llvm::IntegerType>(OutputTy))
Arg = Builder.CreateZExt(Arg, OutputTy);
@@ -1132,7 +1139,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
// call.
unsigned LocID = S.getAsmString()->getLocStart().getRawEncoding();
llvm::Value *LocIDC =
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), LocID);
+ llvm::ConstantInt::get(Int32Ty, LocID);
Result->setMetadata("srcloc", llvm::MDNode::get(VMContext, &LocIDC, 1));
// Extract all of the register value results from the asm.
OpenPOWER on IntegriCloud