@@ -353,8 +353,31 @@ class OpaqueSpecializerCloner
353
353
}
354
354
}
355
355
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
+
356
378
void fixUp (SILFunction *) {
357
- for (auto &BB : getBuilder ().getFunction ()) {
379
+ auto &clonedFunction = getBuilder ().getFunction ();
380
+ for (auto &BB : clonedFunction) {
358
381
for (auto &cloned : BB) {
359
382
// Fix up the type of try_apply successor block arguments.
360
383
if (auto *tryApply = dyn_cast<TryApplyInst>(&cloned)) {
@@ -365,22 +388,25 @@ class OpaqueSpecializerCloner
365
388
auto normalBBType = (*normalBB->args_begin ())->getType ();
366
389
auto applyResultType = calleeConv.getSILResultType ();
367
390
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);
379
409
380
- getBuilder ().setInsertionPoint (normalBB->begin ());
381
- auto cast = createCast (tryApply->getLoc (), newPhi, normalBBType);
382
- for (auto *use : useList) {
383
- use->set (cast);
384
410
}
385
411
}
386
412
}
0 commit comments