@@ -2482,6 +2482,74 @@ class CheckedCastBrRewriter {
2482
2482
}
2483
2483
};
2484
2484
2485
+ // ===----------------------------------------------------------------------===//
2486
+ // unconditional_checked_cast rewriting
2487
+ //
2488
+ // Rewrites an unconditional_checked_cast to an address instruction.
2489
+ // ===----------------------------------------------------------------------===//
2490
+
2491
+ static UnconditionalCheckedCastAddrInst *rewriteUnconditionalCheckedCastInst (
2492
+ UnconditionalCheckedCastInst *uncondCheckedCast, AddressLoweringState &pass,
2493
+ AddressMaterialization *addrMat) {
2494
+ auto srcVal = uncondCheckedCast->getOperand ();
2495
+ auto destVal = SILValue (uncondCheckedCast);
2496
+ auto srcType = srcVal->getType ();
2497
+ auto destType = destVal->getType ();
2498
+ // There are four cases to handle:
2499
+ // - source address-only, target address-only
2500
+ // - source address-only, target loadable
2501
+ // - source loadable, target address-only
2502
+ // - source loadable, target loadable
2503
+ auto srcAddrOnly = srcType.isAddressOnly (*pass.function );
2504
+ auto destAddrOnly = destType.isAddressOnly (*pass.function );
2505
+ SILValue srcAddr;
2506
+
2507
+ auto loc = uncondCheckedCast->getLoc ();
2508
+
2509
+ auto builder = pass.getBuilder (uncondCheckedCast->getIterator ());
2510
+ if (srcAddrOnly) {
2511
+ srcAddr = pass.valueStorageMap .getStorage (srcVal).storageAddress ;
2512
+ } else {
2513
+ srcAddr = builder.createAllocStack (loc, srcType);
2514
+ builder.createStore (loc, srcVal, srcAddr,
2515
+ srcType.isTrivial (*pass.function )
2516
+ ? StoreOwnershipQualifier::Trivial
2517
+ : StoreOwnershipQualifier::Init);
2518
+ }
2519
+ assert (srcAddr);
2520
+ SILValue destAddr;
2521
+ if (destAddrOnly) {
2522
+ destAddr = addrMat->materializeAddress (destVal);
2523
+ } else {
2524
+ destAddr = builder.createAllocStack (loc, destType);
2525
+ }
2526
+ assert (destAddr);
2527
+ auto *uccai = builder.createUnconditionalCheckedCastAddr (
2528
+ uncondCheckedCast->getLoc (), srcAddr, srcAddr->getType ().getASTType (),
2529
+ destAddr, destAddr->getType ().getASTType ());
2530
+ auto afterBuilder =
2531
+ pass.getBuilder (uncondCheckedCast->getNextInstruction ()->getIterator ());
2532
+ if (srcAddrOnly) {
2533
+ // No cleanup to do.
2534
+ } else {
2535
+ afterBuilder.createDeallocStack (loc, srcAddr);
2536
+ }
2537
+ if (destAddrOnly) {
2538
+ // No cleanup to do.
2539
+ } else {
2540
+ auto *load = afterBuilder.createLoad (loc, destAddr,
2541
+ destType.isTrivial (*pass.function )
2542
+ ? LoadOwnershipQualifier::Trivial
2543
+ : LoadOwnershipQualifier::Take);
2544
+ destVal->replaceAllUsesWith (load);
2545
+ afterBuilder.createDeallocStack (loc, destAddr);
2546
+ }
2547
+ if (!srcAddrOnly && !destAddrOnly) {
2548
+ pass.deleter .forceDelete (uncondCheckedCast);
2549
+ }
2550
+ return uccai;
2551
+ }
2552
+
2485
2553
// ===----------------------------------------------------------------------===//
2486
2554
// ReturnRewriter
2487
2555
//
@@ -2721,13 +2789,16 @@ void YieldRewriter::rewriteOperand(YieldInst *yieldInst, unsigned index) {
2721
2789
}
2722
2790
}
2723
2791
2792
+ //
2793
+
2724
2794
// ===----------------------------------------------------------------------===//
2725
2795
// UseRewriter
2726
2796
//
2727
2797
// Rewrite opaque value uses in forward order--uses are rewritten before defs.
2728
2798
// ===----------------------------------------------------------------------===//
2729
2799
2730
2800
namespace {
2801
+
2731
2802
class UseRewriter : SILInstructionVisitor<UseRewriter> {
2732
2803
friend SILVisitorBase<UseRewriter>;
2733
2804
friend SILInstructionVisitor<UseRewriter>;
@@ -2996,7 +3067,15 @@ class UseRewriter : SILInstructionVisitor<UseRewriter> {
2996
3067
}
2997
3068
2998
3069
void visitUnconditionalCheckedCastInst (
2999
- UnconditionalCheckedCastInst *uncondCheckedCast);
3070
+ UnconditionalCheckedCastInst *uncondCheckedCast) {
3071
+ assert (uncondCheckedCast->getOperand ()->getType ().isAddressOnly (
3072
+ *pass.function ));
3073
+ auto *uccai =
3074
+ rewriteUnconditionalCheckedCastInst (uncondCheckedCast, pass, &addrMat);
3075
+ if (uncondCheckedCast->getType ().isAddressOnly (*pass.function )) {
3076
+ markRewritten (uncondCheckedCast, uccai->getDest ());
3077
+ }
3078
+ }
3000
3079
3001
3080
void visitCheckedCastBranchInst (CheckedCastBranchInst *checkedCastBranch);
3002
3081
@@ -3290,38 +3369,6 @@ void UseRewriter::visitUncheckedEnumDataInst(
3290
3369
markRewritten (enumDataInst, enumAddrInst);
3291
3370
}
3292
3371
3293
- void UseRewriter::visitUnconditionalCheckedCastInst (
3294
- UnconditionalCheckedCastInst *uncondCheckedCast) {
3295
- SILValue srcVal = uncondCheckedCast->getOperand ();
3296
- assert (srcVal->getType ().isAddressOnly (*pass.function ));
3297
- SILValue srcAddr = pass.valueStorageMap .getStorage (srcVal).storageAddress ;
3298
-
3299
- if (uncondCheckedCast->getType ().isAddressOnly (*pass.function )) {
3300
- // When cast destination has address only type, use the storage address
3301
- SILValue destAddr = addrMat.materializeAddress (uncondCheckedCast);
3302
- markRewritten (uncondCheckedCast, destAddr);
3303
- builder.createUnconditionalCheckedCastAddr (
3304
- uncondCheckedCast->getLoc (), srcAddr, srcAddr->getType ().getASTType (),
3305
- destAddr, destAddr->getType ().getASTType ());
3306
- return ;
3307
- }
3308
- // For loadable cast destination type, create a stack temporary
3309
- SILValue destAddr = builder.createAllocStack (uncondCheckedCast->getLoc (),
3310
- uncondCheckedCast->getType ());
3311
- builder.createUnconditionalCheckedCastAddr (
3312
- uncondCheckedCast->getLoc (), srcAddr, srcAddr->getType ().getASTType (),
3313
- destAddr, destAddr->getType ().getASTType ());
3314
- auto nextBuilder =
3315
- pass.getBuilder (uncondCheckedCast->getNextInstruction ()->getIterator ());
3316
- auto dest = nextBuilder.createLoad (
3317
- uncondCheckedCast->getLoc (), destAddr,
3318
- destAddr->getType ().isTrivial (*uncondCheckedCast->getFunction ())
3319
- ? LoadOwnershipQualifier::Trivial
3320
- : LoadOwnershipQualifier::Take);
3321
- nextBuilder.createDeallocStack (uncondCheckedCast->getLoc (), destAddr);
3322
- uncondCheckedCast->replaceAllUsesWith (dest);
3323
- }
3324
-
3325
3372
// ===----------------------------------------------------------------------===//
3326
3373
// DefRewriter
3327
3374
//
@@ -3508,25 +3555,11 @@ class DefRewriter : SILInstructionVisitor<DefRewriter> {
3508
3555
3509
3556
void visitUnconditionalCheckedCastInst (
3510
3557
UnconditionalCheckedCastInst *uncondCheckedCast) {
3511
- SILValue srcVal = uncondCheckedCast->getOperand ();
3512
- assert (srcVal-> getType (). isLoadable ( *pass.function ));
3558
+ assert (! uncondCheckedCast->getOperand ()-> getType (). isAddressOnly (
3559
+ *pass.function ));
3513
3560
assert (uncondCheckedCast->getType ().isAddressOnly (*pass.function ));
3514
3561
3515
- // Create a stack temporary to store the srcVal
3516
- SILValue srcAddr = builder.createAllocStack (uncondCheckedCast->getLoc (),
3517
- srcVal->getType ());
3518
- builder.createStore (uncondCheckedCast->getLoc (), srcVal, srcAddr,
3519
- srcVal->getType ().isTrivial (*srcVal->getFunction ())
3520
- ? StoreOwnershipQualifier::Trivial
3521
- : StoreOwnershipQualifier::Init);
3522
- // Use the storage address as destination
3523
- SILValue destAddr = addrMat.materializeAddress (uncondCheckedCast);
3524
- builder.createUnconditionalCheckedCastAddr (
3525
- uncondCheckedCast->getLoc (), srcAddr, srcAddr->getType ().getASTType (),
3526
- destAddr, destAddr->getType ().getASTType ());
3527
-
3528
- pass.getBuilder (uncondCheckedCast->getNextInstruction ()->getIterator ())
3529
- .createDeallocStack (uncondCheckedCast->getLoc (), srcAddr);
3562
+ rewriteUnconditionalCheckedCastInst (uncondCheckedCast, pass, &addrMat);
3530
3563
}
3531
3564
};
3532
3565
} // end anonymous namespace
@@ -3574,34 +3607,11 @@ static void rewriteIndirectApply(FullApplySite apply,
3574
3607
static void rewriteNonopaqueUnconditionalCheckedCast (
3575
3608
UnconditionalCheckedCastInst *uncondCheckedCast,
3576
3609
AddressLoweringState &pass) {
3577
- auto loc = uncondCheckedCast->getLoc ();
3578
- SILValue srcVal = uncondCheckedCast->getOperand ();
3579
- auto srcType = srcVal->getType ();
3580
- auto destType = uncondCheckedCast->getType ();
3581
- assert (srcType.isLoadable (*pass.function ));
3582
- assert (!destType.isAddressOnly (*pass.function ));
3583
-
3584
- // Create a stack temporary to store the source
3585
- auto builder = pass.getBuilder (uncondCheckedCast->getIterator ());
3586
- SILValue srcAddr = builder.createAllocStack (loc, srcType);
3587
- builder.createStore (loc, srcVal, srcAddr,
3588
- srcType.isTrivial (*pass.function )
3589
- ? StoreOwnershipQualifier::Trivial
3590
- : StoreOwnershipQualifier::Init);
3591
- SILValue destAddr = builder.createAllocStack (loc, destType);
3592
- builder.createUnconditionalCheckedCastAddr (loc, srcAddr, srcType.getASTType (),
3593
- destAddr, destType.getASTType ());
3610
+ assert (uncondCheckedCast->getOperand ()->getType ().isLoadable (*pass.function ));
3611
+ assert (uncondCheckedCast->getType ().isLoadable (*pass.function ));
3594
3612
3595
- auto afterBuilder =
3596
- pass.getBuilder (uncondCheckedCast->getNextInstruction ()->getIterator ());
3597
- auto *load = afterBuilder.createLoad (loc, destAddr,
3598
- destType.isTrivial (*pass.function )
3599
- ? LoadOwnershipQualifier::Trivial
3600
- : LoadOwnershipQualifier::Take);
3601
- uncondCheckedCast->replaceAllUsesWith (load);
3602
- pass.deleter .forceDelete (uncondCheckedCast);
3603
- afterBuilder.createDeallocStack (loc, destAddr);
3604
- afterBuilder.createDeallocStack (loc, srcAddr);
3613
+ rewriteUnconditionalCheckedCastInst (uncondCheckedCast, pass,
3614
+ /* addrMat=*/ nullptr );
3605
3615
}
3606
3616
3607
3617
static void rewriteFunction (AddressLoweringState &pass) {
0 commit comments