Commit Graph

42 Commits

Author SHA1 Message Date
Erik Eckstein
3ec5d7de24 SIL: replace the is_escaping_closure instruction with destroy_not_escaped_closure
The problem with `is_escaping_closure` was that it didn't consume its operand and therefore reference count checks were unreliable.
For example, copy-propagation could break it.
As this instruction was always used together with an immediately following `destroy_value` of the closure, it makes sense to combine both into a `destroy_not_escaped_closure`.
It
1. checks the reference count and returns true if it is 1
2. consumes and destroys the operand
2025-01-24 19:23:27 +01:00
Tim Kientzle
1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
2024-06-05 19:37:30 -07:00
Andrew Trick
1be703cbe1 Handle startAsyncLetWithLocalBuffer in exclusivity diagnostics.
Fixes rdar://128981120 (Crash when inout arg captured through some
closures? (llvm::all_of(apply->getUses(), hasExpectedUsesOfNoEscapePartialApply)
&& "noescape partial_apply has unexpected use!"))
2024-05-30 13:36:44 -07:00
Rick van Voorden
f8ae46b3f3 [inclusive-language] changed sanity to soundness 2024-01-25 18:18:02 -08:00
Michael Gottesman
37d60a08bb [move-only] Rename mark_must_check -> mark_unresolved_non_copyable_value.
I was originally hoping to reuse mark_must_check for multiple types of checkers.
In practice, this is not what happened... so giving it a name specifically to do
with non copyable types makes more sense and makes the code clearer.

Just a pure rename.
2023-08-30 22:29:30 -07:00
Michael Gottesman
7e992cef6c [move-only] When emitting exclusivity diagnostics for move only types, do not suggest to the user to make a local copy.
It doesn't make sense to give this note since one can't make a copy of a
noncopyable type.

rdar://108511627
2023-04-25 10:51:04 -07:00
Nate Chandler
85b0cd55c8 [AccessSummaryAnalysis] Allow move PAI users.
It is legal for a `move_value` to appear as a transitive user of a
`partial_apply`.  Look through those like the other ownership
instructions.

rdar://107963619
2023-04-12 15:51:34 -07:00
Joe Groff
69e4b95fb8 SIL: Model noescape partial_applys with ownership in OSSA.
Although nonescaping closures are representationally trivial pointers to their
on-stack context, it is useful to model them as borrowing their captures, which
allows for checking correct use of move-only values across the closure, and
lets us model the lifetime dependence between a closure and its captures without
an ad-hoc web of `mark_dependence` instructions.

During ownership elimination, We eliminate copy/destroy_value instructions and
end the partial_apply's lifetime with an explicit dealloc_stack as before,
for compatibility with existing IRGen and non-OSSA aware passes.
2023-02-16 21:43:53 -08:00
Andrew Trick
ddf0965d3f Rewrite ClosureScopeAnalysis for generality.
Handle recursive non-escaping local functions.

Previously, it was thought that recursion would force a closure to be
escaping. This is not necessarilly true.

Update AccessEnforcementSelection to conservatively handle closure cycles.

Fixes rdar://88726092 (Compiler hangs when building)
2022-03-18 02:28:53 -07:00
Min-Yih Hsu
343d842394 [SIL][DebugInfo] PATCH 3/3: Deprecate debug_value_addr SIL instruciton
This patch removes all references to DebugValueAddrInst class and
debug_value_addr instruction in textual SIL files.
2021-08-31 12:01:04 -07:00
Min-Yih Hsu
e1023bc323 [DebugInfo] PATCH 2/3: Duplicate logics regarding debug_value_addr
This patch replace all in-memory objects of DebugValueAddrInst with
DebugValueInst + op_deref, and duplicates logics that handles
DebugValueAddrInst with the latter. All related check in the tests
have been updated as well.

Note that this patch neither remove the DebugValueAddrInst class nor
remove `debug_value_addr` syntax in the test inputs.
2021-08-31 11:57:56 -07:00
Andrew Trick
b0dc18dd04 Fix an assert in exclusivity diagnostics when inouts escape.
An error found in DiagnoseInvalidEscapingCaptures can indicate invalid
SIL, which will cause DiagnoseStaticExclusivity to assert during SIL
verification. When the source-level closure captures an inout
argument, it appears in SIL to be a non-escaping closure. The SIL
verification then fails because the "nonescaping" closure actually
escapes.

Ensure that capture diagnostics run on closures before exclusivity
enforcement runs on the parent function. Bypass the SIL verification
assert if a diagnostic error was found.

Fixes rdar://75364904 (Crash with assertion `noescape partial_apply
has unexpected use`)
2021-05-05 17:06:30 -07:00
Erik Eckstein
479517f71d AccessSummaryAnalysis: relax the verification of expected no-escape partial_apply uses
* add is_escaping_closure as allowed instruction
* don't restrict the uses of copy_value to be a store

Fixes a verification crash (only in assert builds).

https://bugs.swift.org/browse/SR-14394
rdar://75740622
2021-03-29 13:21:43 +02:00
Andrew Trick
85ff15acd3 Add indexTrieRoot to the SILModule to share across Analyses.
...and avoid reallocation.

This is immediately necessary for LICM, in addition to its current
uses. I suspect this could be used by many passes that work with
addresses. RLE/DSE should absolutely migrate to it.
2020-10-16 15:00:09 -07:00
Andrew Trick
5ae231eaab Rename getFieldNo() to getFieldIndex().
Do I really need to justify this?
2020-09-24 22:44:13 -07:00
Andrew Trick
6823b100a7 Diagnose exclusivity in the presence of coroutines.
Potentially source breaking: SR-11700 Diagnose exclusivity violations
with Dictionary.subscript._modify:

  Exclusivity violations within code that computes the `default`
  argument during Dictionary access are now diagnosed.

  ```swift
  struct Container {
     static let defaultKey = 0

     var dictionary = [defaultKey:0]

     mutating func incrementValue(at key: Int) {
       dictionary[key, default: dictionary[Container.defaultKey]!] += 1
     }
  }
  error: overlapping accesses to 'self.dictionary', but modification requires exclusive access; consider copying to a local variable
       dictionary[key, default: dictionary[Container.defaultKey]!] += 1
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  note: conflicting access is here
       dictionary[key, default: dictionary[Container.defaultKey]!] += 1
                                ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
  ```

This reworks the logic so that four problems end up being fixed:

Fixes three problems related to coroutines:

(1) DiagnoseStaticExclusivity must consider begin_apply as a user of accessed variables. This was an undefined behavior hole in the diagnostics.

(2) AccessedSummaryAnalysis should consider begin_apply as a user of accessed arguments. This does not show up in practice because coroutines don't capture things.

(3) AccessedSummaryAnalysis must consider begin_apply a valid user of
    noescape closures.

And fixes one problem related to resilience:

(4) AccessedSummaryAnalysis must conservatively consider arguments to external functions.

Fixes <rdar://problem/56378713> Investigate why AccessSummaryAnalysis is crashing
2020-04-28 10:57:40 -07:00
Arnold Schwaighofer
8aaa7b4dc1 SILOptimizer: Pipe through TypeExpansionContext 2019-11-11 14:21:52 -08:00
Jordan Rose
171ff440fc Remove swift::reversed in favor of llvm::reverse (#27610)
The former predates the latter, but we don't need it anymore! The
latter has more features anyway.

No functionality change.
2019-10-10 17:16:09 -07:00
Slava Pestov
83c90b6b2a AST: Turn NominalTypeDecl::getStoredProperties() into a request
This improves on the previous situation:

- The request ensures that the backing storage for lazy properties
  and property wrappers gets synthesized first; previously it was
  only somewhat guaranteed by callers.

- Instead of returning a range this just returns an ArrayRef,
  which simplifies clients.

- Indexing into the ArrayRef is O(1), which addresses some FIXMEs
  in the SIL optimizer.
2019-07-16 16:38:38 -04:00
swift-ci
528fe6a32b Merge pull request #22007 from shahzadlone/master 2019-01-20 10:54:09 -08:00
Shahzad Lone
0ff69d4fe5 Prefer Pre-Inc to Post-Inc.
Change all post-increments to pre-increments.

For example consider the following:
```
class Integer {

  public:

  // Sample implementation of pre-incrementing.
  Integer & operator++() {
    myInt += 1;
    return *this;
  }
  // Sample implementation of post-incrementing.
  const Integer operator++(int) {
    Integer temporary = *this;
    ++*this;
    return temporary;
  }

  private:

  int myInt;
};
```

The additional copy (temporary) in post-incrementing step is unnecessary.
2019-01-20 04:27:46 -05:00
Arnold Schwaighofer
13498c46bd Fix exclusivity accesss enforcement for partial_apply [stack] 2019-01-15 11:32:10 -08:00
Arnold Schwaighofer
7e32c68e1d Add new SIL instruction for calling dynamically_replaceable funtions
%0 = dynamic_function_ref @dynamically_replaceable_function
  apply %0()
  Calls a [dynamically_replaceable] function.

  %0 = prev_dynamic_function_ref @dynamic_replacement_function
  apply %0
  Calls the previous implementation that dynamic_replacement_function
  replaced.
2018-11-06 09:53:22 -08:00
Jordan Rose
de7b8ff071 Replace 'delete's with std::unique_ptr throughout SILOptimizer 2018-09-18 09:44:01 -07:00
Andrew Trick
8d41d6ef5f Enable strict verification of begin_access patterns in all SIL passes. (#17534)
* Teach findAccessedStorage about global addressors.

AccessedStorage now properly represents access to global variables, even if they
haven't been fully optimized down to global_addr instructions.

This is essential for optimizing dynamic exclusivity checks. As a
verified SIL property, all access to globals and class properties
needs to be identifiable.

* Add stronger SILVerifier support for formal access.

Ensure that all formal access follows recognizable patterns
at all points in the SIL pipeline.

This is important to run acccess enforcement optimization late in the pipeline.
2018-06-27 23:40:52 -07:00
Devin Coughlin
be60d9bc10 [Exclusivity] Teach separate-stored-property relaxation about TSan instrumentation
The compile-time exclusivity diagnostics explicitly allow conflicting accesses
to a struct when it can prove that the two accesses are used to project addresses
for separate stored properties. Unfortunately, the logic that detects this special
case gets confused by Thread Sanitizer's SIL-level instrumentation. This causes
the exclusivity diagnostics to have false positives when TSan is enabled.

To fix this, teach the AccessSummaryAnalysis to ignore TSan builtins when
determining whether an access has a single projected subpath.

rdar://problem/40455335
2018-06-10 16:44:19 -07:00
Arnold Schwaighofer
c4ed564a46 Fixes to AccessSummaryAnalysis
The pattern we see for noescape closure passed to objective c is different:
There is the additional without actually escaping closure sentinel.

rdar://39682865
2018-05-01 07:24:19 -07:00
Arnold Schwaighofer
4745a7e280 AccessSummaryAnalysis: ConvertEscapeToNoEscapeInst is an expected use of partial_apply 2018-02-13 04:19:59 -08:00
Michael Gottesman
6d654b3cbd [+0-all-args] Loosen whitelist in AccessSummaryAnalysis to allow partial applies to be borrowed.
rdar://34222540
2017-11-28 21:47:33 -08:00
John McCall
ab3f77baf2 Make SILInstruction no longer a subclass of ValueBase and
introduce a common superclass, SILNode.

This is in preparation for allowing instructions to have multiple
results.  It is also a somewhat more elegant representation for
instructions that have zero results.  Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction.  Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.

A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.

Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.
2017-09-25 02:06:26 -04:00
Jordan Rose
f8b7db4e76 Excise the terms "blacklist" and "whitelist" from Swift source. (#11687)
The etymology of these terms isn't about race, but "black" = "blocked"
and "white" = "allowed" isn't really a good look these days. In most
cases we weren't using these terms particularly precisely anyway, so
the rephrasing is actually an improvement.
2017-08-30 09:28:00 -07:00
Devin Coughlin
47d9de9751 [Exclusivity] Relax closure enforcement on separate stored properties (#10789)
Make the static enforcement of accesses in noescape closures stored-property
sensitive. This will relax the existing enforcement so that the following is
not diagnosed:

struct MyStruct {
   var x = X()
   var y = Y()

  mutating
  func foo() {
    x.mutatesAndTakesClosure() {
      _ = y.read() // no-warning
   }
  }
}

To do this, update the access summary analysis to summarize accesses to
subpaths of a capture.

rdar://problem/32987932
2017-07-10 13:33:22 -07:00
Devin Coughlin
2501dd71de Revert "[Exclusivity] Relax closure enforcement on separate stored properties" 2017-07-05 20:19:50 -07:00
Devin Coughlin
86dff5c0a7 [Exclusivity] Relax closure enforcement on separate stored properties
Make the static enforcement of accesses in noescape closures stored-property
sensitive. This will relax the existing enforcement so that the following is
not diagnosed:

struct MyStruct {
   var x = X()
   var y = Y()

  mutating
  func foo() {
    x.mutatesAndTakesClosure() {
      _ = y.read()
   }
  }
}

To do this, update the access summary analysis to be stored-property sensitive.

rdar://problem/32987932
2017-07-05 16:09:54 -07:00
Andrew Trick
c7cb964053 Disable an unnecessary assert in AccessSummaryAnalysis.
I’m totally disabling this assert in 4.0. Tracking down a compiler crash for
each obscure case of missing access marker is not a good use of time since we’re
not actually fixing these cases when we find them anyway. Instead, post 4.0, we
will catch all of these missing cases by implementing strong SIL
verification. Much more SILGen work is really required to fully implement
exclusivity diagnostics. SIL verification will be necessary to drive that.

Fixes <rdar://problem/33024357> AccessSummaryAnalysis assert "Unrecognized
argument use" building source compatibility siesta project.
2017-06-27 23:53:18 -07:00
Andrew Trick
9a11f9977a Strengthen an assertion in AccessSummaryAnalysis.
Mark Lacey caught this bug in the assertion logic that looks for expected SIL
patterns involving non-escaping closures. I broadened it to allow multiple use,
but it was only verifying the first use. This is NFC w.r.t. our automated
testing because that never hits the multiple-use case.
2017-06-22 10:58:01 -07:00
Andrew Trick
b07e145ae5 Fix an assertion in DiagnostStaticExclusivity and add a .sil test.
This is a same-day fix for a typo introduced here:

commit c2c55eea12
Author: Andrew Trick <atrick@apple.com>
Date:   Wed Jun 21 16:08:06 2017

    AccessSummaryAnalysis: handle @convention(block) in nested nonescape closures.
2017-06-21 23:15:26 -07:00
Andrew Trick
c2c55eea12 AccessSummaryAnalysis: handle @convention(block) in nested nonescape closures.
This analysis has a whitelist to ensure that we aren't missing any SIL
patterns and failing to enforce some cases.

There is a special case involving nested non-escaping closures being passed as a
block argument.  Whitelist this very special case even though we don't enforce
it because the corresponding diagnostics pass also doesn't enforce it.
2017-06-21 19:39:12 -07:00
Andrew Trick
e27bdf706e Add utilities to ApplySite to avoid hardcoding parameter/argument offsets. 2017-06-20 00:01:52 -07:00
Devin Coughlin
5ec0563c16 [Exclusivity] Statically enforce exclusive access in noescape closures (#10310)
Use the AccessSummaryAnalysis to statically enforce exclusive access for
noescape closures passed as arguments to functions.

We will now diagnose when a function is passed a noescape closure that begins
an access on capture when that same capture already has a conflicting access
in progress at the time the function is applied.

The interprocedural analysis is not yet stored-property sensitive (unlike the
intraprocedural analysis), so this will report violations on accesses to
separate stored properties of the same struct.

rdar://problem/32020710
2017-06-17 22:52:29 +01:00
Devin Coughlin
06b9ed7501 [Exclusivity] Switch static checking to use IndexTrie instead of ProjectionPath
IndexTrie is a more light-weight representation and it works well in this case.
This requires recovering the represented sequence from an IndexTrieNode, so
also add a getParent() method.
2017-06-15 18:37:23 -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