Skip to content

Commit 6b12277

Browse files
committed
OpaqueArchetypeSpecializer: Fixup switch_enum successor blocks
rdar://50589978
1 parent a6d1e83 commit 6b12277

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
@@ -353,8 +353,31 @@ class OpaqueSpecializerCloner
353353
}
354354
}
355355

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

380-
getBuilder().setInsertionPoint(normalBB->begin());
381-
auto cast = createCast(tryApply->getLoc(), newPhi, normalBBType);
382-
for (auto *use : useList) {
383-
use->set(cast);
384410
}
385411
}
386412
}

0 commit comments

Comments
 (0)