Skip to content

Commit 8cb4456

Browse files
committed
OpaqueArchetypeSpecializer: Fixup switch_enum successor blocks
rdar://50589978
1 parent 558cc63 commit 8cb4456

File tree

1 file changed

+42
-16
lines changed

1 file changed

+42
-16
lines changed

lib/SILOptimizer/Transforms/SpecializeOpaqueArchetypes.cpp

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,31 @@ class OpaqueSpecializerCloner
348348
}
349349
}
350350

351+
void replaceBlockArgumentType(SILLocation loc, SILBasicBlock *destBlock,
352+
SILType withType) {
353+
assert(destBlock->getArguments().size() == 1);
354+
355+
auto origType = (*destBlock->args_begin())->getType();
356+
auto origPhi = destBlock->getPhiArguments()[0];
357+
SILValue undef = SILUndef::get(origType, getBuilder().getFunction());
358+
SmallVector<Operand *, 8> useList(origPhi->use_begin(), origPhi->use_end());
359+
for (auto *use : useList) {
360+
use->set(undef);
361+
}
362+
363+
auto *newPhi =
364+
destBlock->replacePhiArgument(0, withType, origPhi->getOwnershipKind());
365+
366+
getBuilder().setInsertionPoint(destBlock->begin());
367+
auto cast = createCast(loc, newPhi, origType);
368+
for (auto *use : useList) {
369+
use->set(cast);
370+
}
371+
}
372+
351373
void fixUp(SILFunction *) {
352-
for (auto &BB : getBuilder().getFunction()) {
374+
auto &clonedFunction = getBuilder().getFunction();
375+
for (auto &BB : clonedFunction) {
353376
for (auto &cloned : BB) {
354377
// Fix up the type of try_apply successor block arguments.
355378
if (auto *tryApply = dyn_cast<TryApplyInst>(&cloned)) {
@@ -360,22 +383,25 @@ class OpaqueSpecializerCloner
360383
auto normalBBType = (*normalBB->args_begin())->getType();
361384
auto applyResultType = calleeConv.getSILResultType();
362385
if (normalBBType != calleeConv.getSILResultType()) {
363-
auto origPhi = normalBB->getPhiArguments()[0];
364-
SILValue undef =
365-
SILUndef::get(normalBBType, getBuilder().getFunction());
366-
SmallVector<Operand *, 8> useList(origPhi->use_begin(),
367-
origPhi->use_end());
368-
for (auto *use : useList) {
369-
use->set(undef);
370-
}
371-
372-
auto *newPhi = normalBB->replacePhiArgument(
373-
0, applyResultType, origPhi->getOwnershipKind());
386+
replaceBlockArgumentType(tryApply->getLoc(), normalBB, applyResultType);
387+
}
388+
}
389+
// Fix up the type of switch_enum successor block arguments.
390+
if (auto *switchEnum = dyn_cast<SwitchEnumInst>(&cloned)) {
391+
SILType enumTy = switchEnum->getOperand()->getType();
392+
for (unsigned i = 0, e = switchEnum->getNumCases(); i < e; ++i) {
393+
EnumElementDecl *elt;
394+
SILBasicBlock *dest;
395+
std::tie(elt, dest) = switchEnum->getCase(i);
396+
397+
if (elt->hasAssociatedValues() &&
398+
dest->getArguments().size() == 1) {
399+
SILType eltArgTy =
400+
enumTy.getEnumElementType(elt, clonedFunction.getModule());
401+
SILType bbArgTy = dest->getArguments()[0]->getType();
402+
if (eltArgTy != bbArgTy)
403+
replaceBlockArgumentType(switchEnum->getLoc(), dest, eltArgTy);
374404

375-
getBuilder().setInsertionPoint(normalBB->begin());
376-
auto cast = createCast(tryApply->getLoc(), newPhi, normalBBType);
377-
for (auto *use : useList) {
378-
use->set(cast);
379405
}
380406
}
381407
}

0 commit comments

Comments
 (0)