Skip to content

Commit 431aabc

Browse files
Merge pull request #62192 from nate-chandler/opaque-values/2/20221118
[AddressLowering] Factored out unconditional_checked_cast rewriting.
2 parents e1102cc + 221ffbc commit 431aabc

File tree

1 file changed

+87
-77
lines changed

1 file changed

+87
-77
lines changed

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 87 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,6 +2485,74 @@ class CheckedCastBrRewriter {
24852485
}
24862486
};
24872487

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+
24882556
//===----------------------------------------------------------------------===//
24892557
// ReturnRewriter
24902558
//
@@ -2724,13 +2792,16 @@ void YieldRewriter::rewriteOperand(YieldInst *yieldInst, unsigned index) {
27242792
}
27252793
}
27262794

2795+
//
2796+
27272797
//===----------------------------------------------------------------------===//
27282798
// UseRewriter
27292799
//
27302800
// Rewrite opaque value uses in forward order--uses are rewritten before defs.
27312801
//===----------------------------------------------------------------------===//
27322802

27332803
namespace {
2804+
27342805
class UseRewriter : SILInstructionVisitor<UseRewriter> {
27352806
friend SILVisitorBase<UseRewriter>;
27362807
friend SILInstructionVisitor<UseRewriter>;
@@ -2999,7 +3070,15 @@ class UseRewriter : SILInstructionVisitor<UseRewriter> {
29993070
}
30003071

30013072
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+
}
30033082

30043083
void visitCheckedCastBranchInst(CheckedCastBranchInst *checkedCastBranch);
30053084

@@ -3293,38 +3372,6 @@ void UseRewriter::visitUncheckedEnumDataInst(
32933372
markRewritten(enumDataInst, enumAddrInst);
32943373
}
32953374

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-
33283375
//===----------------------------------------------------------------------===//
33293376
// DefRewriter
33303377
//
@@ -3511,25 +3558,11 @@ class DefRewriter : SILInstructionVisitor<DefRewriter> {
35113558

35123559
void visitUnconditionalCheckedCastInst(
35133560
UnconditionalCheckedCastInst *uncondCheckedCast) {
3514-
SILValue srcVal = uncondCheckedCast->getOperand();
3515-
assert(srcVal->getType().isLoadable(*pass.function));
3561+
assert(!uncondCheckedCast->getOperand()->getType().isAddressOnly(
3562+
*pass.function));
35163563
assert(uncondCheckedCast->getType().isAddressOnly(*pass.function));
35173564

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);
35333566
}
35343567
};
35353568
} // end anonymous namespace
@@ -3577,34 +3610,11 @@ static void rewriteIndirectApply(FullApplySite apply,
35773610
static void rewriteNonopaqueUnconditionalCheckedCast(
35783611
UnconditionalCheckedCastInst *uncondCheckedCast,
35793612
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));
35973615

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);
36083618
}
36093619

36103620
static void rewriteFunction(AddressLoweringState &pass) {

0 commit comments

Comments
 (0)