Skip to content

Commit 0c7f5b3

Browse files
committed
[cast-opt] Change optimizeMetatypeConversion to return a value and use the new
replace value uses action to make sure that we properly notify passes that we made the change. This fixes a latent bug where we were not notifying SILCombine about this replacement. Specifically: - auto replaceCast = [&](SingleValueInstruction *NewCast) { - assert(Ty.getAs<AnyMetatypeType>()->getRepresentation() - == NewCast->getType().getAs<AnyMetatypeType>()->getRepresentation()); - MCI->replaceAllUsesWith(NewCast); - EraseInstAction(MCI); - return NewCast; + auto replaceCast = [&](SILValue newValue) -> SILValue { + assert(ty.getAs<AnyMetatypeType>()->getRepresentation() == + newValue->getType().getAs<AnyMetatypeType>()->getRepresentation()); + ReplaceValueUsesAction(mci, newValue); + EraseInstAction(mci); + return newValue; }; Notice how we use MCI->replaceAllUsesWith instead of one of our replace call backs. SILCombine hooks these to know if it should re-run users.
1 parent 4dabf9f commit 0c7f5b3

File tree

2 files changed

+32
-28
lines changed

2 files changed

+32
-28
lines changed

include/swift/SILOptimizer/Utils/CastOptimizer.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,8 @@ class CastOptimizer {
152152
CanType Target, SILBasicBlock *SuccessBB,
153153
SILBasicBlock *FailureBB);
154154

155-
SILInstruction *
156-
optimizeMetatypeConversion(ConversionInst *MCI,
157-
MetatypeRepresentation Representation);
155+
SILValue optimizeMetatypeConversion(ConversionInst *mci,
156+
MetatypeRepresentation representation);
158157
};
159158

160159
} // namespace swift

lib/SILOptimizer/Utils/CastOptimizer.cpp

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,40 +1577,45 @@ SILInstruction *CastOptimizer::optimizeUnconditionalCheckedCastAddrInst(
15771577
}
15781578

15791579
/// Simplify conversions between thick and objc metatypes.
1580-
SILInstruction *CastOptimizer::optimizeMetatypeConversion(
1581-
ConversionInst *MCI, MetatypeRepresentation Representation) {
1582-
SILValue Op = MCI->getOperand(0);
1580+
SILValue CastOptimizer::optimizeMetatypeConversion(
1581+
ConversionInst *mci, MetatypeRepresentation representation) {
1582+
SILValue op = mci->getOperand(0);
15831583
// Instruction has a proper target type already.
1584-
SILType Ty = MCI->getType();
1585-
auto MetatypeTy = Op->getType().getAs<AnyMetatypeType>();
1584+
SILType ty = mci->getType();
1585+
auto metatypeTy = op->getType().getAs<AnyMetatypeType>();
15861586

1587-
if (MetatypeTy->getRepresentation() != Representation)
1588-
return nullptr;
1587+
if (metatypeTy->getRepresentation() != representation)
1588+
return SILValue();
1589+
1590+
auto loc = mci->getLoc();
15891591

15901592
// Rematerialize the incoming metatype instruction with the outgoing type.
1591-
auto replaceCast = [&](SingleValueInstruction *NewCast) {
1592-
assert(Ty.getAs<AnyMetatypeType>()->getRepresentation()
1593-
== NewCast->getType().getAs<AnyMetatypeType>()->getRepresentation());
1594-
MCI->replaceAllUsesWith(NewCast);
1595-
EraseInstAction(MCI);
1596-
return NewCast;
1593+
auto replaceCast = [&](SILValue newValue) -> SILValue {
1594+
assert(ty.getAs<AnyMetatypeType>()->getRepresentation() ==
1595+
newValue->getType().getAs<AnyMetatypeType>()->getRepresentation());
1596+
ReplaceValueUsesAction(mci, newValue);
1597+
EraseInstAction(mci);
1598+
return newValue;
15971599
};
1598-
if (auto *MI = dyn_cast<MetatypeInst>(Op)) {
1599-
return replaceCast(SILBuilderWithScope(MCI, BuilderContext)
1600-
.createMetatype(MCI->getLoc(), Ty));
1600+
1601+
if (auto *mi = dyn_cast<MetatypeInst>(op)) {
1602+
return replaceCast(
1603+
SILBuilderWithScope(mci, BuilderContext).createMetatype(loc, ty));
16011604
}
1605+
16021606
// For metatype instructions that require an operand, generate the new
16031607
// metatype at the same position as the original to avoid extending the
1604-
// lifetime of `Op` past its destroy.
1605-
if (auto *VMI = dyn_cast<ValueMetatypeInst>(Op)) {
1606-
return replaceCast(
1607-
SILBuilderWithScope(VMI, BuilderContext)
1608-
.createValueMetatype(MCI->getLoc(), Ty, VMI->getOperand()));
1608+
// lifetime of `op` past its destroy.
1609+
if (auto *vmi = dyn_cast<ValueMetatypeInst>(op)) {
1610+
return replaceCast(SILBuilderWithScope(vmi, BuilderContext)
1611+
.createValueMetatype(loc, ty, vmi->getOperand()));
16091612
}
1610-
if (auto *EMI = dyn_cast<ExistentialMetatypeInst>(Op)) {
1613+
1614+
if (auto *emi = dyn_cast<ExistentialMetatypeInst>(op)) {
16111615
return replaceCast(
1612-
SILBuilderWithScope(EMI, BuilderContext)
1613-
.createExistentialMetatype(MCI->getLoc(), Ty, EMI->getOperand()));
1616+
SILBuilderWithScope(emi, BuilderContext)
1617+
.createExistentialMetatype(loc, ty, emi->getOperand()));
16141618
}
1615-
return nullptr;
1619+
1620+
return SILValue();
16161621
}

0 commit comments

Comments
 (0)