@@ -801,6 +801,10 @@ SILCombiner::buildConcreteOpenedExistentialInfoFromSoleConformingType(
801
801
SILBuilderWithScope b (std::next (OER->getIterator ()), Builder);
802
802
auto loc = RegularLocation::getAutoGeneratedLocation ();
803
803
SoleCEI.ConcreteValue = b.createUncheckedRefCast (loc, OER, concreteSILType);
804
+ if (F->hasOwnership () &&
805
+ SoleCEI.ConcreteValue ->getOwnershipKind () == OwnershipKind::Owned) {
806
+ SoleCEI.ConcreteValueNeedsFixup = true ;
807
+ }
804
808
return COAI;
805
809
}
806
810
@@ -831,8 +835,19 @@ SILCombiner::buildConcreteOpenedExistentialInfo(Operand &ArgOperand) {
831
835
// Build a ConcreteOpenedExistentialInfo following the data flow chain of the
832
836
// ArgOperand through the open_existential backward to an init_existential.
833
837
ConcreteOpenedExistentialInfo COEI (ArgOperand);
834
- 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
+ }
835
849
return COEI;
850
+ }
836
851
837
852
// Use SoleConformingType information.
838
853
return buildConcreteOpenedExistentialInfoFromSoleConformingType (ArgOperand);
@@ -1126,6 +1141,7 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
1126
1141
1127
1142
// Transform the parameter arguments.
1128
1143
SmallVector<ConcreteArgumentCopy, 4 > concreteArgCopies;
1144
+ llvm::DenseMap<SILValue, SILValue> valuesToReplace;
1129
1145
for (unsigned EndIdx = Apply.getNumArguments (); ArgIdx < EndIdx; ++ArgIdx) {
1130
1146
auto ArgIt = COAIs.find (ArgIdx);
1131
1147
if (ArgIt == COAIs.end ()) {
@@ -1178,6 +1194,9 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
1178
1194
concreteArgCopies.push_back (*argSub);
1179
1195
NewArgs.push_back (argSub->tempArg );
1180
1196
} else {
1197
+ if (CEI.ConcreteValueNeedsFixup ) {
1198
+ valuesToReplace[OAI.OpenedArchetypeValue ] = CEI.ConcreteValue ;
1199
+ }
1181
1200
NewArgs.push_back (CEI.ConcreteValue );
1182
1201
}
1183
1202
@@ -1239,9 +1258,8 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
1239
1258
// SILCombine Worklist.
1240
1259
InstructionDeleter deleter;
1241
1260
for (SILInstruction *inst : *Builder.getTrackingList ()) {
1242
- deleter.trackIfDead (inst);
1261
+ deleter.deleteIfDead (inst, false );
1243
1262
}
1244
- deleter.cleanupDeadInstructions ();
1245
1263
Builder.getTrackingList ()->clear ();
1246
1264
return nullptr ;
1247
1265
}
@@ -1283,6 +1301,20 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
1283
1301
cleanupBuilder.createDeallocStack (cleanupLoc, argCopy.tempArg );
1284
1302
}
1285
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
+ }
1286
1318
return NewApply.getInstruction ();
1287
1319
}
1288
1320
0 commit comments