@@ -348,8 +348,31 @@ class OpaqueSpecializerCloner
348
348
}
349
349
}
350
350
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
+
351
373
void fixUp (SILFunction *) {
352
- for (auto &BB : getBuilder ().getFunction ()) {
374
+ auto &clonedFunction = getBuilder ().getFunction ();
375
+ for (auto &BB : clonedFunction) {
353
376
for (auto &cloned : BB) {
354
377
// Fix up the type of try_apply successor block arguments.
355
378
if (auto *tryApply = dyn_cast<TryApplyInst>(&cloned)) {
@@ -360,22 +383,25 @@ class OpaqueSpecializerCloner
360
383
auto normalBBType = (*normalBB->args_begin ())->getType ();
361
384
auto applyResultType = calleeConv.getSILResultType ();
362
385
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);
374
404
375
- getBuilder ().setInsertionPoint (normalBB->begin ());
376
- auto cast = createCast (tryApply->getLoc (), newPhi, normalBBType);
377
- for (auto *use : useList) {
378
- use->set (cast);
379
405
}
380
406
}
381
407
}
0 commit comments