Commit Graph

410 Commits

Author SHA1 Message Date
Slava Pestov
81cf1d951d SIL: Remove -sil-link-all frontend flag
It was only used in a few tests. Those tests now use -emit-sil instead
of -emit-silgen, with some functions marked @_transparent and a few
CHECK: lines changed now that the mandatory optimizations get to run.
2018-04-09 13:27:52 -07:00
Slava Pestov
cc586594d1 SIL: Remove unnecessary performSILLinking() calls from immediate mode and REPL 2018-04-09 13:27:07 -07:00
Robert Widmann
5c7b79072b Detect and diagnose infinitely-recursive code
Add a new warning that detects when a function will call itself
recursively on all code paths.  Attempts to invoke functions like this
may cause unbounded stack growth at least or undefined behavior in the
worst cases.

The detection code is implemented as DFS for a reachable exit path in
a given SILFunction.
2018-02-26 16:27:32 -05:00
Andrew Trick
92ace2486c Rename -simplify-cfg to -jumpthread-simplify-cfg. 2018-02-22 20:16:44 -08:00
Andrew Trick
29065095ff Make DiagnoseUnreachable and NoReturnFolding function passes.
We want as few module passes as possible.

Function passes allow the PassManager to do its job.
e.g. it can filter certain functions that should not be applied to the
current pipeline. This will result in less work in the pass itself and
fewer pass manager related bugs.

Function passes are easier to understand and debug in the context of the
pipeline. Things like PrettyStackTrace are handled automatically.
Bisecting functionality is builtin.

Function passes are more compatible in general with inter-procedural
analysis.

Function passes are more efficient.

A single module pass in the middle of the pipeline destroys the benefit
of the rest of the pipeline uses function passes.
2018-02-09 09:55:47 -08:00
Andrew Trick
60cfe2f0e1 FunctionTransform should not hide its function.
There's no reason for it other than inconvenience.
2018-02-09 09:55:47 -08:00
Andrew Trick
3a15cee084 -sil-print-all (et al.) should print specialized functions when they are created. 2018-02-08 11:27:46 -08:00
David Ungar
d3f16229c0 Tweaks to shorten performCompile* a bit more.
# Conflicts:
#	lib/FrontendTool/FrontendTool.cpp
2018-02-05 17:47:47 -08:00
Erik Eckstein
bf87035a36 GlobalOpt: Move the object outlining from GlobalOpt into a separate pass "ObjectOutliner"
We run GlobalOpt multiple times in the pass pipeline but in some cases object outlining shouldn't be done too early.
Having it done in a separate pass enables to run it independently from GlobalOpt.
2018-01-19 11:32:36 -08:00
eeckstein
b126b62256 Revert "Optimization changes to completely fold OptionSet literals" 2018-01-18 22:05:07 -08:00
Erik Eckstein
1f511ab846 GlobalOpt: Move the object outlining from GlobalOpt into a separate pass "ObjectOutliner"
We run GlobalOpt multiple times in the pass pipeline but in some cases object outlining shouldn't be done too early.
Having it done in a separate pass enables to run it independently from GlobalOpt.
2018-01-18 18:27:17 -08:00
Erik Eckstein
8bc7fb860d Some improvements and simplifications regarding pass name printing in the pass manager.
* rename "Name" to "Description" in the pass definition, because it's not really the pass name, but the description of a pass
* remove the getName() from Transforms (which actually returned the description of a pass)
* in debug printing, print the pass ID and not the pass description. It makes it easier to correlate the debug output to the actual pass implementation.
* remove the iteration numbering in the pass manager, because we only run a single iteration anyway.
2018-01-09 15:35:26 -08:00
Erik Eckstein
90c21be191 Unify the implementation of optimization mode in various option classes.
This commit is mostly refactoring.

*) Introduce a new OptimizationMode enum and use that in SILOptions and IRGenOptions
*) Allow the optimization mode also be specified for specific SILFunctions. This is not used in this commit yet and thus still a NFC.

Also, fixes a minor bug: we didn’t run mandatory IRGen passes for functions with @_semantics("optimize.sil.never")
2017-11-14 11:25:02 -08:00
Roman Levenstein
53754a7a69 Add a new simple utility optimization pass for serialization of SILModules 2017-10-13 23:19:19 -07:00
Roman Levenstein
6f3b326d12 IRGen should not emit bodies of public_external functions unless it is a transparent function.
Recent changes that eliminated the -sil-serialize-all mode and adding this check to IRGen allow us to get rid of ExternalFunctionDefinitionsElimination and ExternalDefsToDecls passes, which are not needed anymore.
2017-10-11 08:29:46 -07:00
Roman Levenstein
f0a39e9e14 Add support for collecting various SIL optimizer counters
This patch implements collection and dumping of statistics about SILModules, SILFunctions and memory consumption during the execution of SIL optimization pipelines.

The following statistics can be collected:
  *  For SILFunctions: the number of SIL basic blocks, the number of SIL instructions, the number of SIL instructions of a specific kind, duration of a pass
  *  For SILModules: the number of SIL basic blocks, the number of SIL instructions, the number of SIL instructions of a specific kind, the number of SILFunctions, the amount of memory used by the compiler, duration of a pass

By default, any collection of statistics is disabled to avoid affecting compile times.

One can enable the collection of statistics and dumping of these statistics for the whole SILModule and/or for SILFunctions.

To reduce the amount of produced data, one can set thresholds in such a way that changes in the statistics are only reported if the delta between the old and the new values are at least X%. The deltas are computed as using the following formula:

   Delta = (NewValue - OldValue) / OldValue

Thresholds provide a simple way to perform a simple filtering of the collected statistics during the compilation. But if there is a need for a more complex analysis of collected data (e.g. aggregation by a pipeline stage or by the type of a transformation), it is often better to dump as much data as possible into a file using e.g. -sil-stats-dump-all -sil-stats-modules -sil-stats-functions and then e.g. use the helper scripts to store the collected data into a database and then perform complex queries on it. Many kinds of analysis can be then formulated pretty easily as SQL queries.
2017-09-10 21:47:55 -07:00
Arnold Schwaighofer
b625d4da8a Osize: Add a SIL Outliner pass that outlines the bridging of objective c calls.
Implements outlining of bridged objective c property and method calls.

rdar://33387700
2017-09-06 08:37:37 -07:00
Erik Eckstein
6c93798acc SILOptimizer: Add a new TempRValue optimization pass
This is a separate optimization that detects short-lived temporaries that can be eliminated.
This is necessary now that SILGen no longer performs basic RValue forwarding in some cases.

SR-5508: Performance regression in benchmarks caused by removing SILGen peephole for LoadExpr in +0 context
2017-08-05 17:23:51 -07:00
Michael Gottesman
9933f0f3b2 Fix the swap_refcnt test on linux.
The problem here is that we were performing a naive negative FileCheck test for
retain/release. In certain modes, we would not have any retains/releases along
normal control paths but would have retains on unreachable paths. This test only
is trying to test if normal code paths have this issue.

To work around this issue, I created a small utility pass that prunes all
non-unreachable instructions from blocks with an unreachable terminator. This is
useful functionality in general when analyzing SIL since often times one will
have large fatal error blocks that disguise the true behavior of the
function. In this specific case, I just pipe in the normal sil output and run it
through sil-opt. sil-opt then runs just the utility pass and I then FileCheck
that sil-opt output.

rdar://30181104
2017-07-07 13:03:25 -06:00
Andrew Trick
89985ebacd Use the pass's "tag" for command-line options.
A pass has an ID (C++ identifier), Tag (shell identifier),
and Name (human identifier).

Command line options that identify passes should obviously be compatibile with
with the pass' command line identifier. This is also what the user is used to
typing for the -debug-only option.
2017-07-06 14:10:23 -07:00
Andrew Trick
d45f171c98 Cleanup AccessMarkerElimination.
In raw SIL, access markers are unconditionally retained. In canonical SIL,
markers are still removed prior to optimization.

A new flag, -sil-optimized-access-markers, allows testing access markers in
optimized builds, but it is not yet fully supported.
2017-07-05 15:18:48 -07:00
Devin Coughlin
d2ac3d556b [Exclusivity] Add analysis pass summarizing accesses to inout_aliasable args
Add an interprocedural SIL analysis pass that summarizes the accesses that
closures make on their @inout_aliasable captures. This will be used to
statically enforce exclusivity for calls to functions that take noescape
closures.

The analysis summarizes the accesses on each argument independently and
uses the BottomUpIPAnalysis utility class to iterate to a fixed point when
there are cycles in the call graph.

For now, the analysis is not stored-property-sensitive -- that will come in a
later commit.
2017-06-15 07:59:18 -07:00
Joe Shajrawi
edea7d04b3 Add a flag (false by default) for large loadable types pass 2017-05-22 14:25:25 -07:00
Joe Shajrawi
17effee303 Disable large types irgen pass 2017-05-09 18:58:27 -07:00
practicalswift
492f5cd35a [gardening] Remove redundant repetition of type names (DRY): RepeatedTypeName foo = dyn_cast<RepeatedTypeName>(bar)
Replace `NameOfType foo = dyn_cast<NameOfType>(bar)` with DRY version `auto foo = dyn_cast<NameOfType>(bar)`.

The DRY auto version is by far the dominant form already used in the repo, so this PR merely brings the exceptional cases (redundant repetition form) in line with the dominant form (auto form).

See the [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es11-use-auto-to-avoid-redundant-repetition-of-type-names) for a general discussion on why to use `auto` to avoid redundant repetition of type names.
2017-05-05 09:45:53 +02:00
Joe Shajrawi
4dc0801785 IRGen Mandatory Module Pass: Pass large loadable types by address instead of by value 2017-05-01 12:04:06 -07:00
Andrew Trick
e8b0947897 [Exclusivity] Allow testing the -Onone pipeline with access markers.
Markers are always eliminated before -O passes.

At -Onone, markers can be enabled via command line for all -Onone passes.
2017-04-26 17:32:48 -07:00
practicalswift
7eb7d5b109 [gardening] Fix 100 typos. 2017-04-18 17:01:42 +02:00
Michael Gottesman
aa76c2a5e6 [silgen] (mark_uninitialized (project_box (alloc_box))) -> (project_box (mark_uninitialized (alloc_box)))
I put in a simple fixup pass (MarkUninitializedFixup) for staging purposes. I
don't expect it to be in tree long. I just did not feel comfortable fixing up in
1 commit all of the passes up to DI.

rdar://31521023
2017-04-17 17:45:54 -07:00
John McCall
b9676d2002 Add a SIL pass to select an access enforcement for allocated boxes.
Tests to come.
2017-04-11 03:10:51 -04:00
Andrew Trick
4355cad83e Add a pass to eliminate access markers. 2017-04-10 09:47:50 -07:00
Devin Coughlin
bee17f7838 [SILDiagnostics] Add static enforcement of Law of Exclusivity (#8560)
Add a diagnostic pass that emits errors when a violation of the "Law of
Exclusivity" is detected at compile time. The Law of Exclusivity requires
that the access duration of any access to an address not overlap
with an access to the same address unless both accesses are reads.

This pass relies on 'begin_access' and 'end_access' SIL instruction
markers inserted by SILGen to determine when an access to an address begins and
ends. It models the in-progress accesses with a map from storage locations to
the counts of read and write-like accesses in progress for that location.
2017-04-09 21:41:13 -07:00
Andrew Trick
be1881aa1f Remove redundant Transform.getName() definitions.
At some point, pass definitions were heavily macro-ized. Pass
descriptive names were added in two places. This is not only redundant
but a source of confusion. You could waste a lot of time grepping for
the wrong string. I removed all the getName() overrides which, at
around 90 passes, was a fairly significant amount of code bloat.

Any pass that we want to be able to invoke by name from a tool
(sil-opt) or pipeline plan *should* have unique type name, enum value,
commend-line string, and name string. I removed a comment about the
various inliner passes that contradicted that.

Side note: We should be consistent with the policy that a pass is
identified by its type. We have a couple passes, LICM and CSE, which
currently violate that convention.
2017-04-09 15:20:28 -07:00
Andrew Trick
3bcbf04d38 Rewrite unused SIL pass descriptions as proper, descriptive pass names.
I improved all of the pass names so they are minimal but fully descriptive.

The PASS macros contained wordy, unhelpful descriptions, which served
no functional purpose. Those descriptions are permanently preseved in
git history. If anyone thinks they contain useful information, then
they should be added to the *definition* of the pass (where passes are
actually described).

Long-winded pass comments have no place in Passes.def. The purpose of
those macros is to associate a unique type name, enum value,
command-line-option name, and pretty name with each pass for tooling
purposes. Any one of those entities needs to be sufficient for looking
up the others. That's not where anyone should look read a description
of the pass.
2017-04-09 15:12:53 -07:00
Michael Gottesman
5e278fdf67 [semantic-arc-opts] Create a new pass called semantic arc opts.
I am going to run it very early and use it to ensure that extra copies due to my
refactoring of SILGenPattern do not cause COW copies to be introduced.

For now, it does a very simple optimization, namely, it eliminates a copy_value,
with only a destroy_value user on a guaranteed parameter.

It is now disabled behind a flag.
2017-04-05 16:16:57 -07:00
Erik Eckstein
a0079ba5be SIL optimizations: Implement the new API for analysis invalidation.
There are now separate functions for function addition and deletion instead of InvalidationKind::Function.
Also, there is a new function for witness/vtable invalidations.

rdar://problem/29311657
2017-03-14 13:00:54 -07:00
Andrew Trick
855918c620 [Lowering] Add an AddressLowering pass. 2017-02-13 17:10:02 -08:00
Andrew Trick
2f4c84b41f SILPipelinePlan silently doesn't run some passes. Add an assert. 2017-02-13 17:10:02 -08:00
Andrew Trick
a6ebb4e914 Add an option -Xllvm -sil-print-on-error.
Print the SIL function body on an assert. Recovering the SIL code is the
critical path for pretty much any SIL development. The only alternative is
rebuilding the library with string matching or building a debug compiler and
hoping lldb works. The standard library takes a very long time to build with a
debug compiler.
2017-02-01 10:51:53 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
Hugh Bellamy
ac3b56a554 Fix errors and warnings building swift/SILOptimizer on Windows using MSVC
-
https://connect.microsoft.com/VisualStudio/feedback/details/3116505/msvc-fails-to-compile-code-that-compiles-with-clang-reports-attempting-to-reference-a-deleted-function-error-from-destructor
-
https://connect.microsoft.com/VisualStudio/feedback/details/3116636/msvc-reports-ambiguous-symbol-error-for-friend-class-declaration-in-an-anonymous-namespace
2016-12-22 18:26:58 +00:00
Arnold Schwaighofer
f1c2dcf1fa Add an alloc_stack hoisting pass.
Hoist alloc_stack instructions of 'generic' or resilient type to the entry
block. At the same time also perform a very simple stack coloring analysis.
This does not use a true liveness-analysis yet but rather employs some simple
conservative checks to see whether the live ranges of two alloc_stacks might
interfere.

AllocStackHoisting is an IRGen SIL pass. This allows for using IRGen's type
lowering information. Furthermore, hoisting and merging the alloc_stack
instructions this late does not interfere with SIL optimizations because the
resulting SIL never gets serialized.
2016-12-20 07:51:55 -08:00
Arnold Schwaighofer
f38c912878 Add support of a IRGen lowering SIL pipeline.
This pipeline is run as part of IRGen and has access to the IRGenModule.

Passes that run as part of this pipeline can query for the IRGenModule.

We will use it for the AllocStackHoisting pass. It wants to know if a type is of
non-fixed size.

To break the cyclic dependency between IRGen -> SILOptimizer -> IRGen that would
arise from the SILPassManager having to know about the createIRGENPASS()
function IRGen passes instead of exposing this function dynamically have to add
themselves to the pass manager.
2016-12-20 07:51:47 -08:00
Michael Gottesman
be5ec6f990 [passmanager] Remove ExecutionKind::UntilFixPoint and all of ExecutionKind.
rdar://29650781
2016-12-19 13:38:46 -08:00
swift-ci
268c2b668d Merge pull request #6325 from practicalswift/gardening-20161216 2016-12-17 09:19:24 -08:00
Michael Gottesman
4bfaef8ae0 [semantic-sil] Add a new pass that dumps out the ownership of all SILValue in a function and performs some minor checks upon them.
rdar://29671437
2016-12-16 17:53:49 -08:00
practicalswift
92d4aa3b91 [gardening] Use consistent headers. 2016-12-16 21:42:09 +01:00
practicalswift
77a07467bf [gardening] Fix invalid Swift URLs in headers. 2016-12-16 21:42:08 +01:00
Michael Gottesman
1a47a25e90 [sil-bug-reducer] Add pass BugReducerTester to test sil-bug-reducer.
This pass works by blowing up if it finds an apply that calls a function
specified via the cl command line option 'bug-reducer-tester-target-func'. This
makes it easy to test sil-bug-reducer.
2016-12-12 23:30:51 -08:00
Michael Gottesman
483388c9a6 [sil-bug-reducer] Wire up SILPassManager to SILPassManagerPipeline.
We also either remove or make private the addPass* functions on SILPassManager,
so the only way to execute passes via SILPassManager is by creating a
SILPassPipelinePlan. This beyond adding uniformity ensures that we always
resetAndRemoveTransformations properly after a pipeline is run.
2016-12-12 14:42:46 -08:00