Skip to content

Commit 14f9e65

Browse files
author
Raj Barik
committed
Updated Existential Specializer code: (1) Remove old protocol analysis; (2) Perform transformation only if there are concrete types; (3) handle protocol and class compositions; (4) Test case covering a wide variety of scenarios
1 parent d1c8aa0 commit 14f9e65

File tree

17 files changed

+1008
-485
lines changed

17 files changed

+1008
-485
lines changed

include/swift/AST/SILOptions.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ class SILOptions {
6464
/// Remove all runtime assertions during optimizations.
6565
bool RemoveRuntimeAsserts = false;
6666

67-
/// Enable protocol devirtualization optimization.
68-
bool ProtocolDevirtualizer = false;
67+
/// Enable existential specializer optimization.
68+
bool ExistentialSpecializer = false;
6969

7070
/// Controls whether the SIL ARC optimizations are run.
7171
bool EnableARCOptimizations = true;

include/swift/Option/FrontendOptions.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,8 @@ def sil_unroll_threshold : Separate<["-"], "sil-unroll-threshold">,
390390
MetaVarName<"<250>">,
391391
HelpText<"Controls the aggressiveness of loop unrolling">;
392392

393-
def sil_protocol_devirtualizer : Flag<["-"], "sil-protocol-devirtualizer">,
394-
HelpText<"Enable SIL protocol devirtualizer optimization">;
393+
def sil_existential_specializer : Flag<["-"], "sil-existential-specializer">,
394+
HelpText<"Enable SIL existential specializer optimization">;
395395

396396
def sil_merge_partial_modules : Flag<["-"], "sil-merge-partial-modules">,
397397
HelpText<"Merge SIL from all partial swiftmodules into the final module">;

include/swift/SILOptimizer/Analysis/Analysis.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ ANALYSIS(LoopRegion)
3939
ANALYSIS(OptimizerStats)
4040
ANALYSIS(PostDominance)
4141
ANALYSIS(PostOrder)
42-
ANALYSIS(ProtocolDevirtualizer)
4342
ANALYSIS(RCIdentity)
4443
ANALYSIS(SideEffect)
4544
ANALYSIS(TypeExpansion)

include/swift/SILOptimizer/Analysis/ProtocolDevirtualizerAnalysis.h

Lines changed: 0 additions & 66 deletions
This file was deleted.

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ PASS(DeadStoreElimination, "dead-store-elim",
150150
"Dead Store Elimination")
151151
PASS(GenericSpecializer, "generic-specializer",
152152
"Generic Function Specialization on Static Types")
153-
PASS(ProtocolDevirtualizer, "protocol-devirtualizer",
154-
"Protocol Devirtualizer")
153+
PASS(ExistentialSpecializer, "existential-specializer",
154+
"Existential Specializer")
155155
PASS(GlobalOpt, "global-opt",
156156
"SIL Global Optimization")
157157
PASS(GlobalPropertyOpt, "global-property-opt",

include/swift/SILOptimizer/Utils/Generics.h

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include "swift/AST/SubstitutionMap.h"
2121
#include "swift/SIL/SILFunction.h"
2222
#include "swift/SIL/SILInstruction.h"
23-
#include "swift/SILOptimizer/Analysis/ProtocolDevirtualizerAnalysis.h"
2423
#include "swift/SILOptimizer/Utils/FunctionSignatureOptUtils.h"
2524
#include "swift/SILOptimizer/Utils/Local.h"
2625
#include "swift/SILOptimizer/Utils/SpecializationMangler.h"
@@ -302,9 +301,16 @@ class GenericFuncSpecializer {
302301
}
303302
};
304303

305-
/// ProtocolDevirtualizer transformation class that creates a protocol
304+
/// A descriptor to carry information from ExistentialTransform analysis
305+
/// to transformation.
306+
struct ExistentialTransformArgumentDescriptor {
307+
OpenedExistentialAccess AccessType;
308+
bool DestroyAddrUse;
309+
};
310+
311+
/// ExistentialSpecializer transformation class that creates a protocol
306312
/// constrained generic and a thunk.
307-
class ProtocolDevirtualizerTransform {
313+
class ExistentialSpecializerTransform {
308314
/// The original function to analyze and transform.
309315
SILFunction *F;
310316

@@ -314,49 +320,56 @@ class ProtocolDevirtualizerTransform {
314320
/// The function signature mangler we are using.
315321
Mangle::FunctionSignatureSpecializationMangler &Mangler;
316322

317-
/// Map Arguments to their ProtocolTypes.
318-
llvm::SmallDenseMap<int, std::pair<ProtocolDecl *, ClassDecl *>> &Arg2DeclMap;
323+
/// List of arguments and their descriptors to specialize
324+
llvm::SmallDenseMap<int, ExistentialTransformArgumentDescriptor> &ExistentialArgDescriptor;
319325

320326
/// Argument to Generic Type Map for NewF.
321327
llvm::SmallDenseMap<int, GenericTypeParamType *> Arg2GenericTypeMap;
322328

329+
/// Argument to Requirements Map for NewF.
330+
llvm::SmallDenseMap<int, SmallVector<Requirement, 4>> Arg2RequirementsMap;
331+
323332
// Allocate the argument descriptors.
324333
llvm::SmallVector<ArgumentDescriptor, 4> &ArgumentDescList;
325334

335+
/// List of argument indices to specialize
336+
//llvm::SmallBitVector OpenedExistentialArgIndices;
337+
326338
/// Create the Devirtualized Inner Function.
327-
void createDevirtualizedProtocolFunction();
339+
void createExistentialSpecializedFunction();
328340

329341
/// Create a name for the inner function.
330-
std::string createDevirtualizedFunctionName();
342+
std::string createExistentialSpecializedFunctionName();
331343

332344
/// Create the new devirtualized protocol function signature.
333-
CanSILFunctionType createDevirtualizedFunctionType();
345+
CanSILFunctionType createExistentialSpecializedFunctionType();
334346

335347
/// Populate the body of NewF.
336-
void populateProtocolConstrainedGenericFunction(const SILDebugScope *DS);
348+
void populateSpecializedGenericFunction();
337349

338350
/// Create the thunk.
339351
void populateThunkBody();
340352

341353
public:
342354
/// Constructor.
343-
ProtocolDevirtualizerTransform(
355+
ExistentialSpecializerTransform(
344356
SILFunction *F,
345357
Mangle::FunctionSignatureSpecializationMangler &Mangler,
346358
llvm::SmallVector<ArgumentDescriptor, 4> &ADL,
347-
llvm::SmallDenseMap<int, std::pair<ProtocolDecl *, ClassDecl *>> &Arg2DeclMap
348-
) : F(F), NewF(nullptr), Mangler(Mangler), Arg2DeclMap(Arg2DeclMap) , ArgumentDescList(ADL) {}
359+
llvm::SmallDenseMap<int, ExistentialTransformArgumentDescriptor> &ExistentialArgDescriptor
360+
) : F(F), NewF(nullptr), Mangler(Mangler), ExistentialArgDescriptor(ExistentialArgDescriptor) , ArgumentDescList(ADL) {}
349361

350362
/// Return the optimized iner function.
351-
SILFunction *getDevirtualizedProtocolFunction() { return NewF; }
363+
SILFunction *getExistentialSpecializedFunction() { return NewF; }
352364

353-
/// Run the optimization.
365+
/// External function for the optimization.
354366
bool run() {
355-
createDevirtualizedProtocolFunction();
367+
createExistentialSpecializedFunction();
356368
return true;
357369
}
358370
};
359371

372+
360373
// =============================================================================
361374
// Prespecialized symbol lookup.
362375
// =============================================================================

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,8 +568,8 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
568568
return true;
569569
}
570570
}
571-
if (Args.hasArg(OPT_sil_protocol_devirtualizer)) {
572-
Opts.ProtocolDevirtualizer = true;
571+
if (Args.hasArg(OPT_sil_existential_specializer)) {
572+
Opts.ExistentialSpecializer = true;
573573
}
574574
if (const Arg *A = Args.getLastArg(OPT_num_threads)) {
575575
if (StringRef(A->getValue()).getAsInteger(10, Opts.NumThreads)) {

lib/SILOptimizer/Analysis/Analysis.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "swift/SILOptimizer/Analysis/IVAnalysis.h"
1818
#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
1919
#include "swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h"
20-
#include "swift/SILOptimizer/Analysis/ProtocolDevirtualizerAnalysis.h"
2120
#include "swift/AST/Module.h"
2221
#include "swift/AST/SILOptions.h"
2322
#include "swift/SIL/SILModule.h"
@@ -56,7 +55,3 @@ SILAnalysis *swift::createClassHierarchyAnalysis(SILModule *M) {
5655
SILAnalysis *swift::createBasicCalleeAnalysis(SILModule *M) {
5756
return new BasicCalleeAnalysis(M);
5857
}
59-
60-
SILAnalysis *swift::createProtocolDevirtualizerAnalysis(SILModule *M) {
61-
return new ProtocolDevirtualizerAnalysis(M);
62-
}

lib/SILOptimizer/Analysis/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ set(ANALYSIS_SOURCES
1818
Analysis/LoopAnalysis.cpp
1919
Analysis/LoopRegionAnalysis.cpp
2020
Analysis/MemoryBehavior.cpp
21-
Analysis/ProtocolDevirtualizerAnalysis.cpp
2221
Analysis/RCIdentityAnalysis.cpp
2322
Analysis/SideEffectAnalysis.cpp
2423
Analysis/SimplifyInstruction.cpp

lib/SILOptimizer/Analysis/ProtocolDevirtualizerAnalysis.cpp

Lines changed: 0 additions & 59 deletions
This file was deleted.

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,14 +225,17 @@ void addSSAPasses(SILPassPipelinePlan &P, OptimizationLevelKind OpLevel) {
225225
// Promote stack allocations to values.
226226
P.addMem2Reg();
227227

228+
// Run the existentail pecializer Pass.
229+
P.addExistentialSpecializer();
230+
228231
// Cleanup, which is important if the inliner has restarted the pass pipeline.
229232
P.addPerformanceConstantPropagation();
230233
P.addSimplifyCFG();
231234
P.addSILCombine();
232235

233236
// Mainly for Array.append(contentsOf) optimization.
234237
P.addArrayElementPropagation();
235-
238+
236239
// Run the devirtualizer, specializer, and inliner. If any of these
237240
// makes a change we'll end up restarting the function passes on the
238241
// current function (after optimizing any new callees).
@@ -331,9 +334,6 @@ static void addPerfEarlyModulePassPipeline(SILPassPipelinePlan &P) {
331334

332335
// Add the outliner pass (Osize).
333336
P.addOutliner();
334-
335-
// Protocol Devirtualizer Pass.
336-
P.addProtocolDevirtualizer();
337337
}
338338

339339
static void addHighLevelEarlyLoopOptPipeline(SILPassPipelinePlan &P) {

lib/SILOptimizer/SILCombiner/SILCombiner.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "swift/SILOptimizer/Utils/Local.h"
3030
#include "llvm/ADT/DenseMap.h"
3131
#include "llvm/ADT/SmallVector.h"
32+
#include "llvm/ADT/SmallBitVector.h"
3233

3334
namespace swift {
3435

@@ -107,6 +108,21 @@ class SILCombineWorklist {
107108
}
108109
};
109110

111+
/// This struct carries information about arguments of apply instructions
112+
/// for concrete type propagation.
113+
struct ApplyArgumentDescriptor {
114+
SILValue NewArg;
115+
CanType ConcreteType;
116+
#if 0
117+
Optional<ProtocolConformanceRef> Conformance;
118+
#else
119+
ArrayRef<Optional<ProtocolConformanceRef>> Conformance;
120+
#endif
121+
ArchetypeType *OpenedArchetype;
122+
ApplyArgumentDescriptor() {}
123+
ApplyArgumentDescriptor(SILValue NewArg, CanType ConcreteType, ArrayRef<Optional<ProtocolConformanceRef>> Conformance, ArchetypeType *OpenedArchetype) : NewArg(NewArg), ConcreteType(ConcreteType), Conformance(Conformance), OpenedArchetype(OpenedArchetype) {}
124+
};
125+
110126
/// This is a class which maintains the state of the combiner and simplifies
111127
/// many operations such as removing/adding instructions and syncing them with
112128
/// the worklist.
@@ -295,6 +311,10 @@ class SILCombiner :
295311
WitnessMethodInst *WMI);
296312
SILInstruction *propagateConcreteTypeOfInitExistential(FullApplySite AI);
297313

314+
/// Create Apply Instruction with concrete types for arguments.
315+
SILInstruction *createApplyWithConcreteType(FullApplySite AI, llvm::SmallBitVector &RelevantArgIndices,
316+
llvm::SmallDenseMap<SILValue, ApplyArgumentDescriptor> &ArgDesc);
317+
298318
/// Propagate concrete types to all apply arguments.
299319
SILInstruction *propagateConcreteTypeOfInitExistentialToAllApplyArgs(FullApplySite AI);
300320

0 commit comments

Comments
 (0)