Skip to content

Commit b137928

Browse files
author
Harlan Haskins
committed
[SILOptimizer] Add flag to stop optimization after serialization
1 parent be0bdd1 commit b137928

File tree

4 files changed

+44
-4
lines changed

4 files changed

+44
-4
lines changed

include/swift/AST/SILOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ class SILOptions {
7070
/// Whether to dump verbose SIL with scope and location information.
7171
bool EmitVerboseSIL = false;
7272

73+
/// Whether to stop the optimization pipeline after serializing SIL.
74+
bool StopOptimizationAfterSerialization = false;
75+
7376
/// Optimization mode being used.
7477
OptimizationMode OptMode = OptimizationMode::NotSet;
7578

lib/Frontend/CompilerInvocation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,11 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
655655
}
656656
}
657657

658+
// If we're only emitting a module, stop optimizations once we've serialized
659+
// the SIL for the module.
660+
if (FEOpts.RequestedAction == FrontendOptions::ActionType::EmitModuleOnly)
661+
Opts.StopOptimizationAfterSerialization = true;
662+
658663
if (Args.hasArg(OPT_sil_merge_partial_modules))
659664
Opts.MergePartialModules = true;
660665

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,8 @@ void addHighLevelLoopOptPasses(SILPassPipelinePlan &P) {
225225
}
226226

227227
// Perform classic SSA optimizations.
228-
void addSSAPasses(SILPassPipelinePlan &P, OptimizationLevelKind OpLevel) {
228+
void addSSAPasses(SILPassPipelinePlan &P, OptimizationLevelKind OpLevel,
229+
bool stopAfterSerialization = false) {
229230
// Promote box allocations to stack allocations.
230231
P.addAllocBoxToStack();
231232

@@ -282,6 +283,9 @@ void addSSAPasses(SILPassPipelinePlan &P, OptimizationLevelKind OpLevel) {
282283
// which reduces the ability of the compiler to optimize clients
283284
// importing this module.
284285
P.addSerializeSILPass();
286+
if (stopAfterSerialization)
287+
return;
288+
285289
// Does inline semantics-functions (except "availability"), but not
286290
// global-init functions.
287291
P.addPerfInliner();
@@ -384,9 +388,12 @@ static void addMidModulePassesStackPromotePassPipeline(SILPassPipelinePlan &P) {
384388
P.addStackPromotion();
385389
}
386390

387-
static void addMidLevelPassPipeline(SILPassPipelinePlan &P) {
391+
static bool addMidLevelPassPipeline(SILPassPipelinePlan &P,
392+
bool stopAfterSerialization) {
388393
P.startPipeline("MidLevel");
389-
addSSAPasses(P, OptimizationLevelKind::MidLevel);
394+
addSSAPasses(P, OptimizationLevelKind::MidLevel, stopAfterSerialization);
395+
if (stopAfterSerialization)
396+
return true;
390397

391398
// Specialize partially applied functions with dead arguments as a preparation
392399
// for CapturePropagation.
@@ -395,6 +402,7 @@ static void addMidLevelPassPipeline(SILPassPipelinePlan &P) {
395402
// Run loop unrolling after inlining and constant propagation, because loop
396403
// trip counts may have became constant.
397404
P.addLoopUnroll();
405+
return false;
398406
}
399407

400408
static void addClosureSpecializePassPipeline(SILPassPipelinePlan &P) {
@@ -574,7 +582,8 @@ SILPassPipelinePlan::getPerformancePassPipeline(const SILOptions &Options) {
574582
addMidModulePassesStackPromotePassPipeline(P);
575583

576584
// Run an iteration of the mid-level SSA passes.
577-
addMidLevelPassPipeline(P);
585+
if (addMidLevelPassPipeline(P, Options.StopOptimizationAfterSerialization))
586+
return P;
578587

579588
// Perform optimizations that specialize.
580589
addClosureSpecializePassPipeline(P);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-swift-frontend -c -o /dev/null -O -Xllvm -sil-print-after=inline %s 2>&1 | %FileCheck %s --check-prefix NOTSKIPPING
2+
// RUN: %target-swift-frontend -emit-sil -o /dev/null -O -Xllvm -sil-print-after=inline %s 2>&1 | %FileCheck %s --check-prefix NOTSKIPPING
3+
// RUN: %target-swift-frontend -emit-module -o /dev/null -O -Xllvm -sil-print-after=inline %s 2>&1 | %FileCheck %s --check-prefix SKIPPING
4+
5+
// This test ensures that we don't run the Perf Inliner after serializing a
6+
// module, if we're stopping optimizations after serializing. We want to also
7+
// make sure we _do_ still run the Perf Inliner when we're doing a full
8+
// compile or emitting SIL directly.
9+
10+
@inline(never)
11+
func _blackHole(_ x: Int) {}
12+
13+
@inlinable
14+
public func inlinableFunction(_ x: Int) -> Int {
15+
return x + 1
16+
}
17+
18+
public func caller() {
19+
_blackHole(inlinableFunction(20))
20+
}
21+
22+
// NOTSKIPPING: *** SIL function after {{.*}}, stage MidLevel, pass {{.*}}: PerfInliner (inline)
23+
// SKIPPING-NOT: *** SIL function after {{.*}}, stage MidLevel, pass {{.*}}: PerfInliner (inline)

0 commit comments

Comments
 (0)