Refactor basic block construction and revise BB order

This commit is contained in:
Martin 2016-08-06 19:49:06 +02:00
parent 583aab933b
commit e711deac1b
11 changed files with 161 additions and 246 deletions

View file

@ -79,10 +79,8 @@ DLValue *DtoAAIndex(Loc &loc, Type *type, DValue *aa, DValue *key,
// Only check bounds for rvalues ('aa[key]').
// Lvalue use ('aa[key] = value') auto-adds an element.
if (!lvalue && gIR->emitArrayBoundsChecks()) {
llvm::BasicBlock *failbb = llvm::BasicBlock::Create(
gIR->context(), "aaboundscheckfail", gIR->topfunc());
llvm::BasicBlock *okbb =
llvm::BasicBlock::Create(gIR->context(), "aaboundsok", gIR->topfunc());
llvm::BasicBlock *okbb = gIR->insertBB("aaboundsok");
llvm::BasicBlock *failbb = gIR->insertBBAfter(okbb, "aaboundscheckfail");
LLValue *nullaa = LLConstant::getNullValue(ret->getType());
LLValue *cond = gIR->ir->CreateICmpNE(nullaa, ret, "aaboundscheck");

View file

@ -134,12 +134,9 @@ static void DtoArrayInit(Loc &loc, LLValue *ptr, LLValue *length,
}
// create blocks
llvm::BasicBlock *condbb = llvm::BasicBlock::Create(
gIR->context(), "arrayinit.cond", gIR->topfunc());
llvm::BasicBlock *bodybb = llvm::BasicBlock::Create(
gIR->context(), "arrayinit.body", gIR->topfunc());
llvm::BasicBlock *endbb =
llvm::BasicBlock::Create(gIR->context(), "arrayinit.end", gIR->topfunc());
llvm::BasicBlock *condbb = gIR->insertBB("arrayinit.cond");
llvm::BasicBlock *bodybb = gIR->insertBBAfter(condbb, "arrayinit.body");
llvm::BasicBlock *endbb = gIR->insertBBAfter(bodybb, "arrayinit.end");
// initialize iterator
LLValue *itr = DtoAllocaDump(DtoConstSize_t(0), 0, "arrayinit.itr");
@ -1174,15 +1171,12 @@ void DtoIndexBoundsCheck(Loc &loc, DValue *arr, DValue *index) {
llvm::Value *cond = gIR->ir->CreateICmp(cmpop, DtoRVal(index),
DtoArrayLen(arr), "bounds.cmp");
llvm::BasicBlock *failbb =
llvm::BasicBlock::Create(gIR->context(), "bounds.fail", gIR->topfunc());
llvm::BasicBlock *okbb =
llvm::BasicBlock::Create(gIR->context(), "bounds.ok", gIR->topfunc());
llvm::BasicBlock *okbb = gIR->insertBB("bounds.ok");
llvm::BasicBlock *failbb = gIR->insertBBAfter(okbb, "bounds.fail");
gIR->ir->CreateCondBr(cond, okbb, failbb);
// set up failbb to call the array bounds error runtime function
gIR->scope() = IRScope(failbb);
DtoBoundsCheckFailCall(gIR, loc);
// if ok, proceed in okbb

View file

@ -716,8 +716,7 @@ void CompoundAsmStatement_toIR(CompoundAsmStatement *stmt, IRState *p) {
assert(jump_target);
// make new blocks
llvm::BasicBlock *bb = llvm::BasicBlock::Create(
gIR->context(), "afterasmgotoforwarder", p->topfunc());
llvm::BasicBlock *bb = p->insertBB("afterasmgotoforwarder");
llvm::LoadInst *val =
p->ir->CreateLoad(jump_target, "__llvm_jump_target_value");
@ -725,8 +724,7 @@ void CompoundAsmStatement_toIR(CompoundAsmStatement *stmt, IRState *p) {
// add all cases
for (const auto &pair : gotoToVal) {
llvm::BasicBlock *casebb =
llvm::BasicBlock::Create(gIR->context(), "case", p->topfunc(), bb);
llvm::BasicBlock *casebb = p->insertBBBefore(bb, "case");
sw->addCase(LLConstantInt::get(llvm::IntegerType::get(gIR->context(), 32),
pair.second),
casebb);

View file

@ -255,14 +255,12 @@ llvm::BasicBlock *ScopeStack::runCleanupPad(CleanupCursor scope,
// _d_leave_cleanup(%frame)
// cleanupret %0 unwind %unwindTo
//
llvm::BasicBlock *cleanupbb =
llvm::BasicBlock::Create(irs.context(), "cleanuppad", irs.topfunc());
llvm::BasicBlock *cleanupbb = irs.insertBB("cleanuppad");
auto funcletToken = llvm::ConstantTokenNone::get(irs.context());
auto cleanuppad =
llvm::CleanupPadInst::Create(funcletToken, {}, "", cleanupbb);
llvm::BasicBlock *cleanupret =
llvm::BasicBlock::Create(irs.context(), "cleanupret", irs.topfunc());
llvm::BasicBlock *cleanupret = irs.insertBBAfter(cleanupbb, "cleanupret");
// preparation to allocate some space on the stack where _d_enter_cleanup
// can place an exception frame (but not done here)
@ -314,13 +312,13 @@ void ScopeStack::popCleanups(CleanupCursor targetScope) {
llvm::BasicBlock *tentative = gotoJump.tentativeTarget;
#if LDC_LLVM_VER >= 308
if (useMSVCEH()) {
llvm::BasicBlock *continueWith = llvm::BasicBlock::Create(
irs.context(), "jumpcleanup", irs.topfunc());
llvm::BasicBlock *afterCleanup = irs.insertBB("");
auto startCleanup =
executeCleanupCopying(irs, cleanupScopes[i], gotoJump.sourceBlock,
continueWith, nullptr, nullptr);
afterCleanup, nullptr, nullptr);
tentative->replaceAllUsesWith(startCleanup);
llvm::BranchInst::Create(tentative, continueWith);
afterCleanup->replaceAllUsesWith(tentative);
afterCleanup->eraseFromParent();
} else
#endif
{
@ -405,8 +403,7 @@ void ScopeStack::jumpToLabel(Loc loc, Identifier *labelName) {
return;
}
llvm::BasicBlock *target =
llvm::BasicBlock::Create(irs.context(), "goto.unresolved", irs.topfunc());
llvm::BasicBlock *target = irs.insertBB("goto.unresolved");
irs.ir->CreateBr(target);
currentUnresolvedGotos().emplace_back(loc, irs.scopebb(), target, labelName);
}
@ -467,9 +464,8 @@ llvm::BasicBlock *SwitchCaseTargets::get(Statement *stmt) {
llvm::BasicBlock *SwitchCaseTargets::getOrCreate(Statement *stmt,
const llvm::Twine &name) {
auto &bb = targetBBs[stmt];
if (!bb) {
bb = llvm::BasicBlock::Create(llFunc->getContext(), name, llFunc);
}
if (!bb)
bb = gIR->insertBB(name);
return bb;
}
@ -487,8 +483,7 @@ llvm::BasicBlock *FuncGenState::getOrCreateResumeUnwindBlock() {
assert(irFunc.func == irs.topfunc() &&
"Should only access unwind resume block while emitting function.");
if (!resumeUnwindBlock) {
resumeUnwindBlock =
llvm::BasicBlock::Create(irs.context(), "eh.resume", irFunc.func);
resumeUnwindBlock = irs.insertBB("eh.resume");
llvm::BasicBlock *oldBB = irs.scopebb();
irs.scope() = IRScope(resumeUnwindBlock);

View file

@ -384,8 +384,7 @@ llvm::CallSite ScopeStack::callOrInvoke(llvm::Value *callee, const T &args,
llvm::BasicBlock *landingPad = getLandingPad();
llvm::BasicBlock *postinvoke = llvm::BasicBlock::Create(
irs.context(), "postinvoke", irs.topfunc(), landingPad);
llvm::BasicBlock *postinvoke = irs.insertBB("postinvoke");
llvm::InvokeInst *invoke =
irs.ir->CreateInvoke(callee, postinvoke, landingPad, args,
#if LDC_LLVM_VER >= 308

View file

@ -80,6 +80,22 @@ bool IRState::scopereturned() {
return !scopebb()->empty() && scopebb()->back().isTerminator();
}
llvm::BasicBlock *IRState::insertBBBefore(llvm::BasicBlock *successor,
const llvm::Twine &name) {
return llvm::BasicBlock::Create(context(), name, topfunc(), successor);
}
llvm::BasicBlock *IRState::insertBBAfter(llvm::BasicBlock *predecessor,
const llvm::Twine &name) {
auto bb = llvm::BasicBlock::Create(context(), name, topfunc());
bb->moveAfter(predecessor);
return bb;
}
llvm::BasicBlock *IRState::insertBB(const llvm::Twine &name) {
return insertBBAfter(scopebb(), name);
}
LLCallSite IRState::CreateCallOrInvoke(LLValue *Callee, const char *Name) {
LLSmallVector<LLValue *, 1> args;
return funcGen().scopes.callOrInvoke(Callee, args, Name);

View file

@ -139,6 +139,16 @@ struct IRState {
llvm::BasicBlock *scopebb();
bool scopereturned();
// Creates a new basic block and inserts it before the specified one.
llvm::BasicBlock *insertBBBefore(llvm::BasicBlock *successor,
const llvm::Twine &name);
// Creates a new basic block and inserts it after the specified one.
llvm::BasicBlock *insertBBAfter(llvm::BasicBlock *predecessor,
const llvm::Twine &name);
// Creates a new basic block and inserts it after the current scope basic
// block (`scopebb()`).
llvm::BasicBlock *insertBB(const llvm::Twine &name);
// create a call or invoke, depending on the landing pad info
llvm::CallSite CreateCallOrInvoke(LLValue *Callee, const char *Name = "");
llvm::CallSite CreateCallOrInvoke(LLValue *Callee, LLValue *Arg1,

View file

@ -153,8 +153,7 @@ public:
if (constructed) {
// cleanup manually (otherwise done by toElemDtor())
if (funcGen.scopes.currentCleanupScope() != initialCleanupScope) {
auto endbb = llvm::BasicBlock::Create(
irs->context(), "inPlaceSretConstruct.success", llFunc);
auto endbb = irs->insertBB("inPlaceSretConstruct.success");
funcGen.scopes.runCleanups(initialCleanupScope, endbb);
funcGen.scopes.popCleanups(initialCleanupScope);
irs->scope() = IRScope(endbb);
@ -245,8 +244,7 @@ public:
const bool sharedRetBlockExists = !!funcGen.retBlock;
if (useRetValSlot) {
if (!sharedRetBlockExists) {
funcGen.retBlock =
llvm::BasicBlock::Create(irs->context(), "return", llFunc);
funcGen.retBlock = irs->insertBB("return");
if (returnValue) {
funcGen.retValSlot =
DtoRawAlloca(returnValue->getType(), 0, "return.slot");
@ -285,8 +283,7 @@ public:
// Finally, create a new predecessor-less dummy bb as the current IRScope
// to make sure we do not emit any extra instructions after the terminating
// instruction (ret or branch to return bb), which would be illegal IR.
irs->scope() = IRScope(
llvm::BasicBlock::Create(gIR->context(), "dummy.afterreturn", llFunc));
irs->scope() = IRScope(irs->insertBB("dummy.afterreturn"));
}
//////////////////////////////////////////////////////////////////////////
@ -340,14 +337,10 @@ public:
DValue *cond_e = toElemDtor(stmt->condition);
LLValue *cond_val = DtoRVal(cond_e);
llvm::BasicBlock *ifbb =
llvm::BasicBlock::Create(irs->context(), "if", irs->topfunc());
llvm::BasicBlock *endbb =
llvm::BasicBlock::Create(irs->context(), "endif", irs->topfunc());
llvm::BasicBlock *ifbb = irs->insertBB("if");
llvm::BasicBlock *endbb = irs->insertBBAfter(ifbb, "endif");
llvm::BasicBlock *elsebb =
stmt->elsebody ? llvm::BasicBlock::Create(irs->context(), "else",
irs->topfunc(), endbb)
: endbb;
stmt->elsebody ? irs->insertBBAfter(ifbb, "else") : endbb;
if (cond_val->getType() != LLType::getInt1Ty(irs->context())) {
IF_LOG Logger::cout() << "if conditional: " << *cond_val << '\n';
@ -419,12 +412,9 @@ public:
// create while blocks
llvm::BasicBlock *whilebb =
llvm::BasicBlock::Create(irs->context(), "whilecond", irs->topfunc());
llvm::BasicBlock *whilebodybb =
llvm::BasicBlock::Create(irs->context(), "whilebody", irs->topfunc());
llvm::BasicBlock *endbb =
llvm::BasicBlock::Create(irs->context(), "endwhile", irs->topfunc());
llvm::BasicBlock *whilebb = irs->insertBB("whilecond");
llvm::BasicBlock *whilebodybb = irs->insertBBAfter(whilebb, "whilebody");
llvm::BasicBlock *endbb = irs->insertBBAfter(whilebodybb, "endwhile");
// move into the while block
irs->ir->CreateBr(whilebb);
@ -484,12 +474,9 @@ public:
irs->DBuilder.EmitBlockStart(stmt->loc);
// create while blocks
llvm::BasicBlock *dowhilebb =
llvm::BasicBlock::Create(irs->context(), "dowhile", irs->topfunc());
llvm::BasicBlock *condbb =
llvm::BasicBlock::Create(irs->context(), "dowhilecond", irs->topfunc());
llvm::BasicBlock *endbb =
llvm::BasicBlock::Create(irs->context(), "enddowhile", irs->topfunc());
llvm::BasicBlock *dowhilebb = irs->insertBB("dowhile");
llvm::BasicBlock *condbb = irs->insertBBAfter(dowhilebb, "dowhilecond");
llvm::BasicBlock *endbb = irs->insertBBAfter(condbb, "enddowhile");
// move into the while block
assert(!irs->scopereturned());
@ -529,10 +516,6 @@ public:
PGO.addBranchWeights(branchinst, brweights);
}
// Order the blocks in a logical order in IR
condbb->moveAfter(&irs->topfunc()->back());
endbb->moveAfter(condbb);
// rewrite the scope
irs->scope() = IRScope(endbb);
@ -553,14 +536,10 @@ public:
irs->DBuilder.EmitBlockStart(stmt->loc);
// create for blocks
llvm::BasicBlock *forbb =
llvm::BasicBlock::Create(irs->context(), "forcond", irs->topfunc());
llvm::BasicBlock *forbodybb =
llvm::BasicBlock::Create(irs->context(), "forbody", irs->topfunc());
llvm::BasicBlock *forincbb =
llvm::BasicBlock::Create(irs->context(), "forinc", irs->topfunc());
llvm::BasicBlock *endbb =
llvm::BasicBlock::Create(irs->context(), "endfor", irs->topfunc());
llvm::BasicBlock *forbb = irs->insertBB("forcond");
llvm::BasicBlock *forbodybb = irs->insertBBAfter(forbb, "forbody");
llvm::BasicBlock *forincbb = irs->insertBBAfter(forbodybb, "forinc");
llvm::BasicBlock *endbb = irs->insertBBAfter(forincbb, "endfor");
// init
if (stmt->_init != nullptr) {
@ -612,10 +591,6 @@ public:
stmt->_body->accept(this);
}
// Order the blocks in a logical order in IR
forincbb->moveAfter(&irs->topfunc()->back());
endbb->moveAfter(forincbb);
// move into the for increment block
if (!irs->scopereturned()) {
llvm::BranchInst::Create(forincbb, irs->scopebb());
@ -680,8 +655,7 @@ public:
}
// the break terminated this basicblock, start a new one
llvm::BasicBlock *bb =
llvm::BasicBlock::Create(irs->context(), "afterbreak", irs->topfunc());
llvm::BasicBlock *bb = irs->insertBB("afterbreak");
irs->scope() = IRScope(bb);
}
@ -715,9 +689,8 @@ public:
irs->funcGen().scopes.continueWithClosest();
}
// the break terminated this basicblock, start a new one
llvm::BasicBlock *bb =
llvm::BasicBlock::Create(irs->context(), "afterbreak", irs->topfunc());
// the continue terminated this basicblock, start a new one
llvm::BasicBlock *bb = irs->insertBB("aftercontinue");
irs->scope() = IRScope(bb);
}
@ -762,9 +735,14 @@ public:
// for an extra one (we'd need to branch to it unconditionally anyway).
llvm::BasicBlock *trybb = irs->scopebb();
llvm::BasicBlock *finallybb = irs->insertBB("finally");
// Create a block to branch to after successfully running the try block
// and any cleanups.
llvm::BasicBlock *successbb =
irs->scopereturned() ? nullptr
: irs->insertBBAfter(finallybb, "try.success");
// Emit the finally block and set up the cleanup scope for it.
llvm::BasicBlock *finallybb =
llvm::BasicBlock::Create(irs->context(), "finally", irs->topfunc());
irs->scope() = IRScope(finallybb);
irs->DBuilder.EmitBlockStart(stmt->finalbody->loc);
stmt->finalbody->accept(this);
@ -781,11 +759,7 @@ public:
stmt->_body->accept(this);
irs->DBuilder.EmitBlockEnd();
// Create a block to branch to after successfully running the try block
// and any cleanups.
if (!irs->scopereturned()) {
llvm::BasicBlock *successbb = llvm::BasicBlock::Create(
irs->context(), "try.success", irs->topfunc());
if (successbb) {
irs->funcGen().scopes.runCleanups(cleanupBefore, successbb);
irs->scope() = IRScope(successbb);
// PGO counter tracks the continuation of the try-finally statement
@ -812,8 +786,7 @@ public:
// Create a basic block to branch to after leaving the try or an
// associated catch block successfully.
llvm::BasicBlock *endbb = llvm::BasicBlock::Create(
irs->context(), "try.success.or.caught", irs->topfunc());
llvm::BasicBlock *endbb = irs->insertBB("try.success.or.caught");
irs->funcGen().scopes.pushTryCatch(stmt, endbb);
@ -830,9 +803,6 @@ public:
irs->funcGen().scopes.popTryCatch();
// Move end block after all generated blocks
endbb->moveAfter(&irs->topfunc()->back());
irs->scope() = IRScope(endbb);
// PGO counter tracks the continuation of the try statement
@ -865,8 +835,7 @@ public:
irs->ir->CreateUnreachable();
// TODO: Should not be needed.
llvm::BasicBlock *bb =
llvm::BasicBlock::Create(irs->context(), "afterthrow", irs->topfunc());
llvm::BasicBlock *bb = irs->insertBB("afterthrow");
irs->scope() = IRScope(bb);
}
@ -948,17 +917,10 @@ public:
// body block.
// FIXME: that block is never used
llvm::BasicBlock *bodybb =
llvm::BasicBlock::Create(irs->context(), "switchbody", irs->topfunc());
llvm::BasicBlock *bodybb = irs->insertBB("switchbody");
// end (break point)
llvm::BasicBlock *endbb =
llvm::BasicBlock::Create(irs->context(), "switchend", irs->topfunc());
// PGO counter tracks exit point of switch statement:
{
irs->scope() = IRScope(endbb);
PGO.emitCounterIncrement(stmt);
}
llvm::BasicBlock *endbb = irs->insertBBAfter(bodybb, "switchend");
// default
auto defaultTargetBB = endbb;
@ -1005,12 +967,11 @@ public:
// Add PGO instrumentation.
// Create "default" counter bb.
{
llvm::BasicBlock *defaultcntr = llvm::BasicBlock::Create(
irs->context(), "defaultcntr", irs->topfunc());
llvm::BasicBlock *defaultcntr =
irs->insertBBBefore(defaultTargetBB, "defaultcntr");
irs->scope() = IRScope(defaultcntr);
PGO.emitCounterIncrement(stmt->sdefault);
llvm::BranchInst::Create(defaultTargetBB, irs->scopebb());
defaultcntr->moveBefore(defaultTargetBB);
llvm::BranchInst::Create(defaultTargetBB, defaultcntr);
// Create switch
si = llvm::SwitchInst::Create(condVal, defaultcntr, caseCount,
switchbb);
@ -1019,24 +980,16 @@ public:
// Create and add case counter bbs.
for (size_t i = 0; i < caseCount; ++i) {
const auto cs = (*cases)[i];
const auto body = funcGen.switchTargets.get(cs);
auto incrCaseCounter = llvm::BasicBlock::Create(
irs->context(), "incrCaseCounter", irs->topfunc());
auto incrCaseCounter = irs->insertBBBefore(body, "incrCaseCounter");
irs->scope() = IRScope(incrCaseCounter);
PGO.emitCounterIncrement(cs);
const auto body = funcGen.switchTargets.get(cs);
llvm::BranchInst::Create(body, irs->scopebb());
incrCaseCounter->moveBefore(body);
llvm::BranchInst::Create(body, incrCaseCounter);
si->addCase(isaConstantInt(indices[i]), incrCaseCounter);
}
}
// Put the switchend block after the last block, for a more logical IR
// layout.
endbb->moveAfter(&irs->topfunc()->back());
// Apply PGO switch branch weights:
{
// Get case statements execution counts from profile data.
@ -1058,18 +1011,16 @@ public:
DValue *cond = toElemDtor(stmt->condition);
LLValue *condVal = DtoRVal(cond);
llvm::BasicBlock *nextbb =
llvm::BasicBlock::Create(irs->context(), "checkcase", irs->topfunc());
llvm::BasicBlock *nextbb = irs->insertBBBefore(endbb, "checkcase");
llvm::BranchInst::Create(nextbb, irs->scopebb());
if (global.params.genInstrProf) {
// Prepend extra BB to "default:" to increment profiling counter.
llvm::BasicBlock *defaultcntr = llvm::BasicBlock::Create(
irs->context(), "defaultcntr", irs->topfunc());
llvm::BasicBlock *defaultcntr =
irs->insertBBBefore(defaultTargetBB, "defaultcntr");
irs->scope() = IRScope(defaultcntr);
PGO.emitCounterIncrement(stmt->sdefault);
llvm::BranchInst::Create(defaultTargetBB, irs->scopebb());
defaultcntr->moveBefore(defaultTargetBB);
llvm::BranchInst::Create(defaultTargetBB, defaultcntr);
defaultTargetBB = defaultcntr;
}
@ -1078,20 +1029,18 @@ public:
for (size_t i = 0; i < caseCount; ++i) {
LLValue *cmp = irs->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ, indices[i],
condVal, "checkcase");
nextbb = llvm::BasicBlock::Create(irs->context(), "checkcase",
irs->topfunc());
nextbb = irs->insertBBBefore(endbb, "checkcase");
// Add case counters for PGO in front of case body
const auto cs = (*cases)[i];
auto casejumptargetbb = funcGen.switchTargets.get(cs);
if (global.params.genInstrProf) {
llvm::BasicBlock *casecntr = llvm::BasicBlock::Create(
irs->context(), "casecntr", irs->topfunc());
llvm::BasicBlock *casecntr =
irs->insertBBBefore(casejumptargetbb, "casecntr");
auto savedbb = irs->scope();
irs->scope() = IRScope(casecntr);
PGO.emitCounterIncrement(cs);
llvm::BranchInst::Create(casejumptargetbb, irs->scopebb());
casecntr->moveBefore(casejumptargetbb);
llvm::BranchInst::Create(casejumptargetbb, casecntr);
irs->scope() = savedbb;
casejumptargetbb = casecntr;
@ -1116,11 +1065,11 @@ public:
}
llvm::BranchInst::Create(defaultTargetBB, irs->scopebb());
endbb->moveAfter(nextbb);
}
irs->scope() = IRScope(endbb);
// PGO counter tracks exit point of switch statement:
PGO.emitCounterIncrement(stmt);
}
//////////////////////////////////////////////////////////////////////////
@ -1134,6 +1083,8 @@ public:
PGO.setCurrentStmt(stmt);
const auto body = funcGen.switchTargets.getOrCreate(stmt, "case");
// The BB may have already been created by a `goto case` statement.
// Move it after the current scope BB for lexical order.
body->moveAfter(irs->scopebb());
if (!irs->scopereturned()) {
@ -1163,6 +1114,8 @@ public:
PGO.setCurrentStmt(stmt);
const auto body = funcGen.switchTargets.getOrCreate(stmt, "default");
// The BB may have already been created.
// Move it after the current scope BB for lexical order.
body->moveAfter(irs->scopebb());
if (!irs->scopereturned()) {
@ -1203,18 +1156,14 @@ public:
// loop we have to keep track of each statement and jump to the next/end
// on continue/break
// create end block
llvm::BasicBlock *endbb = irs->insertBB("unrolledend");
// create a block for each statement
size_t nstmt = stmt->statements->dim;
llvm::SmallVector<llvm::BasicBlock *, 4> blocks(nstmt, nullptr);
for (size_t i = 0; i < nstmt; i++) {
blocks[i] = llvm::BasicBlock::Create(irs->context(), "unrolledstmt",
irs->topfunc());
}
// create end block
llvm::BasicBlock *endbb =
llvm::BasicBlock::Create(irs->context(), "unrolledend", irs->topfunc());
for (size_t i = 0; i < nstmt; i++)
blocks[i] = irs->insertBBBefore(endbb, "unrolledstmt");
// enter first stmt
if (!irs->scopereturned()) {
@ -1250,10 +1199,6 @@ public:
}
}
// finish scope
if (!irs->scopereturned()) {
irs->ir->CreateBr(endbb);
}
irs->scope() = IRScope(endbb);
// end the dwarf lexical block
@ -1326,14 +1271,10 @@ public:
new llvm::StoreInst(niters, keyvar, irs->scopebb());
}
llvm::BasicBlock *condbb =
llvm::BasicBlock::Create(irs->context(), "foreachcond", irs->topfunc());
llvm::BasicBlock *bodybb =
llvm::BasicBlock::Create(irs->context(), "foreachbody", irs->topfunc());
llvm::BasicBlock *nextbb =
llvm::BasicBlock::Create(irs->context(), "foreachnext", irs->topfunc());
llvm::BasicBlock *endbb =
llvm::BasicBlock::Create(irs->context(), "foreachend", irs->topfunc());
llvm::BasicBlock *condbb = irs->insertBB("foreachcond");
llvm::BasicBlock *bodybb = irs->insertBBAfter(condbb, "foreachbody");
llvm::BasicBlock *nextbb = irs->insertBBAfter(bodybb, "foreachnext");
llvm::BasicBlock *endbb = irs->insertBBAfter(nextbb, "foreachend");
llvm::BranchInst::Create(condbb, irs->scopebb());
@ -1433,14 +1374,10 @@ public:
}
// set up the block we'll need
llvm::BasicBlock *condbb = llvm::BasicBlock::Create(
irs->context(), "foreachrange_cond", irs->topfunc());
llvm::BasicBlock *bodybb = llvm::BasicBlock::Create(
irs->context(), "foreachrange_body", irs->topfunc());
llvm::BasicBlock *nextbb = llvm::BasicBlock::Create(
irs->context(), "foreachrange_next", irs->topfunc());
llvm::BasicBlock *endbb = llvm::BasicBlock::Create(
irs->context(), "foreachrange_end", irs->topfunc());
llvm::BasicBlock *condbb = irs->insertBB("foreachrange_cond");
llvm::BasicBlock *bodybb = irs->insertBBAfter(condbb, "foreachrange_body");
llvm::BasicBlock *nextbb = irs->insertBBAfter(bodybb, "foreachrange_next");
llvm::BasicBlock *endbb = irs->insertBBAfter(nextbb, "foreachrange_end");
// jump to condition
llvm::BranchInst::Create(condbb, irs->scopebb());
@ -1538,9 +1475,8 @@ public:
// disable inlining
irs->func()->setNeverInline();
} else {
llvm::BasicBlock *labelBB = llvm::BasicBlock::Create(
irs->context(), llvm::Twine("label.") + stmt->ident->toChars(),
irs->topfunc());
llvm::BasicBlock *labelBB =
irs->insertBB(llvm::Twine("label.") + stmt->ident->toChars());
irs->funcGen().scopes.addLabelTarget(stmt->ident, labelBB);
if (!irs->scopereturned()) {
@ -1573,8 +1509,7 @@ public:
DtoGoto(stmt->loc, stmt->label);
// TODO: Should not be needed.
llvm::BasicBlock *bb =
llvm::BasicBlock::Create(irs->context(), "aftergoto", irs->topfunc());
llvm::BasicBlock *bb = irs->insertBB("aftergoto");
irs->scope() = IRScope(bb);
}
@ -1599,8 +1534,7 @@ public:
llvm::BranchInst::Create(defaultBB, irs->scopebb());
// TODO: Should not be needed.
llvm::BasicBlock *bb = llvm::BasicBlock::Create(
irs->context(), "aftergotodefault", irs->topfunc());
llvm::BasicBlock *bb = irs->insertBB("aftergotodefault");
irs->scope() = IRScope(bb);
}
@ -1626,8 +1560,7 @@ public:
llvm::BranchInst::Create(caseBB, irs->scopebb());
// TODO: Should not be needed.
llvm::BasicBlock *bb = llvm::BasicBlock::Create(
irs->context(), "aftergotocase", irs->topfunc());
llvm::BasicBlock *bb = irs->insertBB("aftergotocase");
irs->scope() = IRScope(bb);
}

View file

@ -180,8 +180,7 @@ static void write_struct_literal(Loc loc, LLValue *mem, StructDeclaration *sd,
namespace {
void pushVarDtorCleanup(IRState *p, VarDeclaration *vd) {
llvm::BasicBlock *beginBB = llvm::BasicBlock::Create(
p->context(), llvm::Twine("dtor.") + vd->toChars(), p->topfunc());
llvm::BasicBlock *beginBB = p->insertBB(llvm::Twine("dtor.") + vd->toChars());
// TODO: Clean this up with push/pop insertion point methods.
IRScope oldScope = p->scope();
@ -246,8 +245,7 @@ public:
}
}
llvm::BasicBlock *endbb = llvm::BasicBlock::Create(
p->context(), "toElem.success", p->topfunc());
llvm::BasicBlock *endbb = p->insertBB("toElem.success");
p->funcGen().scopes.runCleanups(initialCleanupScope, endbb);
p->funcGen().scopes.popCleanups(initialCleanupScope);
p->scope() = IRScope(endbb);
@ -1094,10 +1092,8 @@ public:
(etype->ty != Tpointer) && !e->upperIsInBounds;
const bool needCheckLower = !e->lowerIsLessThanUpper;
if (p->emitArrayBoundsChecks() && (needCheckUpper || needCheckLower)) {
llvm::BasicBlock *failbb =
llvm::BasicBlock::Create(p->context(), "bounds.fail", p->topfunc());
llvm::BasicBlock *okbb =
llvm::BasicBlock::Create(p->context(), "bounds.ok", p->topfunc());
llvm::BasicBlock *okbb = p->insertBB("bounds.ok");
llvm::BasicBlock *failbb = p->insertBBAfter(okbb, "bounds.fail");
llvm::Value *okCond = nullptr;
if (needCheckUpper) {
@ -1254,12 +1250,9 @@ public:
llvm::Value *lhs = DtoRVal(l);
llvm::Value *rhs = DtoRVal(r);
llvm::BasicBlock *fptreq =
llvm::BasicBlock::Create(gIR->context(), "fptreq", gIR->topfunc());
llvm::BasicBlock *fptrneq =
llvm::BasicBlock::Create(gIR->context(), "fptrneq", gIR->topfunc());
llvm::BasicBlock *dgcmpend = llvm::BasicBlock::Create(
gIR->context(), "dgcmpend", gIR->topfunc());
llvm::BasicBlock *fptreq = p->insertBB("fptreq");
llvm::BasicBlock *fptrneq = p->insertBBAfter(fptreq, "fptrneq");
llvm::BasicBlock *dgcmpend = p->insertBBAfter(fptrneq, "dgcmpend");
llvm::Value *lfptr = p->ir->CreateExtractValue(lhs, 1, ".lfptr");
llvm::Value *rfptr = p->ir->CreateExtractValue(rhs, 1, ".rfptr");
@ -1634,10 +1627,8 @@ public:
}
// create basic blocks
llvm::BasicBlock *passedbb =
llvm::BasicBlock::Create(gIR->context(), "assertPassed", p->topfunc());
llvm::BasicBlock *failedbb =
llvm::BasicBlock::Create(gIR->context(), "assertFailed", p->topfunc());
llvm::BasicBlock *passedbb = p->insertBB("assertPassed");
llvm::BasicBlock *failedbb = p->insertBBAfter(passedbb, "assertFailed");
// test condition
LLValue *condval = DtoRVal(DtoCast(e->loc, cond, Type::tbool));
@ -1720,10 +1711,8 @@ public:
DValue *u = toElem(e->e1);
llvm::BasicBlock *andand =
llvm::BasicBlock::Create(gIR->context(), "andand", gIR->topfunc());
llvm::BasicBlock *andandend =
llvm::BasicBlock::Create(gIR->context(), "andandend", gIR->topfunc());
llvm::BasicBlock *andand = p->insertBB("andand");
llvm::BasicBlock *andandend = p->insertBBAfter(andand, "andandend");
LLValue *ubool = DtoRVal(DtoCast(e->loc, u, Type::tbool));
@ -1782,10 +1771,8 @@ public:
DValue *u = toElem(e->e1);
llvm::BasicBlock *oror =
llvm::BasicBlock::Create(gIR->context(), "oror", gIR->topfunc());
llvm::BasicBlock *ororend =
llvm::BasicBlock::Create(gIR->context(), "ororend", gIR->topfunc());
llvm::BasicBlock *oror = p->insertBB("oror");
llvm::BasicBlock *ororend = p->insertBBAfter(oror, "ororend");
LLValue *ubool = DtoRVal(DtoCast(e->loc, u, Type::tbool));
@ -1848,8 +1835,7 @@ public:
// this terminated the basicblock, start a new one
// this is sensible, since someone might goto behind the assert
// and prevents compiler errors if a terminator follows the assert
llvm::BasicBlock *bb =
llvm::BasicBlock::Create(gIR->context(), "afterhalt", p->topfunc());
llvm::BasicBlock *bb = p->insertBB("afterhalt");
p->scope() = IRScope(bb);
}
@ -2016,12 +2002,9 @@ public:
retPtr = DtoAlloca(dtype->pointerTo(), "condtmp");
}
llvm::BasicBlock *condtrue =
llvm::BasicBlock::Create(gIR->context(), "condtrue", gIR->topfunc());
llvm::BasicBlock *condfalse =
llvm::BasicBlock::Create(gIR->context(), "condfalse", gIR->topfunc());
llvm::BasicBlock *condend =
llvm::BasicBlock::Create(gIR->context(), "condend", gIR->topfunc());
llvm::BasicBlock *condtrue = p->insertBB("condtrue");
llvm::BasicBlock *condfalse = p->insertBBAfter(condtrue, "condfalse");
llvm::BasicBlock *condend = p->insertBBAfter(condfalse, "condend");
DValue *c = toElem(e->econd);
LLValue *cond_val = DtoRVal(DtoCast(e->loc, c, Type::tbool));

View file

@ -93,8 +93,7 @@ void emitBeginCatchMSVC(IRState &irs, Catch *ctch, llvm::BasicBlock *endbb,
// Exceptions are never rethrown by D code (but thrown again), so
// we can leave the catch handler right away and continue execution
// outside the catch funclet
llvm::BasicBlock *catchhandler =
llvm::BasicBlock::Create(irs.context(), "catchhandler", irs.topfunc());
llvm::BasicBlock *catchhandler = irs.insertBB("catchhandler");
llvm::CatchReturnInst::Create(catchpad, catchhandler, irs.scopebb());
irs.scope() = IRScope(catchhandler);
auto enterCatchFn =
@ -172,10 +171,8 @@ void TryCatchScope::emitCatchBodies(IRState &irs) {
cbPrototypes.reserve(stmt->catches->dim);
for (auto c : *stmt->catches) {
auto catchBB = llvm::BasicBlock::Create(
irs.context(), llvm::Twine("catch.") + c->type->toChars(),
irs.topfunc(), endbb);
auto catchBB =
irs.insertBBBefore(endbb, llvm::Twine("catch.") + c->type->toChars());
irs.scope() = IRScope(catchBB);
irs.DBuilder.EmitBlockStart(c->loc);
PGO.emitCounterIncrement(c);
@ -246,8 +243,7 @@ void TryCatchScope::emitCatchBodiesMSVC(IRState &irs) {
auto &PGO = irs.funcGen().pgo;
auto &scopes = irs.funcGen().scopes;
auto catchSwitchBlock =
llvm::BasicBlock::Create(irs.context(), "catch.dispatch", irs.topfunc());
auto catchSwitchBlock = irs.insertBBBefore(endbb, "catch.dispatch");
llvm::BasicBlock *unwindto =
scopes.currentCleanupScope() > 0 ? scopes.getLandingPad() : nullptr;
auto catchSwitchInst = llvm::CatchSwitchInst::Create(
@ -255,9 +251,8 @@ void TryCatchScope::emitCatchBodiesMSVC(IRState &irs) {
"", catchSwitchBlock);
for (auto c : *stmt->catches) {
auto catchBB = llvm::BasicBlock::Create(
irs.context(), llvm::Twine("catch.") + c->type->toChars(),
irs.topfunc(), endbb);
auto catchBB =
irs.insertBBBefore(endbb, llvm::Twine("catch.") + c->type->toChars());
irs.scope() = IRScope(catchBB);
irs.DBuilder.EmitBlockStart(c->loc);
@ -330,8 +325,7 @@ llvm::BasicBlock *TryCatchScopes::emitLandingPad() {
// save and rewrite scope
IRScope savedIRScope = irs.scope();
llvm::BasicBlock *beginBB =
llvm::BasicBlock::Create(irs.context(), "landingPad", irs.topfunc());
llvm::BasicBlock *beginBB = irs.insertBB("landingPad");
irs.scope() = IRScope(beginBB);
llvm::LandingPadInst *landingPad = createLandingPadInst(irs);
@ -361,9 +355,8 @@ llvm::BasicBlock *TryCatchScopes::emitLandingPad() {
assert(lastCleanup >= newCleanup);
if (lastCleanup > newCleanup) {
landingPad->setCleanup(true);
llvm::BasicBlock *afterCleanupBB = llvm::BasicBlock::Create(
irs.context(), beginBB->getName() + llvm::Twine(".after.cleanup"),
irs.topfunc());
llvm::BasicBlock *afterCleanupBB =
irs.insertBB(beginBB->getName() + llvm::Twine(".after.cleanup"));
scopes.runCleanups(lastCleanup, newCleanup, afterCleanupBB);
irs.scope() = IRScope(afterCleanupBB);
lastCleanup = newCleanup;
@ -374,9 +367,8 @@ llvm::BasicBlock *TryCatchScopes::emitLandingPad() {
// emitted to the EH tables.
landingPad->addClause(cb.classInfoPtr);
llvm::BasicBlock *mismatchBB = llvm::BasicBlock::Create(
irs.context(), beginBB->getName() + llvm::Twine(".mismatch"),
irs.topfunc());
llvm::BasicBlock *mismatchBB =
irs.insertBB(beginBB->getName() + llvm::Twine(".mismatch"));
// "Call" llvm.eh.typeid.for, which gives us the eh selector value to
// compare the landing pad selector value with.
@ -395,18 +387,17 @@ llvm::BasicBlock *TryCatchScopes::emitLandingPad() {
}
// No catch matched. Execute all finallys and resume unwinding.
auto resumeUnwindBlock = irs.funcGen().getOrCreateResumeUnwindBlock();
if (lastCleanup > 0) {
landingPad->setCleanup(true);
scopes.runCleanups(lastCleanup, 0,
irs.funcGen().getOrCreateResumeUnwindBlock());
scopes.runCleanups(lastCleanup, 0, resumeUnwindBlock);
} else if (!tryCatchScopes.empty()) {
// Directly convert the last mismatch branch into a branch to the
// unwind resume block.
irs.scopebb()->replaceAllUsesWith(
irs.funcGen().getOrCreateResumeUnwindBlock());
irs.scopebb()->replaceAllUsesWith(resumeUnwindBlock);
irs.scopebb()->eraseFromParent();
} else {
irs.ir->CreateBr(irs.funcGen().getOrCreateResumeUnwindBlock());
irs.ir->CreateBr(resumeUnwindBlock);
}
irs.scope() = savedIRScope;

View file

@ -78,28 +78,23 @@ void try_catch() {
if (i) {} // 1 : 1 (branch taken)
}
// ExceptionTwo 1st BB:
// PROFGEN: store {{.*}} @[[TC]], i64 0, i64 3
// ExceptionThree 1st BB:
// PROFGEN: store {{.*}} @[[TC]], i64 0, i64 4
// ExceptionTwo 2nd BB: if(i)
// PROFGEN: store {{.*}} @[[TC]], i64 0, i64 7
// ExceptionThree 2nd BB: if(i)
// PROFGEN: store {{.*}} @[[TC]], i64 0, i64 8
// Try body 2nd BB: if(i < 2)
// Try body: if(i < 2)
// PROFGEN: store {{.*}} @[[TC]], i64 0, i64 5
// Landingpad stuff:
// No counter increments
// More try body: if(i < 5)
// PROFGEN: store {{.*}} @[[TC]], i64 0, i64 6
// ExceptionTwo body:
// PROFGEN: store {{.*}} @[[TC]], i64 0, i64 3
// More ExceptionTwo body: if(i)
// PROFGEN: store {{.*}} @[[TC]], i64 0, i64 7
// ExceptionThree body:
// PROFGEN: store {{.*}} @[[TC]], i64 0, i64 4
// More ExceptionThree body: if(i)
// PROFGEN: store {{.*}} @[[TC]], i64 0, i64 8
// Try end:
// PROFGEN: store {{.*}} @[[TC]], i64 0, i64 2
// Try body: if(i < 2)
// PROFUSE: br {{.*}} !prof ![[TC5:[0-9]+]]
// Exception handlers: if(i){}
// PROFUSE: br {{.*}} !prof ![[TC7:[0-9]+]]
// PROFUSE: br {{.*}} !prof ![[TC8:[0-9]+]]
// More try body: if(i < 5)
// PROFUSE: br {{.*}} !prof ![[TC6:[0-9]+]]
// Landingpad stuff:
@ -107,6 +102,9 @@ void try_catch() {
// PROFUSE: br {{.*}} !prof ![[TC3:[0-9]+]]
// Match ExceptionThree:
// PROFUSE: br {{.*}} !prof ![[TC4:[0-9]+]]
// Catch bodies: if(i)
// PROFUSE: br {{.*}} !prof ![[TC7:[0-9]+]]
// PROFUSE: br {{.*}} !prof ![[TC8:[0-9]+]]
}
}
@ -149,10 +147,10 @@ void main() {
// PROFUSE-DAG: ![[TC0]] = !{!"function_entry_count", i64 1}
// PROFUSE-DAG: ![[TC1]] = !{!"branch_weights", i32 7, i32 1}
// PROFUSE-DAG: ![[TC5]] = !{!"branch_weights", i32 3, i32 5}
// PROFUSE-DAG: ![[TC8]] = !{!"branch_weights", i32 2, i32 2}
// PROFUSE-DAG: ![[TC7]] = !{!"branch_weights", i32 4, i32 1}
// PROFUSE-DAG: ![[TC6]] = !{!"branch_weights", i32 4, i32 2}
// PROFUSE-DAG: ![[TC3]] = !{!"branch_weights", i32 4, i32 4}
// PROFUSE-DAG: ![[TC7]] = !{!"branch_weights", i32 4, i32 1}
// PROFUSE-DAG: ![[TC4]] = !{!"branch_weights", i32 3, i32 2}
// PROFUSE-DAG: ![[TC8]] = !{!"branch_weights", i32 2, i32 2}
// PROFUSE-DAG: ![[SCP0]] = !{!"function_entry_count", i64 2}