Skip to content

Commit 01465d9

Browse files
committed
SILCombine: Remove a cast if it's only used by an end_cow_mutation.
(end_cow_mutation (upcast X)) -> (end_cow_mutation X) (end_cow_mutation (unchecked_ref_cast X)) -> (end_cow_mutation X)
1 parent 4ca6b31 commit 01465d9

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

lib/SILOptimizer/SILCombiner/SILCombiner.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ class SILCombiner :
183183
SILInstruction *visitPointerToAddressInst(PointerToAddressInst *PTAI);
184184
SILInstruction *visitUncheckedAddrCastInst(UncheckedAddrCastInst *UADCI);
185185
SILInstruction *visitUncheckedRefCastInst(UncheckedRefCastInst *URCI);
186+
SILInstruction *visitEndCOWMutationInst(EndCOWMutationInst *URCI);
186187
SILInstruction *visitUncheckedRefCastAddrInst(UncheckedRefCastAddrInst *URCI);
187188
SILInstruction *visitBridgeObjectToRefInst(BridgeObjectToRefInst *BORI);
188189
SILInstruction *visitUnconditionalCheckedCastInst(

lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,26 @@ SILCombiner::visitUncheckedRefCastInst(UncheckedRefCastInst *URCI) {
264264
return nullptr;
265265
}
266266

267+
SILInstruction *SILCombiner::visitEndCOWMutationInst(EndCOWMutationInst *ECM) {
268+
269+
// Remove a cast if it's only used by an end_cow_mutation.
270+
//
271+
// (end_cow_mutation (upcast X)) -> (end_cow_mutation X)
272+
// (end_cow_mutation (unchecked_ref_cast X)) -> (end_cow_mutation X)
273+
SILValue op = ECM->getOperand();
274+
if (!isa<UncheckedRefCastInst>(op) && !isa<UpcastInst>(op))
275+
return nullptr;
276+
if (!op->hasOneUse())
277+
return nullptr;
278+
279+
SingleValueInstruction *refCast = cast<SingleValueInstruction>(op);
280+
auto *newECM = Builder.createEndCOWMutation(ECM->getLoc(),
281+
refCast->getOperand(0));
282+
ECM->replaceAllUsesWith(refCast);
283+
refCast->setOperand(0, newECM);
284+
refCast->moveAfter(newECM);
285+
return eraseInstFromFunction(*ECM);
286+
}
267287

268288
SILInstruction *
269289
SILCombiner::visitBridgeObjectToRefInst(BridgeObjectToRefInst *BORI) {

0 commit comments

Comments
 (0)