mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 09:00:33 +03:00
Refactor basic block construction and revise BB order
This commit is contained in:
parent
583aab933b
commit
e711deac1b
11 changed files with 161 additions and 246 deletions
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
51
gen/toir.cpp
51
gen/toir.cpp
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue