Shuffle around some of the optimization passes.

The end goal here is to end up with a good pass ordering that will allow
us to only run one set of these passes, rather than running them
twice. This is a start in that direction.

No real impact measured on compile times as of this change. On
benchmarks I see a mix of regressions and improvements.

-O improvements:
  Calculator           -17.6%     1.21x
  Chars                -54.4%     2.19x
  PolymorphicCalls     -14.7%     1.17x
  SetIsSubsetOf        -14.1%     1.16x
  Sim2DArray           -14.1%     1.16x
  StrToInt             -30.4%     1.44x

-O regressions:
  CaptureProp          +32.9%     0.75x
  DictionarySwap       +36.0%     0.74x
  XorLoop              +39.8%     0.72x

-Ounchecked improvements:
  Chars                -58.0%     2.38x

-Ounchecked regressions:
  CaptureProp          +33.3%     0.75x

-Onone improvements:
  StrToInt             -14.9%     1.18x
  StringWalk           -47.6%     1.91x
  StringWithCString    -17.2%     1.21x
  (many more smaller improvements)

-Onone regressions:
  Calculator           +21.5%     0.82x
  OpenClose            +10.1%     0.91x
This commit is contained in:
Mark Lacey
2016-02-24 13:35:32 -08:00
parent 0a893c1f88
commit e50daa6e3b
2 changed files with 41 additions and 27 deletions

View File

@@ -172,18 +172,52 @@ void AddHighLevelLoopOptPasses(SILPassManager &PM) {
PM.addSwiftArrayOpts(); PM.addSwiftArrayOpts();
} }
// Perform classic SSA optimizations.
void AddSSAPasses(SILPassManager &PM, OptimizationLevelKind OpLevel) { void AddSSAPasses(SILPassManager &PM, OptimizationLevelKind OpLevel) {
AddSimplifyCFGSILCombine(PM); // Promote box allocations to stack allocations.
PM.addAllocBoxToStack(); PM.addAllocBoxToStack();
// Propagate copies through stack locations. Should run after
// box-to-stack promotion since it is limited to propagating through
// stack locations. Should run before aggregate lowering since that
// splits up copy_addr.
PM.addCopyForwarding(); PM.addCopyForwarding();
// Split up opaque operations (copy_addr, retain_value, etc.).
PM.addLowerAggregateInstrs(); PM.addLowerAggregateInstrs();
PM.addSILCombine();
// Split up operations on stack-allocated aggregates (struct, tuple).
PM.addSROA(); PM.addSROA();
// Promote stack allocations to values.
PM.addMem2Reg(); PM.addMem2Reg();
// Perform classic SSA optimizations. // Run the devirtualizer, specializer, and inliner. If any of these
// makes a change we'll end up restarting the function passes on the
// current function (after optimizing any new callees).
PM.addDevirtualizer();
PM.addGenericSpecializer();
switch (OpLevel) {
case OptimizationLevelKind::HighLevel:
// Does not inline functions with defined semantics.
PM.addEarlyInliner();
break;
case OptimizationLevelKind::MidLevel:
// Does inline semantics-functions (except "availability"), but not
// global-init functions.
PM.addPerfInliner();
PM.addGlobalOpt(); PM.addGlobalOpt();
PM.addLetPropertiesOpt(); PM.addLetPropertiesOpt();
break;
case OptimizationLevelKind::LowLevel:
// Inlines everything
PM.addLateInliner();
break;
}
PM.addMem2Reg();
AddSimplifyCFGSILCombine(PM);
PM.addPerformanceConstantPropagation(); PM.addPerformanceConstantPropagation();
PM.addDCE(); PM.addDCE();
PM.addCSE(); PM.addCSE();
@@ -203,26 +237,6 @@ void AddSSAPasses(SILPassManager &PM, OptimizationLevelKind OpLevel) {
PM.addSILLinker(); PM.addSILLinker();
// Run the devirtualizer, specializer, and inliner. If any of these
// makes a change we'll end up restarting the function passes on the
// current function (after optimizing any new callees).
PM.addDevirtualizer();
PM.addGenericSpecializer();
switch (OpLevel) {
case OptimizationLevelKind::HighLevel:
// Does not inline functions with defined semantics.
PM.addEarlyInliner();
break;
case OptimizationLevelKind::MidLevel:
// Does inline semantics-functions (except "availability"), but not
// global-init functions.
PM.addPerfInliner();
break;
case OptimizationLevelKind::LowLevel:
// Inlines everything
PM.addLateInliner();
break;
}
PM.addSimplifyCFG(); PM.addSimplifyCFG();
// Only hoist releases very late. // Only hoist releases very late.
if (OpLevel == OptimizationLevelKind::LowLevel) if (OpLevel == OptimizationLevelKind::LowLevel)

View File

@@ -6,12 +6,12 @@ public func test() {
e.evaluate(1) e.evaluate(1)
} }
// CHECK-LABEL: sil shared [transparent] [reabstraction_thunk] @_TTSf3cpfr69_TFFC38devirt_single_module_in_multiple_files9EvaluatorcFT_S0_U_FT_Si_n_n___TTRXFo__dSi_XFo_iT__iSi_ // CHECK-LABEL: sil shared @_TFFC38devirt_single_module_in_multiple_files9Evaluatorc
// CHECK: %{{.*}} = class_method %{{.*}} : $Problem1, #Problem1.run!1 : (Problem1) -> () -> Int , $@convention(method) (@guaranteed Problem1) -> Int // CHECK: %{{.*}} = class_method %{{.*}} : $Problem1, #Problem1.run!1 : (Problem1) -> () -> Int , $@convention(method) (@guaranteed Problem1) -> Int
// CHECK-NEXT: apply // CHECK-NEXT: apply
// CHECK: return // CHECK: return
// CHECK-LABEL: sil shared [transparent] [reabstraction_thunk] @_TTSf3cpfr70_TFFC38devirt_single_module_in_multiple_files9EvaluatorcFT_S0_U0_FT_Si_n_n___TTRXFo__dSi_XFo_iT__iSi_ // CHECK-LABEL: sil shared @_TFFC38devirt_single_module_in_multiple_files9Evaluatorc
// CHECK: %{{.*}} = class_method %{{.*}} : $Problem2, #Problem2.run!1 : (Problem2) -> () -> Int , $@convention(method) (@guaranteed Problem2) -> Int // CHECK: %{{.*}} = class_method %{{.*}} : $Problem2, #Problem2.run!1 : (Problem2) -> () -> Int , $@convention(method) (@guaranteed Problem2) -> Int
// CHECK-NEXT: apply // CHECK-NEXT: apply
// CHECK: return // CHECK: return