@@ -2560,6 +2560,37 @@ class UseRewriter : SILInstructionVisitor<UseRewriter> {
25602560 markRewritten (uncheckedCastInst, destAddr);
25612561 }
25622562
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+ }
25632594 void visitUncheckedEnumDataInst (UncheckedEnumDataInst *enumDataInst);
25642595};
25652596} // end anonymous namespace
@@ -2869,6 +2900,14 @@ class DefRewriter : SILInstructionVisitor<DefRewriter> {
28692900 storage.storageAddress = addrMat.materializeAddress (arg);
28702901 }
28712902
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+
28722911 void beforeVisit (SILInstruction *inst) {
28732912 LLVM_DEBUG (llvm::dbgs () << " REWRITE DEF " ; inst->dump ());
28742913 if (storage.storageAddress )
@@ -2972,12 +3011,27 @@ class DefRewriter : SILInstructionVisitor<DefRewriter> {
29723011 addrMat.initializeComposingUse (&operand);
29733012 }
29743013
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);
29813035 }
29823036};
29833037} // end anonymous namespace
0 commit comments