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