[svn r374] Move label target basic block from AST to IRFunction. This is a first step to allowing labels to be emitted multiple times. (for instance within finally blocks)

This commit is contained in:
Christian Kamm 2008-07-14 11:07:15 +02:00
parent 80ba763fda
commit 7e7ac3a6f7
5 changed files with 20 additions and 11 deletions

View file

@ -3883,7 +3883,6 @@ LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement)
this->enclosinghandler = NULL; this->enclosinghandler = NULL;
this->lblock = NULL; this->lblock = NULL;
this->isReturnLabel = 0; this->isReturnLabel = 0;
this->llvmBB = NULL;
this->asmLabel = false; this->asmLabel = false;
} }

View file

@ -871,7 +871,6 @@ struct LabelStatement : Statement
void toIR(IRState *irs); void toIR(IRState *irs);
// LLVMDC // LLVMDC
llvm::BasicBlock* llvmBB;
bool asmLabel; // for labels inside inline assembler bool asmLabel; // for labels inside inline assembler
}; };

View file

@ -186,8 +186,11 @@ void DtoGoto(Loc* loc, Identifier* target, EnclosingHandler* enclosinghandler)
if(lblstmt->asmLabel) if(lblstmt->asmLabel)
error("cannot goto into inline asm block", loc->toChars()); error("cannot goto into inline asm block", loc->toChars());
if (lblstmt->llvmBB == NULL) // find target basic block
lblstmt->llvmBB = llvm::BasicBlock::Create("label", gIR->topfunc()); std::string labelname = target->toChars();
llvm::BasicBlock*& targetBB = gIR->func()->labelToBB[labelname];
if (targetBB == NULL)
targetBB = llvm::BasicBlock::Create("label", gIR->topfunc());
// find finallys between goto and label // find finallys between goto and label
EnclosingHandler* endfinally = enclosinghandler; EnclosingHandler* endfinally = enclosinghandler;
@ -202,7 +205,7 @@ void DtoGoto(Loc* loc, Identifier* target, EnclosingHandler* enclosinghandler)
// emit code for finallys between goto and label // emit code for finallys between goto and label
DtoEnclosingHandlers(enclosinghandler, endfinally); DtoEnclosingHandlers(enclosinghandler, endfinally);
llvm::BranchInst::Create(lblstmt->llvmBB, gIR->scopebb()); llvm::BranchInst::Create(targetBB, gIR->scopebb());
} }
/****************************************************************************************/ /****************************************************************************************/

View file

@ -1033,16 +1033,20 @@ void LabelStatement::toIR(IRState* p)
} }
else else
{ {
std::string labelname = ident->toChars();
llvm::BasicBlock*& labelBB = p->func()->labelToBB[labelname];
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* oldend = gIR->scopeend();
if (llvmBB) if (labelBB != NULL) {
llvmBB->moveBefore(oldend); labelBB->moveBefore(oldend);
else } else {
llvmBB = llvm::BasicBlock::Create("label", p->topfunc(), oldend); labelBB = llvm::BasicBlock::Create("label", p->topfunc(), oldend);
}
if (!p->scopereturned()) if (!p->scopereturned())
llvm::BranchInst::Create(llvmBB, p->scopebb()); llvm::BranchInst::Create(labelBB, p->scopebb());
p->scope() = IRScope(llvmBB,oldend); p->scope() = IRScope(labelBB,oldend);
} }
if (statement) if (statement)

View file

@ -26,6 +26,10 @@ struct IrFunction : IrBase
llvm::AllocaInst* srcfileArg; llvm::AllocaInst* srcfileArg;
llvm::AllocaInst* msgArg; llvm::AllocaInst* msgArg;
// label to basic block lookup
typedef std::map<std::string, llvm::BasicBlock*> LabelToBBMap;
LabelToBBMap labelToBB;
// landing pads for try statements // landing pads for try statements
IRLandingPad landingPad; IRLandingPad landingPad;