@@ -2560,6 +2560,37 @@ class UseRewriter : SILInstructionVisitor<UseRewriter> {
2560
2560
markRewritten (uncheckedCastInst, destAddr);
2561
2561
}
2562
2562
2563
+ void visitUnconditionalCheckedCastInst (
2564
+ UnconditionalCheckedCastInst *uncondCheckedCast) {
2565
+ SILValue srcVal = uncondCheckedCast->getOperand ();
2566
+ assert (srcVal->getType ().isAddressOnly (*pass.function ));
2567
+ SILValue srcAddr = pass.valueStorageMap .getStorage (srcVal).storageAddress ;
2568
+
2569
+ if (uncondCheckedCast->getType ().isAddressOnly (*pass.function )) {
2570
+ // When cast destination has address only type, use the storage address
2571
+ SILValue destAddr = addrMat.materializeAddress (uncondCheckedCast);
2572
+ markRewritten (uncondCheckedCast, destAddr);
2573
+ builder.createUnconditionalCheckedCastAddr (
2574
+ uncondCheckedCast->getLoc (), srcAddr, srcAddr->getType ().getASTType (),
2575
+ destAddr, destAddr->getType ().getASTType ());
2576
+ return ;
2577
+ }
2578
+ // For loadable cast destination type, create a stack temporary
2579
+ SILValue destAddr = builder.createAllocStack (uncondCheckedCast->getLoc (),
2580
+ uncondCheckedCast->getType ());
2581
+ builder.createUnconditionalCheckedCastAddr (
2582
+ uncondCheckedCast->getLoc (), srcAddr, srcAddr->getType ().getASTType (),
2583
+ destAddr, destAddr->getType ().getASTType ());
2584
+ auto nextBuilder =
2585
+ pass.getBuilder (uncondCheckedCast->getNextInstruction ()->getIterator ());
2586
+ auto dest = nextBuilder.createLoad (
2587
+ uncondCheckedCast->getLoc (), destAddr,
2588
+ destAddr->getType ().isTrivial (*uncondCheckedCast->getFunction ())
2589
+ ? LoadOwnershipQualifier::Trivial
2590
+ : LoadOwnershipQualifier::Copy);
2591
+ nextBuilder.createDeallocStack (uncondCheckedCast->getLoc (), destAddr);
2592
+ uncondCheckedCast->replaceAllUsesWith (dest);
2593
+ }
2563
2594
void visitUncheckedEnumDataInst (UncheckedEnumDataInst *enumDataInst);
2564
2595
};
2565
2596
} // end anonymous namespace
@@ -2869,6 +2900,14 @@ class DefRewriter : SILInstructionVisitor<DefRewriter> {
2869
2900
storage.storageAddress = addrMat.materializeAddress (arg);
2870
2901
}
2871
2902
2903
+ void setStorageAddress (SILValue oldValue, SILValue addr) {
2904
+ auto &storage = pass.valueStorageMap .getStorage (oldValue);
2905
+ // getReusedStorageOperand() ensures that oldValue does not already have
2906
+ // separate storage. So there's no need to delete its alloc_stack.
2907
+ assert (!storage.storageAddress || storage.storageAddress == addr);
2908
+ storage.storageAddress = addr;
2909
+ }
2910
+
2872
2911
void beforeVisit (SILInstruction *inst) {
2873
2912
LLVM_DEBUG (llvm::dbgs () << " REWRITE DEF " ; inst->dump ());
2874
2913
if (storage.storageAddress )
@@ -2972,12 +3011,27 @@ class DefRewriter : SILInstructionVisitor<DefRewriter> {
2972
3011
addrMat.initializeComposingUse (&operand);
2973
3012
}
2974
3013
2975
- void setStorageAddress (SILValue oldValue, SILValue addr) {
2976
- auto &storage = pass.valueStorageMap .getStorage (oldValue);
2977
- // getReusedStorageOperand() ensures that oldValue does not already have
2978
- // separate storage. So there's no need to delete its alloc_stack.
2979
- assert (!storage.storageAddress || storage.storageAddress == addr);
2980
- storage.storageAddress = addr;
3014
+ void visitUnconditionalCheckedCastInst (
3015
+ UnconditionalCheckedCastInst *uncondCheckedCast) {
3016
+ SILValue srcVal = uncondCheckedCast->getOperand ();
3017
+ assert (srcVal->getType ().isLoadable (*pass.function ));
3018
+ assert (uncondCheckedCast->getType ().isAddressOnly (*pass.function ));
3019
+
3020
+ // Create a stack temporary to store the srcVal
3021
+ SILValue srcAddr = builder.createAllocStack (uncondCheckedCast->getLoc (),
3022
+ srcVal->getType ());
3023
+ builder.createStore (uncondCheckedCast->getLoc (), srcVal, srcAddr,
3024
+ srcVal->getType ().isTrivial (*srcVal->getFunction ())
3025
+ ? StoreOwnershipQualifier::Trivial
3026
+ : StoreOwnershipQualifier::Init);
3027
+ // Use the storage address as destination
3028
+ SILValue destAddr = addrMat.materializeAddress (uncondCheckedCast);
3029
+ builder.createUnconditionalCheckedCastAddr (
3030
+ uncondCheckedCast->getLoc (), srcAddr, srcAddr->getType ().getASTType (),
3031
+ destAddr, destAddr->getType ().getASTType ());
3032
+
3033
+ pass.getBuilder (uncondCheckedCast->getNextInstruction ()->getIterator ())
3034
+ .createDeallocStack (uncondCheckedCast->getLoc (), srcAddr);
2981
3035
}
2982
3036
};
2983
3037
} // end anonymous namespace
0 commit comments