Remove IRScope::end

Specifying the basic block before which to insert the new one
is not mandatory when calling llvm::BasicBlock::Create. This
was the only use of the tracked "end" block. The concept was
phony anyway because there is no single "end" to a scope with
unwinding and so on.

For prettying up the IR, it is possible to change the order
of basic blocks using move{Before, After}().
This commit is contained in:
David Nadlinger 2015-08-16 23:31:24 +02:00
parent f3a79f1215
commit bfc20df4c8
11 changed files with 150 additions and 230 deletions

View file

@ -81,9 +81,8 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
// Only check bounds for rvalues ('aa[key]'). // Only check bounds for rvalues ('aa[key]').
// Lvalue use ('aa[key] = value') auto-adds an element. // Lvalue use ('aa[key] = value') auto-adds an element.
if (!lvalue && gIR->emitArrayBoundsChecks()) { if (!lvalue && gIR->emitArrayBoundsChecks()) {
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* failbb = llvm::BasicBlock::Create(gIR->context(), "aaboundscheckfail", gIR->topfunc());
llvm::BasicBlock* failbb = llvm::BasicBlock::Create(gIR->context(), "aaboundscheckfail", gIR->topfunc(), oldend); llvm::BasicBlock* okbb = llvm::BasicBlock::Create(gIR->context(), "aaboundsok", gIR->topfunc());
llvm::BasicBlock* okbb = llvm::BasicBlock::Create(gIR->context(), "aaboundsok", gIR->topfunc(), oldend);
LLValue* nullaa = LLConstant::getNullValue(ret->getType()); LLValue* nullaa = LLConstant::getNullValue(ret->getType());
LLValue* cond = gIR->ir->CreateICmpNE(nullaa, ret, "aaboundscheck"); LLValue* cond = gIR->ir->CreateICmpNE(nullaa, ret, "aaboundscheck");
@ -91,7 +90,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
// set up failbb to call the array bounds error runtime function // set up failbb to call the array bounds error runtime function
gIR->scope() = IRScope(failbb, okbb); gIR->scope() = IRScope(failbb);
LLValue* args[] = { LLValue* args[] = {
// file param // file param
@ -108,7 +107,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
gIR->ir->CreateUnreachable(); gIR->ir->CreateUnreachable();
// if ok, proceed in okbb // if ok, proceed in okbb
gIR->scope() = IRScope(okbb, oldend); gIR->scope() = IRScope(okbb);
} }
return new DVarValue(type, ret); return new DVarValue(type, ret);
} }

View file

@ -141,13 +141,12 @@ static void DtoArrayInit(Loc& loc, LLValue* ptr, LLValue* length, DValue* dvalue
} }
// create blocks // create blocks
llvm::BasicBlock* oldend = gIR->scopeend();
llvm::BasicBlock* condbb = llvm::BasicBlock::Create(gIR->context(), "arrayinit.cond", llvm::BasicBlock* condbb = llvm::BasicBlock::Create(gIR->context(), "arrayinit.cond",
gIR->topfunc(), oldend); gIR->topfunc());
llvm::BasicBlock* bodybb = llvm::BasicBlock::Create(gIR->context(), "arrayinit.body", llvm::BasicBlock* bodybb = llvm::BasicBlock::Create(gIR->context(), "arrayinit.body",
gIR->topfunc(), oldend); gIR->topfunc());
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "arrayinit.end", llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "arrayinit.end",
gIR->topfunc(), oldend); gIR->topfunc());
// initialize iterator // initialize iterator
LLValue *itr = DtoAlloca(Type::tsize_t, "arrayinit.itr"); LLValue *itr = DtoAlloca(Type::tsize_t, "arrayinit.itr");
@ -158,7 +157,7 @@ static void DtoArrayInit(Loc& loc, LLValue* ptr, LLValue* length, DValue* dvalue
llvm::BranchInst::Create(condbb, gIR->scopebb()); llvm::BranchInst::Create(condbb, gIR->scopebb());
// replace current scope // replace current scope
gIR->scope() = IRScope(condbb,bodybb); gIR->scope() = IRScope(condbb);
// create the condition // create the condition
LLValue* cond_val = gIR->ir->CreateICmpNE(DtoLoad(itr), length, "arrayinit.condition"); LLValue* cond_val = gIR->ir->CreateICmpNE(DtoLoad(itr), length, "arrayinit.condition");
@ -168,7 +167,7 @@ static void DtoArrayInit(Loc& loc, LLValue* ptr, LLValue* length, DValue* dvalue
llvm::BranchInst::Create(bodybb, endbb, cond_val, gIR->scopebb()); llvm::BranchInst::Create(bodybb, endbb, cond_val, gIR->scopebb());
// rewrite scope // rewrite scope
gIR->scope() = IRScope(bodybb, endbb); gIR->scope() = IRScope(bodybb);
LLValue* itr_val = DtoLoad(itr); LLValue* itr_val = DtoLoad(itr);
/* bitcopy element /* bitcopy element
@ -185,7 +184,7 @@ static void DtoArrayInit(Loc& loc, LLValue* ptr, LLValue* length, DValue* dvalue
llvm::BranchInst::Create(condbb, gIR->scopebb()); llvm::BranchInst::Create(condbb, gIR->scopebb());
// rewrite the scope // rewrite the scope
gIR->scope() = IRScope(endbb, oldend); gIR->scope() = IRScope(endbb);
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -1213,9 +1212,8 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, DValue* lowerBoun
bool lengthUnknown = arrty->ty == Tpointer; bool lengthUnknown = arrty->ty == Tpointer;
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* failbb = llvm::BasicBlock::Create(gIR->context(), "arrayboundscheckfail", gIR->topfunc());
llvm::BasicBlock* failbb = llvm::BasicBlock::Create(gIR->context(), "arrayboundscheckfail", gIR->topfunc(), oldend); llvm::BasicBlock* okbb = llvm::BasicBlock::Create(gIR->context(), "arrayboundsok", gIR->topfunc());
llvm::BasicBlock* okbb = llvm::BasicBlock::Create(gIR->context(), "arrayboundsok", gIR->topfunc(), oldend);
LLValue* cond = 0; LLValue* cond = 0;
if (!lengthUnknown) { if (!lengthUnknown) {
@ -1230,9 +1228,9 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, DValue* lowerBoun
gIR->ir->CreateCondBr(cond, okbb, failbb); gIR->ir->CreateCondBr(cond, okbb, failbb);
} else { } else {
if (!lengthUnknown) { if (!lengthUnknown) {
llvm::BasicBlock* locheckbb = llvm::BasicBlock::Create(gIR->context(), "arrayboundschecklowerbound", gIR->topfunc(), oldend); llvm::BasicBlock* locheckbb = llvm::BasicBlock::Create(gIR->context(), "arrayboundschecklowerbound", gIR->topfunc());
gIR->ir->CreateCondBr(cond, locheckbb, failbb); gIR->ir->CreateCondBr(cond, locheckbb, failbb);
gIR->scope() = IRScope(locheckbb, failbb); gIR->scope() = IRScope(locheckbb);
} }
// check for lower bound // check for lower bound
cond = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_ULE, lowerBound->getRVal(), index->getRVal(), "boundscheck"); cond = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_ULE, lowerBound->getRVal(), index->getRVal(), "boundscheck");
@ -1241,7 +1239,7 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, DValue* lowerBoun
// set up failbb to call the array bounds error runtime function // set up failbb to call the array bounds error runtime function
gIR->scope() = IRScope(failbb, okbb); gIR->scope() = IRScope(failbb);
std::vector<LLValue*> args; std::vector<LLValue*> args;
@ -1261,5 +1259,5 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, DValue* lowerBoun
gIR->ir->CreateUnreachable(); gIR->ir->CreateUnreachable();
// if ok, proceed in okbb // if ok, proceed in okbb
gIR->scope() = IRScope(okbb, oldend); gIR->scope() = IRScope(okbb);
} }

View file

@ -733,8 +733,7 @@ void CompoundAsmStatement_toIR(CompoundAsmStatement *stmt, IRState* p)
assert(jump_target); assert(jump_target);
// make new blocks // make new blocks
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "afterasmgotoforwarder", p->topfunc());
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "afterasmgotoforwarder", p->topfunc(), oldend);
llvm::LoadInst* val = p->ir->CreateLoad(jump_target, "__llvm_jump_target_value"); llvm::LoadInst* val = p->ir->CreateLoad(jump_target, "__llvm_jump_target_value");
llvm::SwitchInst* sw = p->ir->CreateSwitch(val, bb, gotoToVal.size()); llvm::SwitchInst* sw = p->ir->CreateSwitch(val, bb, gotoToVal.size());
@ -746,11 +745,11 @@ void CompoundAsmStatement_toIR(CompoundAsmStatement *stmt, IRState* p)
llvm::BasicBlock* casebb = llvm::BasicBlock::Create(gIR->context(), "case", p->topfunc(), bb); llvm::BasicBlock* casebb = llvm::BasicBlock::Create(gIR->context(), "case", p->topfunc(), bb);
sw->addCase(LLConstantInt::get(llvm::IntegerType::get(gIR->context(), 32), it->second), casebb); sw->addCase(LLConstantInt::get(llvm::IntegerType::get(gIR->context(), 32), it->second), casebb);
p->scope() = IRScope(casebb,bb); p->scope() = IRScope(casebb);
DtoGoto(stmt->loc, it->first, stmt->enclosingFinally); DtoGoto(stmt->loc, it->first, stmt->enclosingFinally);
} }
p->scope() = IRScope(bb,oldend); p->scope() = IRScope(bb);
} }
} }

View file

@ -794,10 +794,9 @@ void DtoDefineFunction(FuncDeclaration* fd)
#endif #endif
llvm::BasicBlock* beginbb = llvm::BasicBlock::Create(gIR->context(), "", func); llvm::BasicBlock* beginbb = llvm::BasicBlock::Create(gIR->context(), "", func);
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endentry", func);
//assert(gIR->scopes.empty()); //assert(gIR->scopes.empty());
gIR->scopes.push_back(IRScope(beginbb, endbb)); gIR->scopes.push_back(IRScope(beginbb));
// create alloca point // create alloca point
// this gets erased when the function is complete, so alignment etc does not matter at all // this gets erased when the function is complete, so alignment etc does not matter at all
@ -957,10 +956,6 @@ void DtoDefineFunction(FuncDeclaration* fd)
gIR->scopes.pop_back(); gIR->scopes.pop_back();
// get rid of the endentry block, it's never used
assert(!func->getBasicBlockList().empty());
func->getBasicBlockList().pop_back();
gIR->functions.pop_back(); gIR->functions.pop_back();
} }

View file

@ -28,20 +28,15 @@ TargetABI* gABI = 0;
IRScope::IRScope() IRScope::IRScope()
: builder(gIR->context()) : builder(gIR->context())
{ {
begin = end = NULL; begin = NULL;
} }
IRScope::IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e) IRScope::IRScope(llvm::BasicBlock* b)
: builder(b) : begin(b), builder(b) {}
{
begin = b;
end = e;
}
const IRScope& IRScope::operator=(const IRScope& rhs) const IRScope& IRScope::operator=(const IRScope& rhs)
{ {
begin = rhs.begin; begin = rhs.begin;
end = rhs.end;
builder.SetInsertPoint(begin); builder.SetInsertPoint(begin);
return *this; return *this;
} }
@ -106,12 +101,7 @@ llvm::BasicBlock* IRState::scopebb()
assert(s.begin); assert(s.begin);
return s.begin; return s.begin;
} }
llvm::BasicBlock* IRState::scopeend()
{
IRScope& s = scope();
assert(s.end);
return s.end;
}
bool IRState::scopereturned() bool IRState::scopereturned()
{ {
//return scope().returned; //return scope().returned;

View file

@ -66,11 +66,10 @@ struct IrModule;
struct IRScope struct IRScope
{ {
llvm::BasicBlock* begin; llvm::BasicBlock* begin;
llvm::BasicBlock* end;
IRBuilder<> builder; IRBuilder<> builder;
IRScope(); IRScope();
IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e); explicit IRScope(llvm::BasicBlock* b);
const IRScope& operator=(const IRScope& rhs); const IRScope& operator=(const IRScope& rhs);
}; };
@ -146,7 +145,6 @@ struct IRState
std::vector<IRScope> scopes; std::vector<IRScope> scopes;
IRScope& scope(); IRScope& scope();
llvm::BasicBlock* scopebb(); llvm::BasicBlock* scopebb();
llvm::BasicBlock* scopeend();
bool scopereturned(); bool scopereturned();
// create a call or invoke, depending on the landing pad info // create a call or invoke, depending on the landing pad info
@ -230,7 +228,7 @@ llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, const T &args, const
if (hasTemporaries) if (hasTemporaries)
funcGen.landingPadInfo.pop(); funcGen.landingPadInfo.pop();
scope() = IRScope(postinvoke, landingPad); scope() = IRScope(postinvoke);
return invoke; return invoke;
} }

View file

@ -483,9 +483,8 @@ public:
} }
// the return terminated this basicblock, start a new one // the return terminated this basicblock, start a new one
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "afterreturn", irs->topfunc());
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "afterreturn", irs->topfunc(), oldend); irs->scope() = IRScope(bb);
irs->scope() = IRScope(bb, oldend);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -528,10 +527,8 @@ public:
DValue* cond_e = toElemDtor(stmt->condition); DValue* cond_e = toElemDtor(stmt->condition);
LLValue* cond_val = cond_e->getRVal(); LLValue* cond_val = cond_e->getRVal();
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* ifbb = llvm::BasicBlock::Create(gIR->context(), "if", gIR->topfunc());
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endif", gIR->topfunc());
llvm::BasicBlock* ifbb = llvm::BasicBlock::Create(gIR->context(), "if", gIR->topfunc(), oldend);
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endif", gIR->topfunc(), oldend);
llvm::BasicBlock* elsebb = stmt->elsebody ? llvm::BasicBlock::Create(gIR->context(), "else", gIR->topfunc(), endbb) : endbb; llvm::BasicBlock* elsebb = stmt->elsebody ? llvm::BasicBlock::Create(gIR->context(), "else", gIR->topfunc(), endbb) : endbb;
if (cond_val->getType() != LLType::getInt1Ty(gIR->context())) { if (cond_val->getType() != LLType::getInt1Ty(gIR->context())) {
@ -541,7 +538,7 @@ public:
llvm::BranchInst::Create(ifbb, elsebb, cond_val, gIR->scopebb()); llvm::BranchInst::Create(ifbb, elsebb, cond_val, gIR->scopebb());
// replace current scope // replace current scope
gIR->scope() = IRScope(ifbb, elsebb); gIR->scope() = IRScope(ifbb);
// do scoped statements // do scoped statements
@ -555,7 +552,7 @@ public:
} }
if (stmt->elsebody) { if (stmt->elsebody) {
gIR->scope() = IRScope(elsebb, endbb); gIR->scope() = IRScope(elsebb);
gIR->DBuilder.EmitBlockStart(stmt->elsebody->loc); gIR->DBuilder.EmitBlockStart(stmt->elsebody->loc);
stmt->elsebody->accept(this); stmt->elsebody->accept(this);
if (!gIR->scopereturned()) { if (!gIR->scopereturned()) {
@ -568,7 +565,7 @@ public:
gIR->DBuilder.EmitBlockEnd(); gIR->DBuilder.EmitBlockEnd();
// rewrite the scope // rewrite the scope
gIR->scope() = IRScope(endbb, oldend); gIR->scope() = IRScope(endbb);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -577,36 +574,11 @@ public:
IF_LOG Logger::println("ScopeStatement::toIR(): %s", stmt->loc.toChars()); IF_LOG Logger::println("ScopeStatement::toIR(): %s", stmt->loc.toChars());
LOG_SCOPE; LOG_SCOPE;
/*llvm::BasicBlock* oldend = p->scopeend();
llvm::BasicBlock* beginbb = 0;
// remove useless branches by clearing and reusing the current basicblock
llvm::BasicBlock* bb = p->scopebb();
if (bb->empty()) {
beginbb = bb;
}
else {
beginbb = llvm::BasicBlock::Create(gIR->context(), "scope", p->topfunc(), oldend);
if (!p->scopereturned())
llvm::BranchInst::Create(beginbb, bb);
}
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endscope", p->topfunc(), oldend);
if (beginbb != bb)
p->scope() = IRScope(beginbb, endbb);
else
p->scope().end = endbb;*/
if (stmt->statement) { if (stmt->statement) {
gIR->DBuilder.EmitBlockStart(stmt->statement->loc); gIR->DBuilder.EmitBlockStart(stmt->statement->loc);
stmt->statement->accept(this); stmt->statement->accept(this);
gIR->DBuilder.EmitBlockEnd(); gIR->DBuilder.EmitBlockEnd();
} }
/*p->scope().end = oldend;
Logger::println("Erasing scope endbb");
endbb->eraseFromParent();*/
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -619,17 +591,16 @@ public:
gIR->DBuilder.EmitBlockStart(stmt->loc); gIR->DBuilder.EmitBlockStart(stmt->loc);
// create while blocks // create while blocks
llvm::BasicBlock* oldend = gIR->scopeend();
llvm::BasicBlock* whilebb = llvm::BasicBlock::Create(gIR->context(), "whilecond", gIR->topfunc(), oldend); llvm::BasicBlock* whilebb = llvm::BasicBlock::Create(gIR->context(), "whilecond", gIR->topfunc());
llvm::BasicBlock* whilebodybb = llvm::BasicBlock::Create(gIR->context(), "whilebody", gIR->topfunc(), oldend); llvm::BasicBlock* whilebodybb = llvm::BasicBlock::Create(gIR->context(), "whilebody", gIR->topfunc());
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endwhile", gIR->topfunc(), oldend); llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endwhile", gIR->topfunc());
// move into the while block // move into the while block
irs->ir->CreateBr(whilebb); irs->ir->CreateBr(whilebb);
//llvm::BranchInst::Create(whilebb, gIR->scopebb());
// replace current scope // replace current scope
gIR->scope() = IRScope(whilebb, endbb); gIR->scope() = IRScope(whilebb);
// create the condition // create the condition
emitCoverageLinecountInc(stmt->condition->loc); emitCoverageLinecountInc(stmt->condition->loc);
@ -641,7 +612,7 @@ public:
llvm::BranchInst::Create(whilebodybb, endbb, cond_val, irs->scopebb()); llvm::BranchInst::Create(whilebodybb, endbb, cond_val, irs->scopebb());
// rewrite scope // rewrite scope
gIR->scope() = IRScope(whilebodybb, endbb); gIR->scope() = IRScope(whilebodybb);
// while body code // while body code
irs->func()->gen->targetScopes.push_back(IRTargetScope(stmt, NULL, whilebb, endbb)); irs->func()->gen->targetScopes.push_back(IRTargetScope(stmt, NULL, whilebb, endbb));
@ -654,7 +625,7 @@ public:
llvm::BranchInst::Create(whilebb, gIR->scopebb()); llvm::BranchInst::Create(whilebb, gIR->scopebb());
// rewrite the scope // rewrite the scope
gIR->scope() = IRScope(endbb, oldend); gIR->scope() = IRScope(endbb);
// end the dwarf lexical block // end the dwarf lexical block
gIR->DBuilder.EmitBlockEnd(); gIR->DBuilder.EmitBlockEnd();
@ -670,17 +641,16 @@ public:
gIR->DBuilder.EmitBlockStart(stmt->loc); gIR->DBuilder.EmitBlockStart(stmt->loc);
// create while blocks // create while blocks
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* dowhilebb = llvm::BasicBlock::Create(gIR->context(), "dowhile", gIR->topfunc());
llvm::BasicBlock* dowhilebb = llvm::BasicBlock::Create(gIR->context(), "dowhile", gIR->topfunc(), oldend); llvm::BasicBlock* condbb = llvm::BasicBlock::Create(gIR->context(), "dowhilecond", gIR->topfunc());
llvm::BasicBlock* condbb = llvm::BasicBlock::Create(gIR->context(), "dowhilecond", gIR->topfunc(), oldend); llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "enddowhile", gIR->topfunc());
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "enddowhile", gIR->topfunc(), oldend);
// move into the while block // move into the while block
assert(!gIR->scopereturned()); assert(!gIR->scopereturned());
llvm::BranchInst::Create(dowhilebb, gIR->scopebb()); llvm::BranchInst::Create(dowhilebb, gIR->scopebb());
// replace current scope // replace current scope
gIR->scope() = IRScope(dowhilebb, condbb); gIR->scope() = IRScope(dowhilebb);
// do-while body code // do-while body code
irs->func()->gen->targetScopes.push_back(IRTargetScope(stmt, NULL, condbb, endbb)); irs->func()->gen->targetScopes.push_back(IRTargetScope(stmt, NULL, condbb, endbb));
@ -690,7 +660,7 @@ public:
// branch to condition block // branch to condition block
llvm::BranchInst::Create(condbb, gIR->scopebb()); llvm::BranchInst::Create(condbb, gIR->scopebb());
gIR->scope() = IRScope(condbb,endbb); gIR->scope() = IRScope(condbb);
// create the condition // create the condition
emitCoverageLinecountInc(stmt->condition->loc); emitCoverageLinecountInc(stmt->condition->loc);
@ -702,7 +672,7 @@ public:
llvm::BranchInst::Create(dowhilebb, endbb, cond_val, gIR->scopebb()); llvm::BranchInst::Create(dowhilebb, endbb, cond_val, gIR->scopebb());
// rewrite the scope // rewrite the scope
gIR->scope() = IRScope(endbb, oldend); gIR->scope() = IRScope(endbb);
// end the dwarf lexical block // end the dwarf lexical block
gIR->DBuilder.EmitBlockEnd(); gIR->DBuilder.EmitBlockEnd();
@ -718,11 +688,10 @@ public:
gIR->DBuilder.EmitBlockStart(stmt->loc); gIR->DBuilder.EmitBlockStart(stmt->loc);
// create for blocks // create for blocks
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* forbb = llvm::BasicBlock::Create(gIR->context(), "forcond", gIR->topfunc());
llvm::BasicBlock* forbb = llvm::BasicBlock::Create(gIR->context(), "forcond", gIR->topfunc(), oldend); llvm::BasicBlock* forbodybb = llvm::BasicBlock::Create(gIR->context(), "forbody", gIR->topfunc());
llvm::BasicBlock* forbodybb = llvm::BasicBlock::Create(gIR->context(), "forbody", gIR->topfunc(), oldend); llvm::BasicBlock* forincbb = llvm::BasicBlock::Create(gIR->context(), "forinc", gIR->topfunc());
llvm::BasicBlock* forincbb = llvm::BasicBlock::Create(gIR->context(), "forinc", gIR->topfunc(), oldend); llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endfor", gIR->topfunc());
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endfor", gIR->topfunc(), oldend);
// init // init
if (stmt->init != 0) if (stmt->init != 0)
@ -744,7 +713,7 @@ public:
scopeStart, NULL, forincbb, endbb)); scopeStart, NULL, forincbb, endbb));
// replace current scope // replace current scope
gIR->scope() = IRScope(forbb, forbodybb); gIR->scope() = IRScope(forbb);
// create the condition // create the condition
llvm::Value* cond_val; llvm::Value* cond_val;
@ -765,7 +734,7 @@ public:
llvm::BranchInst::Create(forbodybb, endbb, cond_val, gIR->scopebb()); llvm::BranchInst::Create(forbodybb, endbb, cond_val, gIR->scopebb());
// rewrite scope // rewrite scope
gIR->scope() = IRScope(forbodybb, forincbb); gIR->scope() = IRScope(forbodybb);
// do for body code // do for body code
if (stmt->body) if (stmt->body)
@ -774,7 +743,7 @@ public:
// move into the for increment block // move into the for increment block
if (!gIR->scopereturned()) if (!gIR->scopereturned())
llvm::BranchInst::Create(forincbb, gIR->scopebb()); llvm::BranchInst::Create(forincbb, gIR->scopebb());
gIR->scope() = IRScope(forincbb, endbb); gIR->scope() = IRScope(forincbb);
// increment // increment
if (stmt->increment) { if (stmt->increment) {
@ -790,7 +759,7 @@ public:
irs->func()->gen->targetScopes.pop_back(); irs->func()->gen->targetScopes.pop_back();
// rewrite the scope // rewrite the scope
gIR->scope() = IRScope(endbb, oldend); gIR->scope() = IRScope(endbb);
// end the dwarf lexical block // end the dwarf lexical block
gIR->DBuilder.EmitBlockEnd(); gIR->DBuilder.EmitBlockEnd();
@ -859,9 +828,8 @@ public:
} }
// the break terminated this basicblock, start a new one // the break terminated this basicblock, start a new one
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "afterbreak", irs->topfunc());
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "afterbreak", irs->topfunc(), oldend); irs->scope() = IRScope(bb);
irs->scope() = IRScope(bb, oldend);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -917,9 +885,8 @@ public:
} }
// the continue terminated this basicblock, start a new one // the continue terminated this basicblock, start a new one
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftercontinue", irs->topfunc());
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftercontinue", irs->topfunc(), oldend); irs->scope() = IRScope(bb);
irs->scope() = IRScope(bb, oldend);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -955,13 +922,11 @@ public:
} }
// create basic blocks // create basic blocks
llvm::BasicBlock* oldend = irs->scopeend(); llvm::BasicBlock* trybb = llvm::BasicBlock::Create(gIR->context(), "try", irs->topfunc());
llvm::BasicBlock* finallybb = llvm::BasicBlock::Create(gIR->context(), "finally", irs->topfunc());
llvm::BasicBlock* trybb = llvm::BasicBlock::Create(gIR->context(), "try", irs->topfunc(), oldend);
llvm::BasicBlock* finallybb = llvm::BasicBlock::Create(gIR->context(), "finally", irs->topfunc(), oldend);
// the landing pad for statements in the try block // the landing pad for statements in the try block
llvm::BasicBlock* landingpadbb = llvm::BasicBlock::Create(gIR->context(), "landingpad", irs->topfunc(), oldend); llvm::BasicBlock* landingpadbb = llvm::BasicBlock::Create(gIR->context(), "landingpad", irs->topfunc());
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endtryfinally", irs->topfunc(), oldend); llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endtryfinally", irs->topfunc());
// pass the previous BB into this // pass the previous BB into this
assert(!gIR->scopereturned()); assert(!gIR->scopereturned());
@ -970,7 +935,7 @@ public:
// //
// set up the landing pad // set up the landing pad
// //
irs->scope() = IRScope(landingpadbb, endbb); irs->scope() = IRScope(landingpadbb);
assert(stmt->finalbody); assert(stmt->finalbody);
IRLandingPad& pad = gIR->func()->gen->landingPadInfo; IRLandingPad& pad = gIR->func()->gen->landingPadInfo;
@ -989,7 +954,7 @@ public:
// //
// do the try block // do the try block
// //
irs->scope() = IRScope(trybb, finallybb); irs->scope() = IRScope(trybb);
assert(stmt->body); assert(stmt->body);
gIR->DBuilder.EmitBlockStart(stmt->body->loc); gIR->DBuilder.EmitBlockStart(stmt->body->loc);
@ -1006,7 +971,7 @@ public:
// //
// do finally block // do finally block
// //
irs->scope() = IRScope(finallybb, landingpadbb); irs->scope() = IRScope(finallybb);
gIR->DBuilder.EmitBlockStart(stmt->finalbody->loc); gIR->DBuilder.EmitBlockStart(stmt->finalbody->loc);
stmt->finalbody->accept(this); stmt->finalbody->accept(this);
gIR->DBuilder.EmitBlockEnd(); gIR->DBuilder.EmitBlockEnd();
@ -1018,7 +983,7 @@ public:
} }
// rewrite the scope // rewrite the scope
irs->scope() = IRScope(endbb, oldend); irs->scope() = IRScope(endbb);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -1031,12 +996,10 @@ public:
gIR->DBuilder.EmitStopPoint(stmt->loc); gIR->DBuilder.EmitStopPoint(stmt->loc);
// create basic blocks // create basic blocks
llvm::BasicBlock* oldend = irs->scopeend(); llvm::BasicBlock* trybb = llvm::BasicBlock::Create(gIR->context(), "try", irs->topfunc());
llvm::BasicBlock* trybb = llvm::BasicBlock::Create(gIR->context(), "try", irs->topfunc(), oldend);
// the landing pad will be responsible for branching to the correct catch block // the landing pad will be responsible for branching to the correct catch block
llvm::BasicBlock* landingpadbb = llvm::BasicBlock::Create(gIR->context(), "landingpad", irs->topfunc(), oldend); llvm::BasicBlock* landingpadbb = llvm::BasicBlock::Create(gIR->context(), "landingpad", irs->topfunc());
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endtrycatch", irs->topfunc(), oldend); llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endtrycatch", irs->topfunc());
// pass the previous BB into this // pass the previous BB into this
assert(!gIR->scopereturned()); assert(!gIR->scopereturned());
@ -1046,7 +1009,7 @@ public:
// set up the landing pad // set up the landing pad
// //
assert(stmt->catches); assert(stmt->catches);
gIR->scope() = IRScope(landingpadbb, endbb); gIR->scope() = IRScope(landingpadbb);
IRLandingPad& pad = gIR->func()->gen->landingPadInfo; IRLandingPad& pad = gIR->func()->gen->landingPadInfo;
for (Catches::iterator I = stmt->catches->begin(), for (Catches::iterator I = stmt->catches->begin(),
@ -1062,7 +1025,7 @@ public:
// //
// do the try block // do the try block
// //
irs->scope() = IRScope(trybb, landingpadbb); irs->scope() = IRScope(trybb);
assert(stmt->body); assert(stmt->body);
gIR->DBuilder.EmitBlockStart(stmt->body->loc); gIR->DBuilder.EmitBlockStart(stmt->body->loc);
@ -1075,7 +1038,7 @@ public:
pad.pop(); pad.pop();
// rewrite the scope // rewrite the scope
irs->scope() = IRScope(endbb, oldend); irs->scope() = IRScope(endbb);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -1100,9 +1063,8 @@ public:
gIR->ir->CreateUnreachable(); gIR->ir->CreateUnreachable();
// need a block after the throw for now // need a block after the throw for now
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "afterthrow", irs->topfunc());
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "afterthrow", irs->topfunc(), oldend); irs->scope() = IRScope(bb);
irs->scope() = IRScope(bb, oldend);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -1117,7 +1079,6 @@ public:
emitCoverageLinecountInc(stmt->loc); emitCoverageLinecountInc(stmt->loc);
llvm::BasicBlock* oldbb = gIR->scopebb(); llvm::BasicBlock* oldbb = gIR->scopebb();
llvm::BasicBlock* oldend = gIR->scopeend();
// clear data from previous passes... :/ // clear data from previous passes... :/
for (CaseStatements::iterator I = stmt->cases->begin(), for (CaseStatements::iterator I = stmt->cases->begin(),
@ -1149,29 +1110,29 @@ public:
// body block. // body block.
// FIXME: that block is never used // FIXME: that block is never used
llvm::BasicBlock* bodybb = llvm::BasicBlock::Create(gIR->context(), "switchbody", irs->topfunc(), oldend); llvm::BasicBlock* bodybb = llvm::BasicBlock::Create(gIR->context(), "switchbody", irs->topfunc());
// default // default
llvm::BasicBlock* defbb = 0; llvm::BasicBlock* defbb = 0;
if (stmt->sdefault) { if (stmt->sdefault) {
Logger::println("has default"); Logger::println("has default");
defbb = llvm::BasicBlock::Create(gIR->context(), "default", irs->topfunc(), oldend); defbb = llvm::BasicBlock::Create(gIR->context(), "default", irs->topfunc());
stmt->sdefault->bodyBB = defbb; stmt->sdefault->bodyBB = defbb;
} }
// end (break point) // end (break point)
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "switchend", irs->topfunc(), oldend); llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "switchend", irs->topfunc());
// do switch body // do switch body
assert(stmt->body); assert(stmt->body);
irs->scope() = IRScope(bodybb, endbb); irs->scope() = IRScope(bodybb);
irs->func()->gen->targetScopes.push_back(IRTargetScope(stmt, NULL, NULL, endbb)); irs->func()->gen->targetScopes.push_back(IRTargetScope(stmt, NULL, NULL, endbb));
stmt->body->accept(this); stmt->body->accept(this);
irs->func()->gen->targetScopes.pop_back(); irs->func()->gen->targetScopes.pop_back();
if (!irs->scopereturned()) if (!irs->scopereturned())
llvm::BranchInst::Create(endbb, irs->scopebb()); llvm::BranchInst::Create(endbb, irs->scopebb());
gIR->scope() = IRScope(oldbb, oldend); gIR->scope() = IRScope(oldbb);
if (useSwitchInst) if (useSwitchInst)
{ {
// string switch? // string switch?
@ -1243,10 +1204,10 @@ public:
DValue* cond = toElemDtor(stmt->condition); DValue* cond = toElemDtor(stmt->condition);
LLValue *condVal = cond->getRVal(); LLValue *condVal = cond->getRVal();
llvm::BasicBlock* nextbb = llvm::BasicBlock::Create(gIR->context(), "checkcase", irs->topfunc(), oldend); llvm::BasicBlock* nextbb = llvm::BasicBlock::Create(gIR->context(), "checkcase", irs->topfunc());
llvm::BranchInst::Create(nextbb, irs->scopebb()); llvm::BranchInst::Create(nextbb, irs->scopebb());
irs->scope() = IRScope(nextbb, endbb); irs->scope() = IRScope(nextbb);
for (CaseStatements::iterator I = stmt->cases->begin(), for (CaseStatements::iterator I = stmt->cases->begin(),
E = stmt->cases->end(); E = stmt->cases->end();
I != E; ++I) I != E; ++I)
@ -1254,9 +1215,9 @@ public:
CaseStatement *cs = *I; CaseStatement *cs = *I;
LLValue *cmp = irs->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ, cs->llvmIdx, condVal, "checkcase"); LLValue *cmp = irs->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ, cs->llvmIdx, condVal, "checkcase");
nextbb = llvm::BasicBlock::Create(gIR->context(), "checkcase", irs->topfunc(), oldend); nextbb = llvm::BasicBlock::Create(gIR->context(), "checkcase", irs->topfunc());
llvm::BranchInst::Create(cs->bodyBB, nextbb, cmp, irs->scopebb()); llvm::BranchInst::Create(cs->bodyBB, nextbb, cmp, irs->scopebb());
irs->scope() = IRScope(nextbb, endbb); irs->scope() = IRScope(nextbb);
} }
if (stmt->sdefault) { if (stmt->sdefault) {
@ -1267,7 +1228,7 @@ public:
endbb->moveAfter(nextbb); endbb->moveAfter(nextbb);
} }
gIR->scope() = IRScope(endbb, oldend); gIR->scope() = IRScope(endbb);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -1276,8 +1237,7 @@ public:
IF_LOG Logger::println("CaseStatement::toIR(): %s", stmt->loc.toChars()); IF_LOG Logger::println("CaseStatement::toIR(): %s", stmt->loc.toChars());
LOG_SCOPE; LOG_SCOPE;
llvm::BasicBlock* nbb = llvm::BasicBlock::Create(gIR->context(), "case", irs->topfunc(), irs->scopeend()); llvm::BasicBlock* nbb = llvm::BasicBlock::Create(gIR->context(), "case", irs->topfunc());
if (stmt->bodyBB && !stmt->bodyBB->getTerminator()) if (stmt->bodyBB && !stmt->bodyBB->getTerminator())
{ {
llvm::BranchInst::Create(nbb, stmt->bodyBB); llvm::BranchInst::Create(nbb, stmt->bodyBB);
@ -1292,7 +1252,7 @@ public:
if (!irs->scopereturned()) if (!irs->scopereturned())
llvm::BranchInst::Create(stmt->bodyBB, irs->scopebb()); llvm::BranchInst::Create(stmt->bodyBB, irs->scopebb());
irs->scope() = IRScope(stmt->bodyBB, irs->scopeend()); irs->scope() = IRScope(stmt->bodyBB);
assert(stmt->statement); assert(stmt->statement);
gIR->DBuilder.EmitBlockStart(stmt->statement->loc); gIR->DBuilder.EmitBlockStart(stmt->statement->loc);
@ -1309,7 +1269,7 @@ public:
assert(stmt->bodyBB); assert(stmt->bodyBB);
llvm::BasicBlock* nbb = llvm::BasicBlock::Create(gIR->context(), "default", irs->topfunc(), irs->scopeend()); llvm::BasicBlock* nbb = llvm::BasicBlock::Create(gIR->context(), "default", irs->topfunc());
if (!stmt->bodyBB->getTerminator()) if (!stmt->bodyBB->getTerminator())
{ {
@ -1320,7 +1280,7 @@ public:
if (!irs->scopereturned()) if (!irs->scopereturned())
llvm::BranchInst::Create(stmt->bodyBB, irs->scopebb()); llvm::BranchInst::Create(stmt->bodyBB, irs->scopebb());
irs->scope() = IRScope(stmt->bodyBB, irs->scopeend()); irs->scope() = IRScope(stmt->bodyBB);
assert(stmt->statement); assert(stmt->statement);
gIR->DBuilder.EmitBlockStart(stmt->statement->loc); gIR->DBuilder.EmitBlockStart(stmt->statement->loc);
@ -1345,19 +1305,17 @@ public:
// DMD doesn't fold stuff like continue/break, and since this isn't really a loop // DMD doesn't fold stuff like continue/break, and since this isn't really a loop
// we have to keep track of each statement and jump to the next/end on continue/break // we have to keep track of each statement and jump to the next/end on continue/break
llvm::BasicBlock* oldend = gIR->scopeend();
// create a block for each statement // create a block for each statement
size_t nstmt = stmt->statements->dim; size_t nstmt = stmt->statements->dim;
llvm::SmallVector<llvm::BasicBlock*, 4> blocks(nstmt, NULL); llvm::SmallVector<llvm::BasicBlock*, 4> blocks(nstmt, NULL);
for (size_t i=0; i < nstmt; i++) for (size_t i=0; i < nstmt; i++)
{ {
blocks[i] = llvm::BasicBlock::Create(gIR->context(), "unrolledstmt", irs->topfunc(), oldend); blocks[i] = llvm::BasicBlock::Create(gIR->context(), "unrolledstmt", irs->topfunc());
} }
// create end block // create end block
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "unrolledend", irs->topfunc(), oldend); llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "unrolledend", irs->topfunc());
// enter first stmt // enter first stmt
if (!irs->scopereturned()) if (!irs->scopereturned())
@ -1375,7 +1333,7 @@ public:
llvm::BasicBlock* nextbb = (i+1 == nstmt) ? endbb : blocks[i+1]; llvm::BasicBlock* nextbb = (i+1 == nstmt) ? endbb : blocks[i+1];
// update scope // update scope
irs->scope() = IRScope(thisbb, nextbb); irs->scope() = IRScope(thisbb);
// push loop scope // push loop scope
// continue goes to next statement, break goes to end // continue goes to next statement, break goes to end
@ -1395,7 +1353,7 @@ public:
// finish scope // finish scope
if (!irs->scopereturned()) if (!irs->scopereturned())
irs->ir->CreateBr(endbb); irs->ir->CreateBr(endbb);
irs->scope() = IRScope(endbb, oldend); irs->scope() = IRScope(endbb);
// end the dwarf lexical block // end the dwarf lexical block
gIR->DBuilder.EmitBlockEnd(); gIR->DBuilder.EmitBlockEnd();
@ -1464,16 +1422,15 @@ public:
new llvm::StoreInst(niters, keyvar, irs->scopebb()); new llvm::StoreInst(niters, keyvar, irs->scopebb());
} }
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* condbb = llvm::BasicBlock::Create(gIR->context(), "foreachcond", irs->topfunc());
llvm::BasicBlock* condbb = llvm::BasicBlock::Create(gIR->context(), "foreachcond", irs->topfunc(), oldend); llvm::BasicBlock* bodybb = llvm::BasicBlock::Create(gIR->context(), "foreachbody", irs->topfunc());
llvm::BasicBlock* bodybb = llvm::BasicBlock::Create(gIR->context(), "foreachbody", irs->topfunc(), oldend); llvm::BasicBlock* nextbb = llvm::BasicBlock::Create(gIR->context(), "foreachnext", irs->topfunc());
llvm::BasicBlock* nextbb = llvm::BasicBlock::Create(gIR->context(), "foreachnext", irs->topfunc(), oldend); llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "foreachend", irs->topfunc());
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "foreachend", irs->topfunc(), oldend);
llvm::BranchInst::Create(condbb, irs->scopebb()); llvm::BranchInst::Create(condbb, irs->scopebb());
// condition // condition
irs->scope() = IRScope(condbb, bodybb); irs->scope() = IRScope(condbb);
LLValue* done = 0; LLValue* done = 0;
LLValue* load = DtoLoad(keyvar); LLValue* load = DtoLoad(keyvar);
@ -1488,7 +1445,7 @@ public:
llvm::BranchInst::Create(bodybb, endbb, done, irs->scopebb()); llvm::BranchInst::Create(bodybb, endbb, done, irs->scopebb());
// init body // init body
irs->scope() = IRScope(bodybb, nextbb); irs->scope() = IRScope(bodybb);
// get value for this iteration // get value for this iteration
LLValue* loadedKey = irs->ir->CreateLoad(keyvar); LLValue* loadedKey = irs->ir->CreateLoad(keyvar);
@ -1515,7 +1472,7 @@ public:
llvm::BranchInst::Create(nextbb, irs->scopebb()); llvm::BranchInst::Create(nextbb, irs->scopebb());
// next // next
irs->scope() = IRScope(nextbb, endbb); irs->scope() = IRScope(nextbb);
if (stmt->op == TOKforeach) { if (stmt->op == TOKforeach) {
LLValue* load = DtoLoad(keyvar); LLValue* load = DtoLoad(keyvar);
load = irs->ir->CreateAdd(load, LLConstantInt::get(keytype, 1, false)); load = irs->ir->CreateAdd(load, LLConstantInt::get(keytype, 1, false));
@ -1527,7 +1484,7 @@ public:
gIR->DBuilder.EmitBlockEnd(); gIR->DBuilder.EmitBlockEnd();
// end // end
irs->scope() = IRScope(endbb, oldend); irs->scope() = IRScope(endbb);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -1556,17 +1513,16 @@ public:
DtoStore(upper, keyval); DtoStore(upper, keyval);
// set up the block we'll need // set up the block we'll need
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* condbb = llvm::BasicBlock::Create(gIR->context(), "foreachrange_cond", irs->topfunc());
llvm::BasicBlock* condbb = llvm::BasicBlock::Create(gIR->context(), "foreachrange_cond", irs->topfunc(), oldend); llvm::BasicBlock* bodybb = llvm::BasicBlock::Create(gIR->context(), "foreachrange_body", irs->topfunc());
llvm::BasicBlock* bodybb = llvm::BasicBlock::Create(gIR->context(), "foreachrange_body", irs->topfunc(), oldend); llvm::BasicBlock* nextbb = llvm::BasicBlock::Create(gIR->context(), "foreachrange_next", irs->topfunc());
llvm::BasicBlock* nextbb = llvm::BasicBlock::Create(gIR->context(), "foreachrange_next", irs->topfunc(), oldend); llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "foreachrange_end", irs->topfunc());
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "foreachrange_end", irs->topfunc(), oldend);
// jump to condition // jump to condition
llvm::BranchInst::Create(condbb, irs->scopebb()); llvm::BranchInst::Create(condbb, irs->scopebb());
// CONDITION // CONDITION
irs->scope() = IRScope(condbb, bodybb); irs->scope() = IRScope(condbb);
// first we test that lwr < upr // first we test that lwr < upr
lower = DtoLoad(keyval); lower = DtoLoad(keyval);
@ -1590,7 +1546,7 @@ public:
llvm::BranchInst::Create(bodybb, endbb, cond, irs->scopebb()); llvm::BranchInst::Create(bodybb, endbb, cond, irs->scopebb());
// BODY // BODY
irs->scope() = IRScope(bodybb, nextbb); irs->scope() = IRScope(bodybb);
// reverse foreach decrements here // reverse foreach decrements here
if (stmt->op == TOKforeach_reverse) if (stmt->op == TOKforeach_reverse)
@ -1612,7 +1568,7 @@ public:
llvm::BranchInst::Create(nextbb, irs->scopebb()); llvm::BranchInst::Create(nextbb, irs->scopebb());
// NEXT // NEXT
irs->scope() = IRScope(nextbb, endbb); irs->scope() = IRScope(nextbb);
// forward foreach increments here // forward foreach increments here
if (stmt->op == TOKforeach) if (stmt->op == TOKforeach)
@ -1630,7 +1586,7 @@ public:
gIR->DBuilder.EmitBlockEnd(); gIR->DBuilder.EmitBlockEnd();
// END // END
irs->scope() = IRScope(endbb, oldend); irs->scope() = IRScope(endbb);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -1658,17 +1614,13 @@ public:
std::string labelname = irs->func()->gen->getScopedLabelName(stmt->ident->toChars()); std::string labelname = irs->func()->gen->getScopedLabelName(stmt->ident->toChars());
llvm::BasicBlock*& labelBB = irs->func()->gen->labelToBB[labelname]; llvm::BasicBlock*& labelBB = irs->func()->gen->labelToBB[labelname];
llvm::BasicBlock* oldend = gIR->scopeend(); if (!labelBB)
if (labelBB != NULL) { labelBB = llvm::BasicBlock::Create(gIR->context(), "label_" + labelname, irs->topfunc());
labelBB->moveBefore(oldend);
} else {
labelBB = llvm::BasicBlock::Create(gIR->context(), "label_" + labelname, irs->topfunc(), oldend);
}
if (!irs->scopereturned()) if (!irs->scopereturned())
llvm::BranchInst::Create(labelBB, irs->scopebb()); llvm::BranchInst::Create(labelBB, irs->scopebb());
irs->scope() = IRScope(labelBB, oldend); irs->scope() = IRScope(labelBB);
} }
if (stmt->statement) { if (stmt->statement) {
@ -1688,12 +1640,11 @@ public:
emitCoverageLinecountInc(stmt->loc); emitCoverageLinecountInc(stmt->loc);
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergoto", irs->topfunc());
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergoto", irs->topfunc(), oldend);
DtoGoto(stmt->loc, stmt->label, stmt->tf); DtoGoto(stmt->loc, stmt->label, stmt->tf);
irs->scope() = IRScope(bb, oldend); irs->scope() = IRScope(bb);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -1706,8 +1657,7 @@ public:
emitCoverageLinecountInc(stmt->loc); emitCoverageLinecountInc(stmt->loc);
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotodefault", irs->topfunc());
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotodefault", irs->topfunc(), oldend);
assert(!irs->scopereturned()); assert(!irs->scopereturned());
assert(stmt->sw->sdefault->bodyBB); assert(stmt->sw->sdefault->bodyBB);
@ -1715,7 +1665,7 @@ public:
DtoEnclosingHandlers(stmt->loc, stmt->sw); DtoEnclosingHandlers(stmt->loc, stmt->sw);
llvm::BranchInst::Create(stmt->sw->sdefault->bodyBB, irs->scopebb()); llvm::BranchInst::Create(stmt->sw->sdefault->bodyBB, irs->scopebb());
irs->scope() = IRScope(bb,oldend); irs->scope() = IRScope(bb);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -1728,19 +1678,18 @@ public:
emitCoverageLinecountInc(stmt->loc); emitCoverageLinecountInc(stmt->loc);
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotocase", irs->topfunc());
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotocase", irs->topfunc(), oldend);
assert(!irs->scopereturned()); assert(!irs->scopereturned());
if (!stmt->cs->bodyBB) if (!stmt->cs->bodyBB)
{ {
stmt->cs->bodyBB = llvm::BasicBlock::Create(gIR->context(), "goto_case", irs->topfunc(), irs->scopeend()); stmt->cs->bodyBB = llvm::BasicBlock::Create(gIR->context(), "goto_case", irs->topfunc());
} }
DtoEnclosingHandlers(stmt->loc, stmt->sw); DtoEnclosingHandlers(stmt->loc, stmt->sw);
llvm::BranchInst::Create(stmt->cs->bodyBB, irs->scopebb()); llvm::BranchInst::Create(stmt->cs->bodyBB, irs->scopebb());
irs->scope() = IRScope(bb, oldend); irs->scope() = IRScope(bb);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View file

@ -1749,13 +1749,12 @@ public:
llvm::Value* lhs = l->getRVal(); llvm::Value* lhs = l->getRVal();
llvm::Value* rhs = r->getRVal(); llvm::Value* rhs = r->getRVal();
llvm::BasicBlock* oldend = p->scopeend();
llvm::BasicBlock* fptreq = llvm::BasicBlock::Create( llvm::BasicBlock* fptreq = llvm::BasicBlock::Create(
gIR->context(), "fptreq", gIR->topfunc(), oldend); gIR->context(), "fptreq", gIR->topfunc());
llvm::BasicBlock* fptrneq = llvm::BasicBlock::Create( llvm::BasicBlock* fptrneq = llvm::BasicBlock::Create(
gIR->context(), "fptrneq", gIR->topfunc(), oldend); gIR->context(), "fptrneq", gIR->topfunc());
llvm::BasicBlock* dgcmpend = llvm::BasicBlock::Create( llvm::BasicBlock* dgcmpend = llvm::BasicBlock::Create(
gIR->context(), "dgcmpend", gIR->topfunc(), oldend); gIR->context(), "dgcmpend", gIR->topfunc());
llvm::Value* lfptr = p->ir->CreateExtractValue(lhs, 1, ".lfptr"); llvm::Value* lfptr = p->ir->CreateExtractValue(lhs, 1, ".lfptr");
llvm::Value* rfptr = p->ir->CreateExtractValue(rhs, 1, ".rfptr"); llvm::Value* rfptr = p->ir->CreateExtractValue(rhs, 1, ".rfptr");
@ -1764,17 +1763,17 @@ public:
lfptr, rfptr, ".fptreqcmp"); lfptr, rfptr, ".fptreqcmp");
llvm::BranchInst::Create(fptreq, fptrneq, fptreqcmp, p->scopebb()); llvm::BranchInst::Create(fptreq, fptrneq, fptreqcmp, p->scopebb());
p->scope() = IRScope(fptreq, fptrneq); p->scope() = IRScope(fptreq);
llvm::Value* lctx = p->ir->CreateExtractValue(lhs, 0, ".lctx"); llvm::Value* lctx = p->ir->CreateExtractValue(lhs, 0, ".lctx");
llvm::Value* rctx = p->ir->CreateExtractValue(rhs, 0, ".rctx"); llvm::Value* rctx = p->ir->CreateExtractValue(rhs, 0, ".rctx");
llvm::Value* ctxcmp = p->ir->CreateICmp(icmpPred, lctx, rctx, ".ctxcmp"); llvm::Value* ctxcmp = p->ir->CreateICmp(icmpPred, lctx, rctx, ".ctxcmp");
llvm::BranchInst::Create(dgcmpend,p->scopebb()); llvm::BranchInst::Create(dgcmpend,p->scopebb());
p->scope() = IRScope(fptrneq, dgcmpend); p->scope() = IRScope(fptrneq);
llvm::Value* fptrcmp = p->ir->CreateICmp(icmpPred, lfptr, rfptr, ".fptrcmp"); llvm::Value* fptrcmp = p->ir->CreateICmp(icmpPred, lfptr, rfptr, ".fptrcmp");
llvm::BranchInst::Create(dgcmpend,p->scopebb()); llvm::BranchInst::Create(dgcmpend,p->scopebb());
p->scope() = IRScope(dgcmpend, oldend); p->scope() = IRScope(dgcmpend);
llvm::PHINode* phi = p->ir->CreatePHI(ctxcmp->getType(), 2, ".dgcmp"); llvm::PHINode* phi = p->ir->CreatePHI(ctxcmp->getType(), 2, ".dgcmp");
phi->addIncoming(ctxcmp, fptreq); phi->addIncoming(ctxcmp, fptreq);
phi->addIncoming(fptrcmp, fptrneq); phi->addIncoming(fptrcmp, fptrneq);
@ -2156,9 +2155,8 @@ public:
} }
// create basic blocks // create basic blocks
llvm::BasicBlock* oldend = p->scopeend(); llvm::BasicBlock* passedbb = llvm::BasicBlock::Create(gIR->context(), "assertPassed", p->topfunc());
llvm::BasicBlock* passedbb = llvm::BasicBlock::Create(gIR->context(), "assertPassed", p->topfunc(), oldend); llvm::BasicBlock* failedbb = llvm::BasicBlock::Create(gIR->context(), "assertFailed", p->topfunc());
llvm::BasicBlock* failedbb = llvm::BasicBlock::Create(gIR->context(), "assertFailed", p->topfunc(), oldend);
// test condition // test condition
LLValue* condval = DtoCast(e->loc, cond, Type::tbool)->getRVal(); LLValue* condval = DtoCast(e->loc, cond, Type::tbool)->getRVal();
@ -2167,7 +2165,7 @@ public:
llvm::BranchInst::Create(passedbb, failedbb, condval, p->scopebb()); llvm::BranchInst::Create(passedbb, failedbb, condval, p->scopebb());
// failed: call assert runtime function // failed: call assert runtime function
p->scope() = IRScope(failedbb, oldend); p->scope() = IRScope(failedbb);
/* DMD Bugzilla 8360: If the condition is evaluated to true, /* DMD Bugzilla 8360: If the condition is evaluated to true,
* msg is not evaluated at all. So should use toElemDtor() * msg is not evaluated at all. So should use toElemDtor()
@ -2176,7 +2174,7 @@ public:
DtoAssert(p->func()->decl->getModule(), e->loc, e->msg ? toElemDtor(e->msg) : NULL); DtoAssert(p->func()->decl->getModule(), e->loc, e->msg ? toElemDtor(e->msg) : NULL);
// passed: // passed:
p->scope() = IRScope(passedbb, failedbb); p->scope() = IRScope(passedbb);
FuncDeclaration* invdecl; FuncDeclaration* invdecl;
// class invariants // class invariants
@ -2235,16 +2233,15 @@ public:
DValue* u = toElem(e->e1); DValue* u = toElem(e->e1);
llvm::BasicBlock* oldend = p->scopeend(); llvm::BasicBlock* andand = llvm::BasicBlock::Create(gIR->context(), "andand", gIR->topfunc());
llvm::BasicBlock* andand = llvm::BasicBlock::Create(gIR->context(), "andand", gIR->topfunc(), oldend); llvm::BasicBlock* andandend = llvm::BasicBlock::Create(gIR->context(), "andandend", gIR->topfunc());
llvm::BasicBlock* andandend = llvm::BasicBlock::Create(gIR->context(), "andandend", gIR->topfunc(), oldend);
LLValue* ubool = DtoCast(e->loc, u, Type::tbool)->getRVal(); LLValue* ubool = DtoCast(e->loc, u, Type::tbool)->getRVal();
llvm::BasicBlock* oldblock = p->scopebb(); llvm::BasicBlock* oldblock = p->scopebb();
llvm::BranchInst::Create(andand, andandend, ubool, p->scopebb()); llvm::BranchInst::Create(andand, andandend, ubool, p->scopebb());
p->scope() = IRScope(andand, andandend); p->scope() = IRScope(andand);
emitCoverageLinecountInc(e->e2->loc); emitCoverageLinecountInc(e->e2->loc);
DValue* v = toElemDtor(e->e2); DValue* v = toElemDtor(e->e2);
@ -2256,7 +2253,7 @@ public:
llvm::BasicBlock* newblock = p->scopebb(); llvm::BasicBlock* newblock = p->scopebb();
llvm::BranchInst::Create(andandend,p->scopebb()); llvm::BranchInst::Create(andandend,p->scopebb());
p->scope() = IRScope(andandend, oldend); p->scope() = IRScope(andandend);
LLValue* resval = 0; LLValue* resval = 0;
if (ubool == vbool || !vbool) { if (ubool == vbool || !vbool) {
@ -2283,16 +2280,15 @@ public:
DValue* u = toElem(e->e1); DValue* u = toElem(e->e1);
llvm::BasicBlock* oldend = p->scopeend(); llvm::BasicBlock* oror = llvm::BasicBlock::Create(gIR->context(), "oror", gIR->topfunc());
llvm::BasicBlock* oror = llvm::BasicBlock::Create(gIR->context(), "oror", gIR->topfunc(), oldend); llvm::BasicBlock* ororend = llvm::BasicBlock::Create(gIR->context(), "ororend", gIR->topfunc());
llvm::BasicBlock* ororend = llvm::BasicBlock::Create(gIR->context(), "ororend", gIR->topfunc(), oldend);
LLValue* ubool = DtoCast(e->loc, u, Type::tbool)->getRVal(); LLValue* ubool = DtoCast(e->loc, u, Type::tbool)->getRVal();
llvm::BasicBlock* oldblock = p->scopebb(); llvm::BasicBlock* oldblock = p->scopebb();
llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb()); llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb());
p->scope() = IRScope(oror, ororend); p->scope() = IRScope(oror);
emitCoverageLinecountInc(e->e2->loc); emitCoverageLinecountInc(e->e2->loc);
DValue* v = toElemDtor(e->e2); DValue* v = toElemDtor(e->e2);
@ -2304,7 +2300,7 @@ public:
llvm::BasicBlock* newblock = p->scopebb(); llvm::BasicBlock* newblock = p->scopebb();
llvm::BranchInst::Create(ororend,p->scopebb()); llvm::BranchInst::Create(ororend,p->scopebb());
p->scope() = IRScope(ororend, oldend); p->scope() = IRScope(ororend);
LLValue* resval = 0; LLValue* resval = 0;
if (ubool == vbool || !vbool) { if (ubool == vbool || !vbool) {
@ -2375,9 +2371,8 @@ public:
// this terminated the basicblock, start a new one // this terminated the basicblock, start a new one
// this is sensible, since someone might goto behind the assert // this is sensible, since someone might goto behind the assert
// and prevents compiler errors if a terminator follows the assert // and prevents compiler errors if a terminator follows the assert
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "afterhalt", p->topfunc());
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "afterhalt", p->topfunc(), oldend); p->scope() = IRScope(bb);
p->scope() = IRScope(bb,oldend);
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -2552,16 +2547,15 @@ public:
retPtr = DtoAlloca(dtype->pointerTo(), "condtmp"); retPtr = DtoAlloca(dtype->pointerTo(), "condtmp");
} }
llvm::BasicBlock* oldend = p->scopeend(); llvm::BasicBlock* condtrue = llvm::BasicBlock::Create(gIR->context(), "condtrue", gIR->topfunc());
llvm::BasicBlock* condtrue = llvm::BasicBlock::Create(gIR->context(), "condtrue", gIR->topfunc(), oldend); llvm::BasicBlock* condfalse = llvm::BasicBlock::Create(gIR->context(), "condfalse", gIR->topfunc());
llvm::BasicBlock* condfalse = llvm::BasicBlock::Create(gIR->context(), "condfalse", gIR->topfunc(), oldend); llvm::BasicBlock* condend = llvm::BasicBlock::Create(gIR->context(), "condend", gIR->topfunc());
llvm::BasicBlock* condend = llvm::BasicBlock::Create(gIR->context(), "condend", gIR->topfunc(), oldend);
DValue* c = toElem(e->econd); DValue* c = toElem(e->econd);
LLValue* cond_val = DtoCast(e->loc, c, Type::tbool)->getRVal(); LLValue* cond_val = DtoCast(e->loc, c, Type::tbool)->getRVal();
llvm::BranchInst::Create(condtrue, condfalse, cond_val, p->scopebb()); llvm::BranchInst::Create(condtrue, condfalse, cond_val, p->scopebb());
p->scope() = IRScope(condtrue, condfalse); p->scope() = IRScope(condtrue);
DValue* u = toElemDtor(e->e1); DValue* u = toElemDtor(e->e1);
if (retPtr) { if (retPtr) {
LLValue* lval = makeLValue(e->loc, u); LLValue* lval = makeLValue(e->loc, u);
@ -2569,7 +2563,7 @@ public:
} }
llvm::BranchInst::Create(condend, p->scopebb()); llvm::BranchInst::Create(condend, p->scopebb());
p->scope() = IRScope(condfalse, condend); p->scope() = IRScope(condfalse);
DValue* v = toElemDtor(e->e2); DValue* v = toElemDtor(e->e2);
if (retPtr) { if (retPtr) {
LLValue* lval = makeLValue(e->loc, v); LLValue* lval = makeLValue(e->loc, v);
@ -2577,7 +2571,7 @@ public:
} }
llvm::BranchInst::Create(condend, p->scopebb()); llvm::BranchInst::Create(condend, p->scopebb());
p->scope() = IRScope(condend, oldend); p->scope() = IRScope(condend);
if (retPtr) if (retPtr)
result = new DVarValue(e->type, DtoLoad(retPtr)); result = new DVarValue(e->type, DtoLoad(retPtr));
else else

View file

@ -349,8 +349,7 @@ llvm::GlobalVariable * IrAggr::getInterfaceVtbl(BaseClass * b, bool new_instance
// create entry and end blocks // create entry and end blocks
llvm::BasicBlock* beginbb = llvm::BasicBlock::Create(gIR->context(), "", thunk); llvm::BasicBlock* beginbb = llvm::BasicBlock::Create(gIR->context(), "", thunk);
llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endentry", thunk); gIR->scopes.push_back(IRScope(beginbb));
gIR->scopes.push_back(IRScope(beginbb, endbb));
// copy the function parameters, so later we can pass them to the real function // copy the function parameters, so later we can pass them to the real function
std::vector<LLValue*> args; std::vector<LLValue*> args;
@ -376,7 +375,6 @@ llvm::GlobalVariable * IrAggr::getInterfaceVtbl(BaseClass * b, bool new_instance
// clean up // clean up
gIR->scopes.pop_back(); gIR->scopes.pop_back();
thunk->getBasicBlockList().pop_back();
fn = thunk; fn = thunk;
} }

View file

@ -119,7 +119,7 @@ void FuncGen::prepareToDestructAllTemporariesOnThrow(IRState* irState)
// create landing pad // create landing pad
llvm::BasicBlock* landingpadbb = llvm::BasicBlock::Create(irState->context(), llvm::BasicBlock* landingpadbb = llvm::BasicBlock::Create(irState->context(),
"temporariesLandingPad", irState->topfunc(), irState->scopeend()); "temporariesLandingPad", irState->topfunc());
// set up the landing pad // set up the landing pad
landingPadInfo.addFinally(callDestructors, /* deleteOnPop = */ true); landingPadInfo.addFinally(callDestructors, /* deleteOnPop = */ true);

View file

@ -57,7 +57,7 @@ void IRLandingPadCatchInfo::toIR()
if (!catchStmt) if (!catchStmt)
return; return;
gIR->scope() = IRScope(target, target); gIR->scope() = IRScope(target);
gIR->DBuilder.EmitBlockStart(catchStmt->loc); gIR->DBuilder.EmitBlockStart(catchStmt->loc);
LLFunction* enterCatchFn = LLFunction* enterCatchFn =
@ -165,7 +165,7 @@ void IRLandingPad::constructLandingPad(IRLandingPadScope scope)
{ {
// save and rewrite scope // save and rewrite scope
IRScope savedIRScope = gIR->scope(); IRScope savedIRScope = gIR->scope();
gIR->scope() = IRScope(scope.target, savedIRScope.end); gIR->scope() = IRScope(scope.target);
// create landingpad // create landingpad
llvm::LandingPadInst *landingPad = createLandingPadInst(); llvm::LandingPadInst *landingPad = createLandingPadInst();
@ -205,7 +205,7 @@ void IRLandingPad::constructLandingPad(IRLandingPadScope scope)
} }
// create next block // create next block
llvm::BasicBlock *next = llvm::BasicBlock::Create(gIR->context(), "eh.next", gIR->topfunc(), gIR->scopeend()); llvm::BasicBlock *next = llvm::BasicBlock::Create(gIR->context(), "eh.next", gIR->topfunc());
// get class info symbol // get class info symbol
LLValue *classInfo = getIrAggr(catchItr->catchType)->getClassInfoSymbol(); LLValue *classInfo = getIrAggr(catchItr->catchType)->getClassInfoSymbol();
// add that symbol as landing pad clause // add that symbol as landing pad clause
@ -215,7 +215,7 @@ void IRLandingPad::constructLandingPad(IRLandingPadScope scope)
LLValue *eh_id = gIR->ir->CreateCall(eh_typeid_for_fn, classInfo); LLValue *eh_id = gIR->ir->CreateCall(eh_typeid_for_fn, classInfo);
// check exception selector (eh_sel) against the class info index // check exception selector (eh_sel) against the class info index
gIR->ir->CreateCondBr(gIR->ir->CreateICmpEQ(eh_sel, eh_id), catchItr->target, next); gIR->ir->CreateCondBr(gIR->ir->CreateICmpEQ(eh_sel, eh_id), catchItr->target, next);
gIR->scope() = IRScope(next, gIR->scopeend()); gIR->scope() = IRScope(next);
} }
if (scope.finally) { if (scope.finally) {