Skip to content

Commit 221ffbc

Browse files
committed
[AddressLowering] Factored out UCCI rewriting.
Previously, there were three places where unconditional_checked_cast instructions were rewritten as unconditional_checked_cast_addr instructions: - from address-only - to address-only - neither Here, all three are made to factor through the new rewriteUnconditionalCheckedCast function.
1 parent c40a98a commit 221ffbc

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
@@ -2482,6 +2482,74 @@ class CheckedCastBrRewriter {
24822482
}
24832483
};
24842484

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+
24852553
//===----------------------------------------------------------------------===//
24862554
// ReturnRewriter
24872555
//
@@ -2721,13 +2789,16 @@ void YieldRewriter::rewriteOperand(YieldInst *yieldInst, unsigned index) {
27212789
}
27222790
}
27232791

2792+
//
2793+
27242794
//===----------------------------------------------------------------------===//
27252795
// UseRewriter
27262796
//
27272797
// Rewrite opaque value uses in forward order--uses are rewritten before defs.
27282798
//===----------------------------------------------------------------------===//
27292799

27302800
namespace {
2801+
27312802
class UseRewriter : SILInstructionVisitor<UseRewriter> {
27322803
friend SILVisitorBase<UseRewriter>;
27332804
friend SILInstructionVisitor<UseRewriter>;
@@ -2996,7 +3067,15 @@ class UseRewriter : SILInstructionVisitor<UseRewriter> {
29963067
}
29973068

29983069
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+
}
30003079

30013080
void visitCheckedCastBranchInst(CheckedCastBranchInst *checkedCastBranch);
30023081

@@ -3290,38 +3369,6 @@ void UseRewriter::visitUncheckedEnumDataInst(
32903369
markRewritten(enumDataInst, enumAddrInst);
32913370
}
32923371

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-
33253372
//===----------------------------------------------------------------------===//
33263373
// DefRewriter
33273374
//
@@ -3508,25 +3555,11 @@ class DefRewriter : SILInstructionVisitor<DefRewriter> {
35083555

35093556
void visitUnconditionalCheckedCastInst(
35103557
UnconditionalCheckedCastInst *uncondCheckedCast) {
3511-
SILValue srcVal = uncondCheckedCast->getOperand();
3512-
assert(srcVal->getType().isLoadable(*pass.function));
3558+
assert(!uncondCheckedCast->getOperand()->getType().isAddressOnly(
3559+
*pass.function));
35133560
assert(uncondCheckedCast->getType().isAddressOnly(*pass.function));
35143561

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);
35303563
}
35313564
};
35323565
} // end anonymous namespace
@@ -3574,34 +3607,11 @@ static void rewriteIndirectApply(FullApplySite apply,
35743607
static void rewriteNonopaqueUnconditionalCheckedCast(
35753608
UnconditionalCheckedCastInst *uncondCheckedCast,
35763609
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));
35943612

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);
36053615
}
36063616

36073617
static void rewriteFunction(AddressLoweringState &pass) {

0 commit comments

Comments
 (0)