Skip to content

Commit aa43c26

Browse files
committed
SILGen: Split up Emission.getSharedCaseBlockDest()
1 parent c286170 commit aa43c26

File tree

1 file changed

+47
-36
lines changed

1 file changed

+47
-36
lines changed

lib/SILGen/SILGenPattern.cpp

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,10 @@ class PatternMatchEmission {
422422
void emitDispatch(ClauseMatrix &matrix, ArgArray args,
423423
const FailureHandler &failure);
424424

425-
JumpDest getSharedCaseBlockDest(CaseStmt *caseStmt, bool hasFallthroughTo);
425+
void initSharedCaseBlockDest(CaseStmt *caseBlock, bool hasFallthroughTo);
426+
427+
JumpDest getSharedCaseBlockDest(CaseStmt *caseStmt);
428+
426429
void emitSharedCaseBlocks();
427430

428431
void emitCaseBody(CaseStmt *caseBlock);
@@ -2324,45 +2327,43 @@ void PatternMatchEmission::emitCaseBody(CaseStmt *caseBlock) {
23242327
}
23252328
}
23262329

2327-
/// Retrieve the jump destination for a shared case block.
2328-
JumpDest PatternMatchEmission::getSharedCaseBlockDest(CaseStmt *caseBlock,
2329-
bool hasFallthroughTo) {
2330+
void PatternMatchEmission::initSharedCaseBlockDest(CaseStmt *caseBlock,
2331+
bool hasFallthroughTo) {
23302332
auto result = SharedCases.insert({caseBlock, {nullptr, hasFallthroughTo}});
2333+
assert(result.second);
23312334

2332-
// If there's already an entry, use that.
2333-
SILBasicBlock *block;
2334-
if (!result.second) {
2335-
block = result.first->second.first;
2336-
assert(block);
2337-
} else {
2338-
// Create the shared destination at the first place that might
2339-
// have needed it.
2340-
block = SGF.createBasicBlock();
2341-
result.first->second.first = block;
2335+
auto *block = SGF.createBasicBlock();
2336+
result.first->second.first = block;
23422337

2343-
// Add args for any pattern variables
2344-
if (caseBlock->hasBoundDecls()) {
2345-
auto pattern = caseBlock->getCaseLabelItems()[0].getPattern();
2346-
pattern->forEachVariable([&](VarDecl *V) {
2347-
if (!V->hasName())
2348-
return;
2349-
// We should never PHI addresses. To eliminate that possibility, we:
2350-
//
2351-
// 1. Load all loadable types and pass them as objects to the block.
2352-
// 2. We do not emit arguments for address only types. We instead just
2353-
// assign SILUndef to the VarLoc.
2354-
SILType ty = SGF.getLoweredType(V->getType());
2355-
if (ty.isAddressOnly(SGF.F.getModule()))
2356-
return;
2357-
block->createPHIArgument(ty, ValueOwnershipKind::Owned, V);
2358-
});
2359-
}
2338+
// Add args for any pattern variables
2339+
if (caseBlock->hasBoundDecls()) {
2340+
auto pattern = caseBlock->getCaseLabelItems()[0].getPattern();
2341+
pattern->forEachVariable([&](VarDecl *V) {
2342+
if (!V->hasName())
2343+
return;
2344+
2345+
// We don't pass address-only values in basic block arguments.
2346+
SILType ty = SGF.getLoweredType(V->getType());
2347+
if (ty.isAddressOnly(SGF.F.getModule()))
2348+
return;
2349+
block->createPHIArgument(ty, ValueOwnershipKind::Owned, V);
2350+
});
23602351
}
2352+
}
2353+
2354+
/// Retrieve the jump destination for a shared case block.
2355+
JumpDest PatternMatchEmission::getSharedCaseBlockDest(CaseStmt *caseBlock) {
2356+
auto result = SharedCases.find(caseBlock);
2357+
assert(result != SharedCases.end());
2358+
2359+
auto *block = result->second.first;
2360+
assert(block);
23612361

23622362
return JumpDest(block, PatternMatchStmtDepth,
23632363
CleanupLocation(PatternMatchStmt));
23642364
}
23652365

2366+
23662367
/// Emit all the shared case statements.
23672368
void PatternMatchEmission::emitSharedCaseBlocks() {
23682369
for (auto &entry: SharedCases) {
@@ -2386,8 +2387,13 @@ void PatternMatchEmission::emitSharedCaseBlocks() {
23862387
SGF.B.setInsertionPoint(predBB);
23872388

23882389
} else {
2390+
// FIXME: Figure out why this is necessary.
2391+
if (caseBB->pred_empty()) {
2392+
SGF.eraseBasicBlock(caseBB);
2393+
continue;
2394+
}
2395+
23892396
// Otherwise, move the block to after the first predecessor.
2390-
assert(!caseBB->pred_empty() && "Emitted an unused shared block?");
23912397
auto predBB = *caseBB->pred_begin();
23922398
caseBB->moveAfter(predBB);
23932399

@@ -2593,12 +2599,11 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) {
25932599
if (!caseBlock->hasBoundDecls()) {
25942600
// Don't emit anything yet, we emit it at the cleanup level of the switch
25952601
// statement.
2596-
JumpDest sharedDest = emission.getSharedCaseBlockDest(caseBlock,
2597-
row.hasFallthroughTo());
2602+
JumpDest sharedDest = emission.getSharedCaseBlockDest(caseBlock);
25982603
Cleanups.emitBranchAndCleanups(sharedDest, caseBlock);
25992604
} else if (caseBlock->getCaseLabelItems().size() > 1) {
26002605
JumpDest sharedDest =
2601-
emission.getSharedCaseBlockDest(caseBlock, row.hasFallthroughTo());
2606+
emission.getSharedCaseBlockDest(caseBlock);
26022607

26032608
// Generate the arguments from this row's pattern in the case block's expected order,
26042609
// and keep those arguments from being cleaned up, as we're passing the +1 along to
@@ -2679,6 +2684,12 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) {
26792684
clauseRows.reserve(S->getRawCases().size());
26802685
bool hasFallthrough = false;
26812686
for (auto caseBlock : S->getCases()) {
2687+
if (!caseBlock->hasBoundDecls() ||
2688+
caseBlock->getCaseLabelItems().size() > 1 ||
2689+
hasFallthrough) {
2690+
emission.initSharedCaseBlockDest(caseBlock, hasFallthrough);
2691+
}
2692+
26822693
for (auto &labelItem : caseBlock->getCaseLabelItems()) {
26832694
clauseRows.emplace_back(caseBlock,
26842695
const_cast<Pattern*>(labelItem.getPattern()),
@@ -2721,7 +2732,7 @@ void SILGenFunction::emitSwitchFallthrough(FallthroughStmt *S) {
27212732
// Get the destination block.
27222733
CaseStmt *caseStmt = S->getFallthroughDest();
27232734
JumpDest sharedDest =
2724-
context->Emission.getSharedCaseBlockDest(caseStmt, true);
2735+
context->Emission.getSharedCaseBlockDest(caseStmt);
27252736
Cleanups.emitBranchAndCleanups(sharedDest, S);
27262737
}
27272738

0 commit comments

Comments
 (0)