forked from OSchip/llvm-project
parent
779dd9382d
commit
1d91dd98ad
|
@ -188,7 +188,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
|
||||||
|
|
||||||
Builder.CreateStore(V, Stack);
|
Builder.CreateStore(V, Stack);
|
||||||
|
|
||||||
StackSaveValues.back() = Stack;
|
StackSaveValues.back() = StackDepth = Stack;
|
||||||
}
|
}
|
||||||
// Get the element type.
|
// Get the element type.
|
||||||
const llvm::Type *LElemTy = ConvertType(Ty);
|
const llvm::Type *LElemTy = ConvertType(Ty);
|
||||||
|
|
|
@ -515,8 +515,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
|
||||||
llvm::BasicBlock *LoopEnd = createBasicBlock("loopend");
|
llvm::BasicBlock *LoopEnd = createBasicBlock("loopend");
|
||||||
llvm::BasicBlock *AfterBody = createBasicBlock("afterbody");
|
llvm::BasicBlock *AfterBody = createBasicBlock("afterbody");
|
||||||
|
|
||||||
BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody,
|
BreakContinuePush(LoopEnd, AfterBody);
|
||||||
ObjCEHStack.size()));
|
|
||||||
|
|
||||||
EmitStmt(S.getBody());
|
EmitStmt(S.getBody());
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,7 @@ RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (llvm::Value *V = StackSaveValues.pop_back_val()) {
|
if (llvm::Value *V = StackSaveValues.pop_back_val()) {
|
||||||
|
StackDepth = V;
|
||||||
V = Builder.CreateLoad(V, "tmp");
|
V = Builder.CreateLoad(V, "tmp");
|
||||||
|
|
||||||
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
|
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
|
||||||
|
@ -186,6 +187,41 @@ void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB, bool IsFinished) {
|
||||||
Builder.SetInsertPoint(BB);
|
Builder.SetInsertPoint(BB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenFunction::EmitStackUpdate(const LabelStmt &S) {
|
||||||
|
if (StackDepthMap.find(&S) == StackDepthMap.end()) {
|
||||||
|
// If we can't find it, just remember the depth now,
|
||||||
|
// so we can validate it later.
|
||||||
|
// FIXME: We need to save a place to insert the adjustment,
|
||||||
|
// if needed, here, sa that later in EmitLabel, we can
|
||||||
|
// backpatch the adjustment into that place, instead of
|
||||||
|
// saying unsupported.
|
||||||
|
StackDepthMap[&S] = StackDepth;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find applicable stack depth, if any...
|
||||||
|
llvm::Value *V = StackDepthMap[&S];
|
||||||
|
// V can be 0 here, if it is, be sure to start searching from the
|
||||||
|
// top of the function, as we want the next save after that point.
|
||||||
|
for (unsigned int i = 0; i < StackSaveValues.size(); ++i)
|
||||||
|
if (StackSaveValues[i] == V) {
|
||||||
|
// The actual depth is actually in the next used slot, if any.
|
||||||
|
while (++i < StackSaveValues.size()
|
||||||
|
&& (V = StackSaveValues[i]) == 0) ;
|
||||||
|
// If there were no other depth changes, we don't need any
|
||||||
|
// adjustments.
|
||||||
|
if (V) {
|
||||||
|
V = Builder.CreateLoad(V, "tmp");
|
||||||
|
// and restore it.
|
||||||
|
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
|
||||||
|
Builder.CreateCall(F, V);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
// FIXME: Move to semq and assert here, codegen isn't the right
|
||||||
|
// time to be checking.
|
||||||
|
CGM.ErrorUnsupported(&S, "invalid goto to VLA scope that has finished");
|
||||||
|
}
|
||||||
|
|
||||||
void CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) {
|
void CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) {
|
||||||
// Emit a branch from the current block to the target one if this
|
// 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
|
// was a real block. If this was just a fall-through block after a
|
||||||
|
@ -205,6 +241,22 @@ void CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) {
|
||||||
|
|
||||||
void CodeGenFunction::EmitLabel(const LabelStmt &S) {
|
void CodeGenFunction::EmitLabel(const LabelStmt &S) {
|
||||||
llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
|
llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
|
||||||
|
if (StackDepthMap.find(&S) == StackDepthMap.end()) {
|
||||||
|
// We need to remember the stack depth so that we can readjust the
|
||||||
|
// stack back to the right depth for this label if we want to
|
||||||
|
// transfer here from a different depth.
|
||||||
|
StackDepthMap[&S] = StackDepth;
|
||||||
|
} else {
|
||||||
|
if (StackDepthMap[&S] != StackDepth) {
|
||||||
|
// FIXME: Sema needs to ckeck for jumps that cross decls with
|
||||||
|
// initializations for C++, and all VLAs, not just the first in
|
||||||
|
// a block that does a stacksave.
|
||||||
|
// FIXME: We need to save a place to insert the adjustment
|
||||||
|
// when we do a EmitStackUpdate on a forward jump, and then
|
||||||
|
// backpatch the adjustment into that place.
|
||||||
|
CGM.ErrorUnsupported(&S, "forward goto inside scope with VLA");
|
||||||
|
}
|
||||||
|
}
|
||||||
EmitBlock(NextBB);
|
EmitBlock(NextBB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,18 +273,16 @@ void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < StackSaveValues.size(); i++) {
|
|
||||||
if (StackSaveValues[i]) {
|
|
||||||
CGM.ErrorUnsupported(&S, "goto inside scope with VLA");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this code is reachable then emit a stop point (if generating
|
// If this code is reachable then emit a stop point (if generating
|
||||||
// debug info). We have to do this ourselves because we are on the
|
// debug info). We have to do this ourselves because we are on the
|
||||||
// "simple" statement path.
|
// "simple" statement path.
|
||||||
if (HaveInsertPoint())
|
if (HaveInsertPoint())
|
||||||
EmitStopPoint(&S);
|
EmitStopPoint(&S);
|
||||||
|
|
||||||
|
// We need to adjust the stack, if the destination was (will be) at
|
||||||
|
// a different depth.
|
||||||
|
EmitStackUpdate(*S.getLabel());
|
||||||
|
|
||||||
EmitBranch(getBasicBlockForLabel(S.getLabel()));
|
EmitBranch(getBasicBlockForLabel(S.getLabel()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,14 +380,13 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
|
||||||
Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
|
Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
|
||||||
|
|
||||||
// Store the blocks to use for break and continue.
|
// Store the blocks to use for break and continue.
|
||||||
BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader,
|
BreakContinuePush(ExitBlock, LoopHeader);
|
||||||
ObjCEHStack.size()));
|
|
||||||
|
|
||||||
// Emit the loop body.
|
// Emit the loop body.
|
||||||
EmitBlock(LoopBody);
|
EmitBlock(LoopBody);
|
||||||
EmitStmt(S.getBody());
|
EmitStmt(S.getBody());
|
||||||
|
|
||||||
BreakContinueStack.pop_back();
|
BreakContinuePop();
|
||||||
|
|
||||||
// Cycle to the condition.
|
// Cycle to the condition.
|
||||||
EmitBranch(LoopHeader);
|
EmitBranch(LoopHeader);
|
||||||
|
@ -364,13 +413,12 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
|
||||||
llvm::BasicBlock *DoCond = createBasicBlock("do.cond");
|
llvm::BasicBlock *DoCond = createBasicBlock("do.cond");
|
||||||
|
|
||||||
// Store the blocks to use for break and continue.
|
// Store the blocks to use for break and continue.
|
||||||
BreakContinueStack.push_back(BreakContinue(AfterDo, DoCond,
|
BreakContinuePush(AfterDo, DoCond);
|
||||||
ObjCEHStack.size()));
|
|
||||||
|
|
||||||
// Emit the body of the loop into the block.
|
// Emit the body of the loop into the block.
|
||||||
EmitStmt(S.getBody());
|
EmitStmt(S.getBody());
|
||||||
|
|
||||||
BreakContinueStack.pop_back();
|
BreakContinuePop();
|
||||||
|
|
||||||
EmitBlock(DoCond);
|
EmitBlock(DoCond);
|
||||||
|
|
||||||
|
@ -443,13 +491,12 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) {
|
||||||
ContinueBlock = CondBlock;
|
ContinueBlock = CondBlock;
|
||||||
|
|
||||||
// Store the blocks to use for break and continue.
|
// Store the blocks to use for break and continue.
|
||||||
BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock,
|
BreakContinuePush(AfterFor, ContinueBlock);
|
||||||
ObjCEHStack.size()));
|
|
||||||
|
|
||||||
// If the condition is true, execute the body of the for stmt.
|
// If the condition is true, execute the body of the for stmt.
|
||||||
EmitStmt(S.getBody());
|
EmitStmt(S.getBody());
|
||||||
|
|
||||||
BreakContinueStack.pop_back();
|
BreakContinuePop();
|
||||||
|
|
||||||
// If there is an increment, emit it next.
|
// If there is an increment, emit it next.
|
||||||
if (S.getInc()) {
|
if (S.getInc()) {
|
||||||
|
@ -678,12 +725,11 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
|
||||||
llvm::BasicBlock *ContinueBlock = NULL;
|
llvm::BasicBlock *ContinueBlock = NULL;
|
||||||
if (!BreakContinueStack.empty())
|
if (!BreakContinueStack.empty())
|
||||||
ContinueBlock = BreakContinueStack.back().ContinueBlock;
|
ContinueBlock = BreakContinueStack.back().ContinueBlock;
|
||||||
BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock,
|
BreakContinuePush(NextBlock, ContinueBlock);
|
||||||
ObjCEHStack.size()));
|
|
||||||
|
|
||||||
// Emit switch body.
|
// Emit switch body.
|
||||||
EmitStmt(S.getBody());
|
EmitStmt(S.getBody());
|
||||||
BreakContinueStack.pop_back();
|
BreakContinuePop();
|
||||||
|
|
||||||
// Update the default block in case explicit case range tests have
|
// Update the default block in case explicit case range tests have
|
||||||
// been chained on top.
|
// been chained on top.
|
||||||
|
|
|
@ -24,7 +24,7 @@ using namespace CodeGen;
|
||||||
|
|
||||||
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
|
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
|
||||||
: CGM(cgm), Target(CGM.getContext().Target), SwitchInsn(NULL),
|
: CGM(cgm), Target(CGM.getContext().Target), SwitchInsn(NULL),
|
||||||
CaseRangeBlock(NULL) {
|
CaseRangeBlock(NULL), StackDepth(0) {
|
||||||
LLVMIntTy = ConvertType(getContext().IntTy);
|
LLVMIntTy = ConvertType(getContext().IntTy);
|
||||||
LLVMPointerWidth = Target.getPointerWidth(0);
|
LLVMPointerWidth = Target.getPointerWidth(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,21 +144,36 @@ private:
|
||||||
/// until all AddrLabelExprs have been seen.
|
/// until all AddrLabelExprs have been seen.
|
||||||
std::vector<llvm::SwitchInst*> IndirectSwitches;
|
std::vector<llvm::SwitchInst*> IndirectSwitches;
|
||||||
|
|
||||||
/// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
|
/// LocalDeclMap - This keeps track of the LLVM allocas or globals for local
|
||||||
/// decls.
|
/// C decls.
|
||||||
llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
|
llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
|
||||||
|
|
||||||
/// LabelMap - This keeps track of the LLVM basic block for each C label.
|
/// LabelMap - This keeps track of the LLVM basic block for each C label.
|
||||||
llvm::DenseMap<const LabelStmt*, llvm::BasicBlock*> LabelMap;
|
llvm::DenseMap<const LabelStmt*, llvm::BasicBlock*> LabelMap;
|
||||||
|
|
||||||
|
/// BreakContinuePush - Note a new break and continue level.
|
||||||
|
void BreakContinuePush(llvm::BasicBlock *bb, llvm::BasicBlock *cb) {
|
||||||
|
BreakContinueStack.push_back(BreakContinue(bb, cb, StackDepth,
|
||||||
|
ObjCEHStack.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// BreakContinuePop - Note end of previous break and continue level.
|
||||||
|
void BreakContinuePop() {
|
||||||
|
BreakContinueStack.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
// BreakContinueStack - This keeps track of where break and continue
|
// BreakContinueStack - This keeps track of where break and continue
|
||||||
// statements should jump to, as well as the size of the eh stack.
|
// statements should jump to, as well as the depth of the stack and the size
|
||||||
|
// of the eh stack.
|
||||||
struct BreakContinue {
|
struct BreakContinue {
|
||||||
BreakContinue(llvm::BasicBlock *bb, llvm::BasicBlock *cb, size_t ehss)
|
BreakContinue(llvm::BasicBlock *bb, llvm::BasicBlock *cb,
|
||||||
: BreakBlock(bb), ContinueBlock(cb), EHStackSize(ehss) {}
|
llvm::Value *sd, size_t ehss)
|
||||||
|
: BreakBlock(bb), ContinueBlock(cb), SaveStackDepth(sd),
|
||||||
|
EHStackSize(ehss) {}
|
||||||
|
|
||||||
llvm::BasicBlock *BreakBlock;
|
llvm::BasicBlock *BreakBlock;
|
||||||
llvm::BasicBlock *ContinueBlock;
|
llvm::BasicBlock *ContinueBlock;
|
||||||
|
llvm::Value *SaveStackDepth;
|
||||||
size_t EHStackSize;
|
size_t EHStackSize;
|
||||||
};
|
};
|
||||||
llvm::SmallVector<BreakContinue, 8> BreakContinueStack;
|
llvm::SmallVector<BreakContinue, 8> BreakContinueStack;
|
||||||
|
@ -176,11 +191,23 @@ private:
|
||||||
// we enter/leave scopes.
|
// we enter/leave scopes.
|
||||||
llvm::DenseMap<const VariableArrayType*, llvm::Value*> VLASizeMap;
|
llvm::DenseMap<const VariableArrayType*, llvm::Value*> VLASizeMap;
|
||||||
|
|
||||||
|
/// StackDepth - This keeps track of the stack depth. It is used to
|
||||||
|
/// notice when control flow results in a change in stack depth and
|
||||||
|
/// to arrange for the appropriate stack depth to be restored.
|
||||||
|
llvm::Value *StackDepth;
|
||||||
|
|
||||||
/// StackSaveValues - A stack(!) of stack save values. When a new scope is
|
/// StackSaveValues - A stack(!) of stack save values. When a new scope is
|
||||||
/// entered, a null is pushed on this stack. If a VLA is emitted, then
|
/// entered, a null is pushed on this stack. If a VLA is emitted, then
|
||||||
/// the return value of llvm.stacksave() is stored at the top of this stack.
|
/// the return value of llvm.stacksave() is stored at the top of this stack.
|
||||||
llvm::SmallVector<llvm::Value*, 8> StackSaveValues;
|
llvm::SmallVector<llvm::Value*, 8> StackSaveValues;
|
||||||
|
|
||||||
|
llvm::DenseMap<const LabelStmt*, llvm::Value *> StackDepthMap;
|
||||||
|
|
||||||
|
/// EmitStackUpdate - Routine to adjust the stack to the depth the
|
||||||
|
/// stack should be at by the time we transfer control flow to the
|
||||||
|
/// label.
|
||||||
|
void EmitStackUpdate(const LabelStmt &S);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CodeGenFunction(CodeGenModule &cgm);
|
CodeGenFunction(CodeGenModule &cgm);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue