Add frontend flags for developers to easily control copy propagation:

-enable-copy-propagation: enables whatever form of copy propagation
 the current pipeline runs (mandatory-copy-propagation at -Onone,
 regular copy-propation at -O).

-disable-copy-propagation: similarly disables any form of copy
 propagation in the current pipelien.
This commit is contained in:
Andrew Trick
2021-03-02 20:31:59 -08:00
parent b689b1dabe
commit a77ced8423
5 changed files with 38 additions and 11 deletions

View File

@@ -44,6 +44,16 @@ public:
/// Remove all runtime assertions during optimizations. /// Remove all runtime assertions during optimizations.
bool RemoveRuntimeAsserts = false; bool RemoveRuntimeAsserts = false;
/// Force-run SIL copy propagation to shorten object lifetime in whatever
/// optimization pipeline is currently used.
/// When this is 'false' the pipeline has default behavior.
bool EnableCopyPropagation = false;
/// Disable SIL copy propagation to preserve object lifetime in whatever
/// optimization pipeline is currently used.
/// When this is 'false' the pipeline has default behavior.
bool DisableCopyPropagation = false;
/// Controls whether the SIL ARC optimizations are run. /// Controls whether the SIL ARC optimizations are run.
bool EnableARCOptimizations = true; bool EnableARCOptimizations = true;

View File

@@ -188,6 +188,11 @@ def batch_scan_input_file
def import_prescan : Flag<["-"], "import-prescan">, def import_prescan : Flag<["-"], "import-prescan">,
HelpText<"When performing a dependency scan, only dentify all imports of the main Swift module sources">; HelpText<"When performing a dependency scan, only dentify all imports of the main Swift module sources">;
def enable_copy_propagation : Flag<["-"], "enable-copy-propagation">,
HelpText<"Run SIL copy propagation to shorten object lifetime.">;
def disable_copy_propagation : Flag<["-"], "disable-copy-propagation">,
HelpText<"Don't run SIL copy propagation to preserve object lifetime.">;
} // end let Flags = [FrontendOption, NoDriverOption] } // end let Flags = [FrontendOption, NoDriverOption]
def debug_crash_Group : OptionGroup<"<automatic crashing options>">; def debug_crash_Group : OptionGroup<"<automatic crashing options>">;

View File

@@ -1185,6 +1185,8 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
// -Ounchecked might also set removal of runtime asserts (cond_fail). // -Ounchecked might also set removal of runtime asserts (cond_fail).
Opts.RemoveRuntimeAsserts |= Args.hasArg(OPT_RemoveRuntimeAsserts); Opts.RemoveRuntimeAsserts |= Args.hasArg(OPT_RemoveRuntimeAsserts);
Opts.EnableCopyPropagation |= Args.hasArg(OPT_enable_copy_propagation);
Opts.DisableCopyPropagation |= Args.hasArg(OPT_disable_copy_propagation);
Opts.EnableARCOptimizations &= !Args.hasArg(OPT_disable_arc_opts); Opts.EnableARCOptimizations &= !Args.hasArg(OPT_disable_arc_opts);
Opts.EnableOSSAModules |= Args.hasArg(OPT_enable_ossa_modules); Opts.EnableOSSAModules |= Args.hasArg(OPT_enable_ossa_modules);
Opts.EnableOSSAOptimizations &= !Args.hasArg(OPT_disable_ossa_opts); Opts.EnableOSSAOptimizations &= !Args.hasArg(OPT_disable_ossa_opts);

View File

@@ -350,7 +350,9 @@ void addFunctionPasses(SILPassPipelinePlan &P,
if (P.getOptions().EnableOSSAModules) { if (P.getOptions().EnableOSSAModules) {
// We earlier eliminated ownership if we are not compiling the stdlib. Now // We earlier eliminated ownership if we are not compiling the stdlib. Now
// handle the stdlib functions, re-simplifying, eliminating ARC as we do. // handle the stdlib functions, re-simplifying, eliminating ARC as we do.
P.addCopyPropagation(); if (!P.getOptions().DisableCopyPropagation) {
P.addCopyPropagation();
}
P.addSemanticARCOpts(); P.addSemanticARCOpts();
} }
@@ -372,7 +374,9 @@ void addFunctionPasses(SILPassPipelinePlan &P,
// Clean up Semantic ARC before we perform additional post-inliner opts. // Clean up Semantic ARC before we perform additional post-inliner opts.
if (P.getOptions().EnableOSSAModules) { if (P.getOptions().EnableOSSAModules) {
P.addCopyPropagation(); if (!P.getOptions().DisableCopyPropagation) {
P.addCopyPropagation();
}
P.addSemanticARCOpts(); P.addSemanticARCOpts();
} }
@@ -437,7 +441,9 @@ void addFunctionPasses(SILPassPipelinePlan &P,
// Run a final round of ARC opts when ownership is enabled. // Run a final round of ARC opts when ownership is enabled.
if (P.getOptions().EnableOSSAModules) { if (P.getOptions().EnableOSSAModules) {
P.addCopyPropagation(); if (!P.getOptions().DisableCopyPropagation) {
P.addCopyPropagation();
}
P.addSemanticARCOpts(); P.addSemanticARCOpts();
} }
} }
@@ -471,7 +477,9 @@ static void addPerfEarlyModulePassPipeline(SILPassPipelinePlan &P) {
// Cleanup after SILGen: remove trivial copies to temporaries. // Cleanup after SILGen: remove trivial copies to temporaries.
P.addTempRValueOpt(); P.addTempRValueOpt();
// Cleanup after SILGen: remove unneeded borrows/copies. // Cleanup after SILGen: remove unneeded borrows/copies.
P.addCopyPropagation(); if (!P.getOptions().DisableCopyPropagation) {
P.addCopyPropagation();
}
P.addSemanticARCOpts(); P.addSemanticARCOpts();
// Devirtualizes differentiability witnesses into functions that reference them. // Devirtualizes differentiability witnesses into functions that reference them.
@@ -785,7 +793,9 @@ SILPassPipelinePlan::getPerformancePassPipeline(const SILOptions &Options) {
// Run one last copy propagation/semantic arc opts run before serialization/us // Run one last copy propagation/semantic arc opts run before serialization/us
// lowering ownership. // lowering ownership.
if (P.getOptions().EnableOSSAModules) { if (P.getOptions().EnableOSSAModules) {
P.addCopyPropagation(); if (!P.getOptions().DisableCopyPropagation) {
P.addCopyPropagation();
}
P.addSemanticARCOpts(); P.addSemanticARCOpts();
} }
@@ -835,8 +845,10 @@ SILPassPipelinePlan::getOnonePassPipeline(const SILOptions &Options) {
P.startPipeline("non-Diagnostic Enabling Mandatory Optimizations"); P.startPipeline("non-Diagnostic Enabling Mandatory Optimizations");
P.addForEachLoopUnroll(); P.addForEachLoopUnroll();
P.addMandatoryCombine(); P.addMandatoryCombine();
// MandatoryCopyPropagation should only be run at -Onone, not -O. if (P.getOptions().EnableCopyPropagation) {
P.addMandatoryCopyPropagation(); // MandatoryCopyPropagation should only be run at -Onone, not -O.
P.addMandatoryCopyPropagation();
}
// TODO: MandatoryARCOpts should be subsumed by CopyPropagation. There should // TODO: MandatoryARCOpts should be subsumed by CopyPropagation. There should
// be no need to run another analysis of copies at -Onone. // be no need to run another analysis of copies at -Onone.
P.addMandatoryARCOpts(); P.addMandatoryARCOpts();

View File

@@ -136,11 +136,9 @@ void CopyPropagation::run() {
} }
SILTransform *swift::createMandatoryCopyPropagation() { SILTransform *swift::createMandatoryCopyPropagation() {
return new CopyPropagation(/*pruneDebug*/ true, /*unownedRemnant*/ true, return new CopyPropagation(/*pruneDebug*/ true, /*canonicalizeAll*/ true);
/*canonicalizeAll*/ true);
} }
SILTransform *swift::createCopyPropagation() { SILTransform *swift::createCopyPropagation() {
return new CopyPropagation(/*pruneDebug*/ true, /*unownedRemnant*/ false, return new CopyPropagation(/*pruneDebug*/ true, /*canonicalizeAll*/ false);
/*canonicalizeAll*/ false);
} }