Skip to content

Commit d402077

Browse files
authored
Merge pull request #25038 from atrick/fix-specializer-leak
Fix ExistentialSpecializer to correctly cleanup storage.
2 parents 651045f + d9d0fae commit d402077

14 files changed

+617
-308
lines changed

include/swift/AST/SILOptions.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ class SILOptions {
5050
/// Remove all runtime assertions during optimizations.
5151
bool RemoveRuntimeAsserts = false;
5252

53-
/// Enable existential specializer optimization.
54-
bool ExistentialSpecializer = false;
55-
5653
/// Controls whether the SIL ARC optimizations are run.
5754
bool EnableARCOptimizations = true;
5855

include/swift/Option/FrontendOptions.td

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -472,9 +472,6 @@ def sil_unroll_threshold : Separate<["-"], "sil-unroll-threshold">,
472472
MetaVarName<"<250>">,
473473
HelpText<"Controls the aggressiveness of loop unrolling">;
474474

475-
def sil_existential_specializer : Flag<["-"], "sil-existential-specializer">,
476-
HelpText<"Enable SIL existential specializer optimization">;
477-
478475
def sil_merge_partial_modules : Flag<["-"], "sil-merge-partial-modules">,
479476
HelpText<"Merge SIL from all partial swiftmodules into the final module">;
480477

lib/Frontend/CompilerInvocation.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -702,9 +702,6 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
702702
return true;
703703
}
704704
}
705-
if (Args.hasArg(OPT_sil_existential_specializer)) {
706-
Opts.ExistentialSpecializer = true;
707-
}
708705
if (const Arg *A = Args.getLastArg(OPT_num_threads)) {
709706
if (StringRef(A->getValue()).getAsInteger(10, Opts.NumThreads)) {
710707
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,

lib/SILOptimizer/FunctionSignatureTransforms/ExistentialSpecializer.cpp

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828

2929
using namespace swift;
3030

31+
static llvm::cl::opt<bool>
32+
EnableExistentialSpecializer("enable-existential-specializer",
33+
llvm::cl::Hidden,
34+
llvm::cl::init(true));
35+
3136
STATISTIC(NumFunctionsWithExistentialArgsSpecialized,
3237
"Number of functions with existential args specialized");
3338

@@ -66,7 +71,7 @@ class ExistentialSpecializer : public SILFunctionTransform {
6671
auto *F = getFunction();
6772

6873
/// Don't optimize functions that should not be optimized.
69-
if (!F->shouldOptimize() || !F->getModule().getOptions().ExistentialSpecializer) {
74+
if (!F->shouldOptimize() || !EnableExistentialSpecializer) {
7075
return;
7176
}
7277

@@ -110,19 +115,6 @@ bool ExistentialSpecializer::findConcreteTypeFromSoleConformingType(
110115
return true;
111116
}
112117

113-
/// Check if the argument Arg is used in a destroy_use instruction.
114-
static void
115-
findIfCalleeUsesArgInDestroyUse(SILValue Arg,
116-
ExistentialTransformArgumentDescriptor &ETAD) {
117-
for (Operand *ArgUse : Arg->getUses()) {
118-
auto *ArgUser = ArgUse->getUser();
119-
if (isa<DestroyAddrInst>(ArgUser)) {
120-
ETAD.DestroyAddrUse = true;
121-
break;
122-
}
123-
}
124-
}
125-
126118
/// Helper function to ensure that the argument is not InOut or InOut_Aliasable
127119
static bool isNonInoutIndirectArgument(SILValue Arg,
128120
SILArgumentConvention ArgConvention) {
@@ -188,24 +180,27 @@ bool ExistentialSpecializer::canSpecializeExistentialArgsInFunction(
188180
continue;
189181
}
190182

191-
/// Determine attributes of the existential addr arguments such as
192-
/// destroy_use, immutable_access.
183+
/// Determine attributes of the existential addr argument.
193184
ExistentialTransformArgumentDescriptor ETAD;
194185
auto paramInfo = origCalleeConv.getParamInfoForSILArg(Idx);
195-
ETAD.AccessType = (paramInfo.isIndirectMutating() || paramInfo.isConsumed())
186+
// The ExistentialSpecializerCloner copies the incoming generic argument
187+
// into an existential. This won't work if the original argument is
188+
// mutated. Furthermore, SILCombine would not be able to replace a mutated
189+
// existential with a concrete value, so the specialization thunk could not
190+
// be optimized away.
191+
if (paramInfo.isIndirectMutating())
192+
continue;
193+
194+
ETAD.AccessType = paramInfo.isConsumed()
196195
? OpenedExistentialAccess::Mutable
197196
: OpenedExistentialAccess::Immutable;
198-
ETAD.DestroyAddrUse = false;
199-
if ((CalleeArgs[Idx]->getType().getPreferredExistentialRepresentation(
200-
F->getModule()))
201-
!= ExistentialRepresentation::Class)
202-
findIfCalleeUsesArgInDestroyUse(CalleeArg, ETAD);
197+
ETAD.isConsumed = paramInfo.isConsumed();
203198

204199
/// Save the attributes
205200
ExistentialArgDescriptor[Idx] = ETAD;
206201
LLVM_DEBUG(llvm::dbgs()
207202
<< "ExistentialSpecializer Pass:Function: " << F->getName()
208-
<< " Arg:" << Idx << "has a concrete type.\n");
203+
<< " Arg:" << Idx << " has a concrete type.\n");
209204
returnFlag |= true;
210205
}
211206
return returnFlag;

0 commit comments

Comments
 (0)