Skip to content

Commit d1f964e

Browse files
committed
Don't use previously found owned concrete values in ossa
1 parent 8494f68 commit d1f964e

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

include/swift/SILOptimizer/Utils/Existential.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ struct ConcreteExistentialInfo {
7474
SILValue ConcreteValue;
7575
// True if the ConcreteValue is copied from another stack location
7676
bool isConcreteValueCopied = false;
77+
// True if the ConcreteValue should replace all uses of the opened
78+
// existential.
79+
bool ConcreteValueNeedsFixup = false;
7780
// When ConcreteType is itself an opened existential, record the type
7881
// definition. May be nullptr for a valid AppliedConcreteType.
7982
SingleValueInstruction *ConcreteTypeDef = nullptr;

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,10 @@ SILCombiner::buildConcreteOpenedExistentialInfoFromSoleConformingType(
801801
SILBuilderWithScope b(std::next(OER->getIterator()), Builder);
802802
auto loc = RegularLocation::getAutoGeneratedLocation();
803803
SoleCEI.ConcreteValue = b.createUncheckedRefCast(loc, OER, concreteSILType);
804+
if (F->hasOwnership() &&
805+
SoleCEI.ConcreteValue->getOwnershipKind() == OwnershipKind::Owned) {
806+
SoleCEI.ConcreteValueNeedsFixup = true;
807+
}
804808
return COAI;
805809
}
806810

@@ -831,8 +835,19 @@ SILCombiner::buildConcreteOpenedExistentialInfo(Operand &ArgOperand) {
831835
// Build a ConcreteOpenedExistentialInfo following the data flow chain of the
832836
// ArgOperand through the open_existential backward to an init_existential.
833837
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+
}
835849
return COEI;
850+
}
836851

837852
// Use SoleConformingType information.
838853
return buildConcreteOpenedExistentialInfoFromSoleConformingType(ArgOperand);
@@ -1126,6 +1141,7 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
11261141

11271142
// Transform the parameter arguments.
11281143
SmallVector<ConcreteArgumentCopy, 4> concreteArgCopies;
1144+
llvm::DenseMap<SILValue, SILValue> valuesToReplace;
11291145
for (unsigned EndIdx = Apply.getNumArguments(); ArgIdx < EndIdx; ++ArgIdx) {
11301146
auto ArgIt = COAIs.find(ArgIdx);
11311147
if (ArgIt == COAIs.end()) {
@@ -1178,6 +1194,9 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
11781194
concreteArgCopies.push_back(*argSub);
11791195
NewArgs.push_back(argSub->tempArg);
11801196
} else {
1197+
if (CEI.ConcreteValueNeedsFixup) {
1198+
valuesToReplace[OAI.OpenedArchetypeValue] = CEI.ConcreteValue;
1199+
}
11811200
NewArgs.push_back(CEI.ConcreteValue);
11821201
}
11831202

@@ -1239,9 +1258,8 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
12391258
// SILCombine Worklist.
12401259
InstructionDeleter deleter;
12411260
for (SILInstruction *inst : *Builder.getTrackingList()) {
1242-
deleter.trackIfDead(inst);
1261+
deleter.deleteIfDead(inst, false);
12431262
}
1244-
deleter.cleanupDeadInstructions();
12451263
Builder.getTrackingList()->clear();
12461264
return nullptr;
12471265
}
@@ -1283,6 +1301,19 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
12831301
cleanupBuilder.createDeallocStack(cleanupLoc, argCopy.tempArg);
12841302
}
12851303
}
1304+
// Replace all uses of the opened existential with the unconditional cast to concrete type.
1305+
for (auto &valuePair : valuesToReplace) {
1306+
auto openedExistential = valuePair.first;
1307+
auto uncheckedCast = valuePair.second;
1308+
SmallVector<Operand *> uses(openedExistential->getNonTypeDependentUses());
1309+
for (auto use : uses) {
1310+
auto *user = use->getUser();
1311+
if (user == cast<SingleValueInstruction>(uncheckedCast)) {
1312+
continue;
1313+
}
1314+
use->set(uncheckedCast);
1315+
}
1316+
}
12861317
return NewApply.getInstruction();
12871318
}
12881319

test/SILOptimizer/sil_combine_ossa.sil

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2855,7 +2855,21 @@ bb0(%0 : @owned $Klass):
28552855
%2 = open_existential_ref %1 : $AnyObject to $@opened("7CAE06CE-5F10-11E4-AF13-C82A1428F987", AnyObject) Self
28562856
%f = function_ref @use_generic_obj_guaranteed : $@convention(thin) <τ_0_0> (@guaranteed τ_0_0) -> ()
28572857
apply %f<@opened("7CAE06CE-5F10-11E4-AF13-C82A1428F987", AnyObject) Self>(%2) : $@convention(thin) <τ_0_0> (@guaranteed τ_0_0) -> ()
2858+
%3 = unchecked_ref_cast %2 : $@opened("7CAE06CE-5F10-11E4-AF13-C82A1428F987", AnyObject) Self to $Builtin.NativeObject
2859+
return %3 : $Builtin.NativeObject
2860+
}
28582861

2862+
// CHECK-LABEL: sil [ossa] @collapse_existential_pack_unpack_unchecked_ref_cast_owned4 :
2863+
// CHECK: apply {{.*}}<Klass>
2864+
// CHECK: } // end sil function 'collapse_existential_pack_unpack_unchecked_ref_cast_owned4'
2865+
sil [ossa] @collapse_existential_pack_unpack_unchecked_ref_cast_owned4 : $@convention(thin) (@owned Klass) -> @owned Builtin.NativeObject {
2866+
bb0(%0 : @owned $Klass):
2867+
%1 = init_existential_ref %0 : $Klass : $Klass, $AnyObject
2868+
%f1 = function_ref @use_anyobject_guaranteed : $@convention(thin) (@guaranteed AnyObject) -> ()
2869+
apply %f1(%1) : $@convention(thin) (@guaranteed AnyObject) -> ()
2870+
%2 = open_existential_ref %1 : $AnyObject to $@opened("7CAE06CE-5F10-11E4-AF13-C82A1428F987", AnyObject) Self
2871+
%f2 = function_ref @use_generic_obj_guaranteed : $@convention(thin) <τ_0_0> (@guaranteed τ_0_0) -> ()
2872+
apply %f2<@opened("7CAE06CE-5F10-11E4-AF13-C82A1428F987", AnyObject) Self>(%2) : $@convention(thin) <τ_0_0> (@guaranteed τ_0_0) -> ()
28592873
%3 = unchecked_ref_cast %2 : $@opened("7CAE06CE-5F10-11E4-AF13-C82A1428F987", AnyObject) Self to $Builtin.NativeObject
28602874
return %3 : $Builtin.NativeObject
28612875
}

0 commit comments

Comments
 (0)