@@ -798,30 +798,13 @@ SILCombiner::buildConcreteOpenedExistentialInfoFromSoleConformingType(
798
798
// Prepare the code by adding UncheckedCast instructions that cast opened
799
799
// existentials to concrete types. Set the ConcreteValue of CEI.
800
800
if (auto *OER = dyn_cast<OpenExistentialRefInst>(OAI.OpenedArchetypeValue )) {
801
- // If we have an owned open_existential_ref, we only optimize for now if our
802
- // open_existential_ref has a single non-debug consuming use that is a
803
- // destroy_value.
804
- if (OER->getForwardingOwnershipKind () != OwnershipKind::Owned) {
805
- // We use OER as the insertion point so that
806
- SILBuilderWithScope b (std::next (OER->getIterator ()), Builder);
807
- auto loc = RegularLocation::getAutoGeneratedLocation ();
808
- SoleCEI.ConcreteValue =
809
- b.createUncheckedRefCast (loc, OER, concreteSILType);
810
- return COAI;
811
- }
812
-
813
- auto *consumingUse = OER->getSingleConsumingUse ();
814
- if (!consumingUse || !isa<DestroyValueInst>(consumingUse->getUser ())) {
815
- return std::nullopt;
816
- }
817
-
818
- // We use std::next(OER) as the insertion point so that we can reuse the
819
- // destroy_value of consumingUse.
820
801
SILBuilderWithScope b (std::next (OER->getIterator ()), Builder);
821
802
auto loc = RegularLocation::getAutoGeneratedLocation ();
822
- auto *uri = b.createUncheckedRefCast (loc, OER, concreteSILType);
823
- SoleCEI.ConcreteValue = uri;
824
- replaceInstUsesWith (*OER, uri);
803
+ SoleCEI.ConcreteValue = b.createUncheckedRefCast (loc, OER, concreteSILType);
804
+ if (F->hasOwnership () &&
805
+ SoleCEI.ConcreteValue ->getOwnershipKind () == OwnershipKind::Owned) {
806
+ SoleCEI.ConcreteValueNeedsFixup = true ;
807
+ }
825
808
return COAI;
826
809
}
827
810
@@ -852,8 +835,19 @@ SILCombiner::buildConcreteOpenedExistentialInfo(Operand &ArgOperand) {
852
835
// Build a ConcreteOpenedExistentialInfo following the data flow chain of the
853
836
// ArgOperand through the open_existential backward to an init_existential.
854
837
ConcreteOpenedExistentialInfo COEI (ArgOperand);
855
- if (COEI.CEI )
838
+ if (COEI.CEI ) {
839
+ auto ConcreteValue = COEI.CEI ->ConcreteValue ;
840
+ if (ConcreteValue->getFunction ()->hasOwnership () &&
841
+ ConcreteValue->getOwnershipKind () == OwnershipKind::Owned) {
842
+ SILBuilderWithScope b (COEI.OAI .OpenedArchetypeValue ->getNextInstruction (),
843
+ Builder);
844
+ auto loc = RegularLocation::getAutoGeneratedLocation ();
845
+ COEI.CEI ->ConcreteValue = b.createUncheckedRefCast (
846
+ loc, COEI.OAI .OpenedArchetypeValue , ConcreteValue->getType ());
847
+ COEI.CEI ->ConcreteValueNeedsFixup = true ;
848
+ }
856
849
return COEI;
850
+ }
857
851
858
852
// Use SoleConformingType information.
859
853
return buildConcreteOpenedExistentialInfoFromSoleConformingType (ArgOperand);
@@ -1147,6 +1141,7 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
1147
1141
1148
1142
// Transform the parameter arguments.
1149
1143
SmallVector<ConcreteArgumentCopy, 4 > concreteArgCopies;
1144
+ llvm::SmallMapVector<SILValue, SILValue, 4 > valuesToReplace;
1150
1145
for (unsigned EndIdx = Apply.getNumArguments (); ArgIdx < EndIdx; ++ArgIdx) {
1151
1146
auto ArgIt = COAIs.find (ArgIdx);
1152
1147
if (ArgIt == COAIs.end ()) {
@@ -1199,6 +1194,9 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
1199
1194
concreteArgCopies.push_back (*argSub);
1200
1195
NewArgs.push_back (argSub->tempArg );
1201
1196
} else {
1197
+ if (CEI.ConcreteValueNeedsFixup ) {
1198
+ valuesToReplace[OAI.OpenedArchetypeValue ] = CEI.ConcreteValue ;
1199
+ }
1202
1200
NewArgs.push_back (CEI.ConcreteValue );
1203
1201
}
1204
1202
@@ -1260,9 +1258,8 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
1260
1258
// SILCombine Worklist.
1261
1259
InstructionDeleter deleter;
1262
1260
for (SILInstruction *inst : *Builder.getTrackingList ()) {
1263
- deleter.trackIfDead (inst);
1261
+ deleter.deleteIfDead (inst, false );
1264
1262
}
1265
- deleter.cleanupDeadInstructions ();
1266
1263
Builder.getTrackingList ()->clear ();
1267
1264
return nullptr ;
1268
1265
}
@@ -1304,6 +1301,20 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
1304
1301
cleanupBuilder.createDeallocStack (cleanupLoc, argCopy.tempArg );
1305
1302
}
1306
1303
}
1304
+ // Replace all uses of the opened existential with the unconditional cast to
1305
+ // concrete type.
1306
+ for (auto &valuePair : valuesToReplace) {
1307
+ auto openedExistential = valuePair.first ;
1308
+ auto uncheckedCast = valuePair.second ;
1309
+ SmallVector<Operand *> uses (openedExistential->getNonTypeDependentUses ());
1310
+ for (auto use : uses) {
1311
+ auto *user = use->getUser ();
1312
+ if (user == cast<SingleValueInstruction>(uncheckedCast)) {
1313
+ continue ;
1314
+ }
1315
+ use->set (uncheckedCast);
1316
+ }
1317
+ }
1307
1318
return NewApply.getInstruction ();
1308
1319
}
1309
1320
0 commit comments