Commit Graph

2864 Commits

Author SHA1 Message Date
Andrew Trick
e9d5118bff Rewrite the static exclusivity diagnostics for noescape closures.
Rather than recognizing specific patterns of closures that we've run
across, handle a broad set of possible SIL patterns. This includes
directly applied closures and reapplied closures.

I'm not sure how to expose these SIL patterns with source level
tests. However, unlike optimization passes, the exclusivity
diagnostics cannot conservatively ignore or bail out on unrecognized
SIL, and we cannot allow future changes to SILGen and mandatory passes
to create new holes in the exclusivity model.
2018-05-08 12:44:41 -07:00
Michael Gottesman
0de2b76ec9 [func-sig-opts][+0->+1] Rename OwnershipChecker.h => OwnershipUtils.h
I am going to be expanding this to contain more general utilities so naming the
file OwnershipChecker.h really doesn't make sense.

rdar://38196046
2018-05-08 11:21:06 -07:00
David Zarzycki
8c0c55539f [SIL] NFC: Rename misleading getSwiftRValueType() to getASTType()
Reference storage types are not RValues. Also, use more SILType helper
methods to avoid line wrap.
2018-05-04 08:14:38 -04:00
Arnold Schwaighofer
1f65ee25f6 Distinguish between withoutActuallyEscaping and passing @noescape
Objective C closures when reporting that a closure has escaped

rdar://39682865
2018-05-01 07:24:19 -07:00
Arnold Schwaighofer
15e26c9640 Fix DiagnoseStaticExclusivity
After the copy_block_without_actually_escaping change it might see a
mark_dependence instruction on a noescape closure.

rdar://39682865
2018-05-01 07:24:19 -07:00
Arnold Schwaighofer
1ae309c44c ClosureLifetimeFixup: Add support for copy_block_without_escaping instructions
Replace:

  %copy = copy_block_without_escaping %block withoutEscaping %closure

  ...
  destroy_value %copy

by (roughly) the instruction sequence:

  %copy = copy_block %block

  ...
  destroy_value %copy
  %e = is_escaping %closure
  cond_fail %e
  destroy_value %closure

rdar://39682865
2018-05-01 07:24:19 -07:00
Andrew Trick
33ca063bc5 Improve -enable-verify-exclusivity.
Cleanup the memory access utilities to for more robust detection of local
initialization patterns that don't use access markers.
2018-04-25 22:40:21 -07:00
Andrew Trick
abab49e54c Support exclusivity enforcement of KeyPath read-only access.
Use begin_unpaired_access [no_nested_conflict] for
Builtin.performInstantaneousReadAccess. This can't be optimized away
and is the proper marker to use when the access scope is unknown.

Drop the requirement that
_semantics("optimize.sil.preserve_exclusivity") be @inline(never). We
actually want theses inlined into user code. Verify that the
@_semantic functions are not inlined or otherwise tampered with prior
to serialization.

Make *no* change to propagate @inline(__always) into LLVM. This no longer has
any relationship to this PR and can be investigated seperately.
2018-04-19 22:46:10 -07:00
Michael Gottesman
e58fdc81fc [Exclusivity] Add support for semantics tag "optimize.sil.preserve_exclusivity".
This is a special @_semantics attribute that preserves exclusivity even if we
are eliminating exclusivity in other parts of a module in release mode. This is
done by:

1. Teaching the Access Marker Elimination pass to skip any function with the
semantics tag.

2. Requiring all functions with the semantics tag to be noinline. This ensures
that the SIL level inliner will not inline these functions into any callers
without the protection of the semantics tag. This is enforced in IRGenPrepare
and ensures that our access markers will live to IRGen time.

3. In IRGenPrepare, we convert these functions from noinline to always
inline. After IRGen this then allows for the LLVM inliner to inline these
trivial functions that just perform the exclusivity checks ensuring that we do
not have extra calls in the fast path.

This ensures that we can fix the keypaths exclusivity issue without having to
enable exclusivity across the entire stdlib and deal with any of the potential
performance issues therein.

rdar://39335800
2018-04-19 21:37:12 -07:00
Arnold Schwaighofer
b2d1554a2c ClosureLifetimeFixup: Add missing nullptr check
rdar://39548527
2018-04-19 08:14:08 -07:00
Slava Pestov
45f3f013b0 Remove -disable-sil-linking frontend flag 2018-04-17 15:10:22 -07:00
Michael Gottesman
b05094fbed Merge pull request #15973 from gottesmm/pr-6a0bf75d9fc53d10ccd9de4251fb9b080f22a6b5
SILCleanup => IRGenPrepare.
2018-04-17 10:45:17 -07:00
Slava Pestov
6c9365023d Merge pull request #15969 from slavapestov/do-not-mandatory-inline-deserialized-funcs
SIL Optimizer: Don't run mandatory inlining on deserialized functions
2018-04-17 06:50:21 -07:00
Arnold Schwaighofer
7b472f983e Merge pull request #15927 from aschwaighofer/remove_postponed_cleanup
Remove SILGen's PostponedCleanup
2018-04-17 06:19:29 -07:00
Michael Gottesman
245325c7cd [irgen-prepare] Clean up the pass and only invalidate analyzes if we actually change something.
rdar://39335800
2018-04-17 00:07:16 -07:00
Michael Gottesman
5baa90ca4c [irgen-prepare] Move SILCleanup to ./lib/SILOptimizer/Mandatory and rename it to IRGenPrepare.
I am going to be adding logic here to enable apple/swift#1550 to be completed.
The rename makes sense due to precedent from LLVM's codegen prepare and also
since I am going to be expanding what the pass is doing beyond just "cleaning
up". It is really a grab bag pass for performing simple transformations that we
do not want to pollute IRGen's logic with.

https://github.com/apple/swift/pull/15502

rdar://39335800
2018-04-17 00:07:16 -07:00
Slava Pestov
a101fff96f SIL Optimizer: Don't run mandatory inlining on deserialized functions 2018-04-16 22:20:37 -07:00
Slava Pestov
1b79b742db Mandatory Inlining: Use loadFunction() instead of linkFunction()
We only need to deserialize the function itself, not its transitive
dependencies. Also, only deserialize a function after we've checked
that its transparent.

For now, this doesn't reduce the volume of SIL linking, because the
mandatory linker pass still links everything. But we're almost
there.
2018-04-16 16:18:50 -07:00
Slava Pestov
34d4a88df0 Mandatory Inlining: Remove outdated remark about transparent functions
Transparent function bodies are in fact available externally.
2018-04-16 16:18:50 -07:00
Arnold Schwaighofer
e6d3580b6b Add missing null check 2018-04-16 12:52:01 -07:00
swift-ci
91f8a75644 Merge pull request #15915 from devincoughlin/exclusivity-reabstraction-thunk-as-error 2018-04-16 01:25:53 -07:00
Andrew Trick
22530b922f Merge pull request #15662 from atrick/access-refactor
[NFC] Refactor access enforcement utilities into MemAccessUtils.
2018-04-15 09:25:19 -07:00
Andrew Trick
39de8c7aed Revert "Mandatory SIL linker pass" 2018-04-14 16:41:34 -07:00
Andrew Trick
9fdba965b1 [NFC] Create an AccessedStorage utility for use in multiple exclusivity related passes.
Added new files, MemAccessUtils.h and MemAccessUtils.cpp to house the
new utility. Three functions previously in InstructionUtils.h move
here:
- findAccessedAddressBase
- isPossibleFormalAccessBase
- visitAccessedAddress

Rather than working with SILValues, these routines now work with the
AccessedStorage abstraction. This allows enforcement logic and SIL
pattern recognition to be shared across diagnostics and
optimization. (It's very important for this to be consistent).

The new AccessedStorage utility is a superset of the class that was
local to DiagnoseStaticExclusivity. It exposes the full set of all
recognized kinds of storage. It also represents function arguments as
an index rather that a SILValue. This allows an analysis pass to
compare/merge AccessedStorage results from multiple callee functions,
or more naturally propagate from callee to caller context.
2018-04-13 23:07:20 -07:00
swift-ci
79b268a68b Merge pull request #15935 from atrick/safe-init 2018-04-13 18:45:15 -07:00
Slava Pestov
8cf0869351 Mandatory Inlining: Use loadFunction() instead of linkFunction()
We only need to deserialize the function itself, not its transitive
dependencies. Also, only deserialize a function after we've checked
that its transparent.

For now, this doesn't reduce the volume of SIL linking, because the
mandatory linker pass still links everything. But we're almost
there.
2018-04-13 14:26:32 -07:00
Slava Pestov
839d00ad55 Mandatory Inlining: Remove outdated remark about transparent functions
Transparent function bodies are in fact available externally.
2018-04-13 14:26:29 -07:00
Arnold Schwaighofer
e36655fddc SILGen: Remove PostponedCleanup in favor or the SIL pass that fixes
closure lifetimes.

SILGen will now unconditionally emit

  %cvt = convert_escape_to_noescape [guaranteed] %op

instructions. The mandatory ClosureLifetimeFixup pass ensures that %op's
lifetime spans %cvt's uses.

The code in DefiniteInitialization that handled a subset of cases is
removed.
2018-04-13 13:44:09 -07:00
Arnold Schwaighofer
37ed76e2b4 Make some functions static 2018-04-13 13:29:46 -07:00
Arnold Schwaighofer
f82dbef1b7 Add a ClosureLifetimeFixup pass
To replace the code in DI and eventually remove PostponedCleanup in a
follow-up.

When SILGen emits ``convert_escape_to_noescape [not_guaranteed]
%operand`` instructions it assumes that a later SIL pass (this pass)
comes along and inserts retain_value/release_value instructions such that
the lifetime of the operand for the duration of the trivial closure
result.

This commit introduces the pass but does not yet use it.
2018-04-13 13:25:07 -07:00
Arnold Schwaighofer
36d5408125 SIL: Add an [escaped] attribute to convert_escape_to_noescape instruction
To mark when a user of it is known to escape the value. This happens
with materializeForSet arguments which are captured and used in the
write-back. This means we need to keep the context alive until after
the write-back.

Follow-up patches to fully replace the PostponedCleanup hack in SILGen
by a mandatory SIL transformation pass to guarantee the proper lifetime
will use this flag to be more conservative when extending the lifetime.

The problem:

%pa = partial_apply %f(%some_context)
%cvt = convert_escape_to_noescape [not_guaranteed] [escaped] %pa
%ptr = %materialize_for_set(..., %cvt)
...  write_back
... // <-- %pa needs to be alive until after write_back
2018-04-13 12:40:10 -07:00
Andrew Trick
00df6b1b58 Remove some extraneous logic from -enable-verify-exclusivity.
Once the dust settled, this logic was only protecting a single occurrence of
memory access in SILGenLValue.cpp. It's simpler just to emit the begin/end
access markers in that case. The logic to work around it was nasty.
2018-04-12 22:09:28 -07:00
Devin Coughlin
cef3139d03 [Exclusivity] Treat warning violations with reabstraction thunks as errors
In Swift 4.1 we fixed a false negative and started looking through
reabstraction thunks to statically find exclusivity violations. To lessen
source impact, we treated these violations as warnings. This commit upgrades
those warnings to errors.

rdar://problem/34669400
2018-04-12 21:38:48 -07:00
Slava Pestov
653ce6162e SIL: Small mandatory inlining cleanup
If we have an apply of a partial_apply, all the substitutions
are performed at the partial_apply. We don't have substitutions
on the apply itself. This is unlikely to change in the future,
and it's not valid to 'concatenate' two lists of substitutions
like this anyway.
2018-04-09 13:26:23 -07:00
Slava Pestov
0dcd0d5114 SILOptimizer: Fix mandatory devirtualization of throwing methods 2018-04-05 08:53:33 -07:00
Arnold Schwaighofer
8f0976d5aa Really fix the logic error in fixupConvertEscapeToNoEscapeLifetime 2018-03-30 12:55:41 -07:00
Arnold Schwaighofer
f40ac5d6d9 Rewrite DI to always guaranteed the lifetime of the convert_escape_to_noescape [not_guaranteed] operand
Either through a peephole or we keep the closure operand alive to the end of the function

rdar://38124009
2018-03-30 09:27:53 -07:00
Arnold Schwaighofer
a9786978b2 Ensure lifetimes of optional convert_escape_to_noescape closures
rdar://38124009
2018-03-30 06:20:13 -07:00
Slava Pestov
34fd4ae512 AST: Use DeclBaseName::Kind::Constructor
Fixes <rdar://problem/35852727>, <https://bugs.swift.org/browse/SR-1660>,
<https://bugs.swift.org/browse/SR-6557>.
2018-03-16 00:25:56 -07:00
Sho Ikeda
422136e1a2 [gardening][enum class] Replace unsigned char with uint8_t for consistency
Before the changes:

- `git grep -E "enum class .+ : uint8_t \{" | wc -l`: 90
- `git grep -E "enum class .+ : unsigned char \{" | wc -l`: 26
2018-03-12 13:57:36 +09:00
Slava Pestov
76349a0f87 Squash some unused variable warnings 2018-03-08 17:05:59 -07:00
Sho Ikeda
cea6c03eb2 [gardening] Use !empty() over size() > 0 2018-03-08 09:21:09 +09:00
Sho Ikeda
25cdc981c7 Merge pull request #14977 from ikesyo/gardening-use-empty
[gardening] Use `empty()` over `size() == 0`
2018-03-07 09:34:26 +09:00
Sho Ikeda
26d650292f [gardening] Use empty() over size() == 0 2018-03-05 14:43:13 +09:00
Andrew Trick
fe72e816f8 Enable access markers at -O when -enforce-exclusivity is explicit.
-enforce-exclusivity=checked now does what it says. It emits checks at -O, not
just -Onone.

This does not change the default.
-Onone default: -enforce-exclusivity=checked
-O default: -enforce-exclusivity=unchecked
2018-03-02 16:12:28 -08:00
Andrew Trick
d96306fbad Don't run AccessEnforcementSelection on deserialized SIL and add verification.
This is a module pass, so was processing a combination of raw and deserialized
canonical SIL. The analysis makes structural assumptions that only hold prior to
mandatory inlining.

Add more verification of the structural properties.

Teach the pass to skip over canonical SIL, which only works because closures
must be serialized/deserialized in the same module as their parent.

Fixes <rdar://38042781> [Repl] crash while running SILOptimizer
2018-03-02 15:49:01 -08:00
Arnold Schwaighofer
8155707ee3 MandatoryInlining: Add a peephole for inlining thorough a thin to noescape conversion
%0 = function_ref @return_one : $@convention(thin) () -> Builtin.Int32
  %1 = convert_function %0 : $@convention(thin) () -> Builtin.Int32 to $@convention(thin) @noescape () -> Builtin.Int32
  %2 = thin_to_thick_function %1 : $@convention(thin) @noescape () -> Builtin.Int32 to $@noescape () -> Builtin.Int32
  %3 = apply %2() : $@noescape () -> Builtin.Int32

rdar://37945226
2018-02-27 10:34:08 -08:00
Andrew Trick
5921c3fb11 Reenable stripping of access markers at -O.
Until other bugs are fixed, this is still required in the short term after
mandatory inlining of debug libraries into an optimized executable.

Also, enable rerunning access marker elimination on deserialized functions,
because theoretically, the same problem could occur if we emit an external
function without inlining it.
2018-02-26 16:38:56 -08: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
5d7d02d252 Allow options: -O with -enforce-exclusivity. 2018-02-22 16:04:18 -08:00