Commit Graph

2037 Commits

Author SHA1 Message Date
Alejandro Alonso
45d7ea39a5 Merge pull request #75518 from Azoy/integer-generics
Implement Value generics
2024-09-05 15:33:46 -07:00
Alejandro Alonso
b35ac50d3c Optimize TypeValueInst in Swift 2024-09-04 15:13:48 -07:00
Michael Gottesman
eda603d2c9 [region-isolation] Add mocking for getSourceInst so that unittests still work. 2024-09-04 12:55:09 -07:00
Michael Gottesman
3cfcc173e9 [region-isolation] Do not allow for a disconnected value passed as an explicitly sent parameter to be reused.
This only occurs specifically for async nonisolated functions with an isolated
parameter that passes a disconnected value in its body off to a nonisolated
async function as a sending parameter.

rdar://134409359
2024-09-03 17:41:59 -07:00
Kavon Farvardin
7203a4fa73 ColdBlockInfo: overhaul analysis pass
The old analysis pass doesn't take into account profile data, nor does
it consider post-dominance. It primarily dealt with _fastPath/_slowPath.

A block that is dominated by a cold block is itself cold. That's true
whether it's forwards or backwards dominance.

We can also consider a call to any `Never` returning function as a
cold-exit, though the block(s) leading up to that call may be executed
frequently because of concurrency. For now, I'm ignoring the concurrency
case and assuming it's cold. To make use of this "no return" prediction,
use the `-enable-noreturn-prediction` flag, which is currently off by
default.
2024-09-03 15:41:10 -07:00
Egor Zhdan
b3c13e445e Merge pull request #74094 from swiftlang/egorzhdan/scs-inline-dtor
[cxx-interop][SwiftCompilerSources] Remove a workaround
2024-09-03 12:37:35 +01:00
Ryan Mansfield
908d97dde5 SIL: Fix cl::desc typos. [NFC] 2024-08-29 16:26:56 -04:00
Erik Eckstein
b54117c22d GenericSpecializer: drop unused indirect arguments.
If there is no read from an indirect argument, this argument has to be dropped.
At the call site the store to the argument's memory location could have been removed (based on the callee's memory effects).
Therefore, converting such an unused indirect argument to a direct argument, would load an uninitialized value at the call site.
This would lead to verifier errors and in worst case to a miscompile because IRGen can implicitly use dead arguments, e.g. for getting the type of a class reference.
2024-08-26 11:19:12 +02:00
Erik Eckstein
c8e74b8393 Generic specialization: change the mangling for dropped metatype arguments
Instead of adding a "flag" (`m` in `...Tgm5`) make it more generic to allow to drop any unused argument.
Add all dropped arguments with a `t<n-1>` (where `<n-1>` is empty for n === 0). For example `...Ttt2g5`.
2024-08-26 10:43:15 +02:00
Michael Gottesman
582144a017 Merge pull request #75960 from gottesmm/pr-d0a4bbf70b470c53c7f2435ee53051da8fd643d3
[region-isolation] Move the region isolation logging decls out of PartitionUtils.h -> RegionIsolation.h
2024-08-19 15:06:51 -07:00
Michael Gottesman
b477433a20 [region-isolation] Move the region isolation logging decls out of PartitionUtils.h -> RegionIsolation.h
These do not specifically have to do with PartitionUtils... they are really
logging options for the whole infrastructure, so it makes sense to have them in
the a different file.
2024-08-19 11:28:55 -07:00
Michael Gottesman
4bb2e4f3b1 [region-isolation] Improve the error we emit for closure literals captured as a sending parameter.
Specifically:

I changed the main error message to focus on the closure and that the closure
is being accessed concurrently.

If we find that we captured a value that is the actual isolation source, we
emit that the capture is actually actor isolated.

If the captured value is in the same region as the isolated value but is not
isolated, we instead say that the value is accessible from *-isolated code or
code within the current task.

If we find multiple captures and we do not which is the actual value that was
in the same region before we formed the partial apply, we just emit a note on
the captures saying that the closure captures the value.

I changed the diagnostics from using the phrase "task-isolated" to use some
variant of accessible to code in the current task.

The idea is that in all situations we provide a breadcrumb that the user can
start investigating rather than just saying that the closure is "task-isolated".

From a preconcurrency perspective, I made it so that we apply the preconcurrency
behavior of all of the captures. This means that if one of the captures is
preconcurrency, we apply the preconcurrency restriction to the closure. This is
one step towards making it so that preconcurrency applies at the region level...
we just are not completely there yet.

rdar://133798044
2024-08-14 10:37:31 -07:00
Michael Gottesman
8a20df1c44 [region-isolation] When dumping send never-sendable errors, dump the isolated value and its name if we can compute it.
This just makes it quicker/easier to diagnose inability to infer the appropriate
name of an isolated value and what the isolated value itself is.
2024-08-12 11:35:57 -07:00
Michael Gottesman
2dd1ef2322 Merge pull request #75759 from gottesmm/variable-name-utils-refactor
[variable-name-utils] Change internal representation to use StringRef instead of a SILValue
2024-08-07 19:37:46 -07:00
Michael Gottesman
1fbc930cdd [region-isolation] Make logging and debug tooling appear in non-asserts builds.
This will just help me to more quickly triage without needing to compile an
asserts compiler.
2024-08-07 13:35:18 -07:00
Michael Gottesman
0039b286b5 [variable-name-inference] Eliminate the old value representation and just use StringRef. 2024-08-07 13:14:50 -07:00
Michael Gottesman
1e2fb39362 [variable-name-utils] Fix thinko.
rootValue isn't always around... so stash the ASTContext on construction.
2024-08-07 13:14:50 -07:00
Michael Gottesman
63b67389b0 [variable-name-utils] Convert all DebugVarCarryingInst|VarDeclCarryingInst to the new representation of storing a StringRef. 2024-08-07 13:14:50 -07:00
Michael Gottesman
76f67cf092 [variable-name-utils] Convert all gep like instructions except ref_element_addr to be put on the stack as StringRefs instead of values. 2024-08-07 13:14:50 -07:00
Michael Gottesman
3d85f47671 [variable-name-utils] Store a std::variant instead of a pointer union and add the ability to append StringRef.
CONTEXT: This code works by building up a stack of SIL values of values that
need to be transformed into a StringRef as part of generating our name path and
then as a second phase performs the conversion of those values to StringRef as
we pop from the stack.

This is the first in a string of commits that are going to refactor
VariableNameUtils so that the stack will only contain StringRef instead of SIL
entities. This will be accomplished by moving the SIL value -> StringRef code
from the combining part of the algorithm (where we drain the stack) to the
construction of the stack.

The reason why I am doing this is two fold:

1. By just storing StringRef into the stack I am simplifying the code. Today as
mentioned above in the context, we gather up the SILValue we want to process and
then just convert them to StringRef. This means that any time one has to add a
new instruction, one has to update two different pieces of code. By trafficking
in StringRef instead, one only has to update one piece of code.

2. I want to add some simple code that allows for us to get names from closures
which would require me to recurse. I am nervous about putting
values/instructions from different functions in the same data structure. Today
it is safe, but it is bad practice. Instead, by just using StringRef in the
stack, I can avoid this problem.
2024-08-07 13:14:50 -07:00
Michael Gottesman
d8d4989325 [region-isolation] Add a comment to VariableNamePathArray that explains its "snapshot" functionality and why it is useful. 2024-08-05 16:58:20 -07:00
Michael Gottesman
a75501e985 [region-isolation] Eliminate the last non-SIL test case usage of SILIsolationInfo::getWithIsolationCrossing().
The reason that I am changing this code is that getWithIsolationCrossing is a
bad API that was being used to infer actor isolation straight from an ApplyExpr
without adding an actor instance. This can cause us to reject programs
unnecessarily if we in other parts of the code correctly infer the SILValue
actor instance for the isolation.

Rather than allow for that, I am removing this code and I improved the rest of
the pattern matching here to ensure that we handled that with the normal actor
instance inferring code. This will prevent this type of mismerge from happening
by mistake. I fixed up the changes in the test cases.

The only usage of this left is for ApplyIsolationCrossings parsed straight from
SIL that we use only when testing. This is safe since if a test writer is using
the parsed SIL in this manner, they can make sure that mismerges do not happen.
2024-07-31 13:10:01 -07:00
Michael Gottesman
541863dbc6 [region-isolation] Fix handling of coroutine apply results.
In this part of the code, we are attempting to merge all of the operands into
the same region and then assigning all non-Sendable results of the function to
that same region. The problem that was occuring here was a thinko due to the
control flow of the code here not separating nicely the case of whether or not
we had operands or not. Previously this did not matter, since we just used the
first result in such a case... but since we changed to assign to the first
operand element in some cases, it matters now. To fix this, I split the confused
logic into two different easy to follow control paths... one if we have operands
and one where we do not have an operand. In the case where we have a first
operand, we merge our elements into its region. If we do not have any operands,
then we just perform one large region assign fresh.

This was not exposed by code that used non-coroutines since in SIL only
coroutines today have multiple results.

rdar://132767643
2024-07-31 09:37:42 -07:00
Michael Gottesman
c1ddeb26c1 [gardening] Add some comments to SILIsolationInfo's header file. 2024-07-31 09:37:42 -07:00
Erik Eckstein
f9b524b1cb AliasAnalysis: a complete overhaul of alias- and memory-behavior analysis
The main changes are:

*) Rewrite everything in swift. So far, parts of memory-behavior analysis were already implemented in swift. Now everything is done in swift and lives in `AliasAnalysis.swift`. This is a big code simplification.

*) Support many more instructions in the memory-behavior analysis - especially OSSA instructions, like `begin_borrow`, `end_borrow`, `store_borrow`, `load_borrow`. The computation of end_borrow effects is now much more precise. Also, partial_apply is now handled more precisely.

*) Simplify and reduce type-based alias analysis (TBAA). The complexity of the old TBAA comes from old days where the language and SIL didn't have strict aliasing and exclusivity rules (e.g. for inout arguments). Now TBAA is only needed for code using unsafe pointers. The new TBAA handles this - and not more. Note that TBAA for classes is already done in `AccessBase.isDistinct`.

*) Handle aliasing in `begin_access [modify]` scopes. We already supported truly immutable scopes like `begin_access [read]` or `ref_element_addr [immutable]`. For `begin_access [modify]` we know that there are no other reads or writes to the access-address within the scope.

*) Don't cache memory-behavior results. It turned out that the hit-miss rate was pretty bad (~ 1:7). The overhead of the cache lookup took as long as recomputing the memory behavior.
2024-07-29 17:33:46 +02:00
Erik Eckstein
4c49e0039b Verifier: in the swift verifier call the bridged C++ verificationFailure function in case of a failure
This brings all the nice verifier features to the swift verifier, like printing the surrounding instructions in case of a failure, etc.
2024-07-29 17:33:43 +02:00
Andrew Trick
cbfe326d9b Fix StackNesting to handle move_value. 2024-07-26 08:27:31 -07:00
Nate Chandler
aa8ccafd20 [OwnedLifetimeCan] Prune fewer debug_values.
Use the more precise areUsesWithinBoundary API (which takes dead-end
blocks into account).  This requires first updating liveness with the
newly created destroys.
2024-07-22 21:51:33 -07:00
Nate Chandler
001c41741a [NFC] OwnedLifetimeCan: Record new destroys.
Add them to a small vector.  For now, do nothing with them.
2024-07-22 21:51:33 -07:00
Nate Chandler
4a397cc018 [NFC] OwnedLifetimeCan: Take DeadEndBlocksAnalysis
All clients of OwnedLifetimeCanonicalization pass an instance of the
analysis in.  For now, it's unused.
2024-07-22 21:51:28 -07:00
Nate Chandler
e125c5cf64 [NFC] SILOptimizer: Remove LexicalDestroyHoisting.
It has been superseded by OwnedValueCanonicalization's support for
lexical values.
2024-07-22 20:35:30 -07:00
Nate Chandler
afca04dd08 [OwnedLifetimeCan] Fix clearing.
Just clear all structures in a single method which is called wherever
clearing is done.  Fixes a failure to clear discoveredBlocks under
certain circumstances.
2024-07-22 20:35:29 -07:00
Nate Chandler
f31254150a [NFC] OwnedLifetimeCan: Extracted dead-end visit.
This is separate from deinit barrier visiting, and will be deleted once
complete lifetimes are finished.
2024-07-22 20:35:29 -07:00
Nate Chandler
800cd3f942 [NFC] OwnedLifetimeCan: Remove spurious array.
Inlined a single-caller method and removed the array that was created
only to be iterated over once.
2024-07-22 20:35:29 -07:00
Michael Gottesman
ebedf63138 [region-isolation] Do not squelch use-after-transfer error even if the value is isolated to the same actor.
rdar://132074953
2024-07-19 02:25:53 -07:00
Michael Gottesman
10862642ca [region-isolation] Stub out PartitionOpEvaluator::doesFunctionHaveSendingResult() so that the unittests can override it.
The unittests for PartitionUtils pass in mocked operands and instructions that
cannot be dereferenced. Adding this static CRTP helper allows for the unittest
PartitionOpEvaluator subclass to just return false for it instead of
dereferencing operands or instructions. The rest of the evaluators just get to
use the default "normal" implementation that actually accesses program state.
2024-07-18 22:35:52 -07:00
Michael Gottesman
bcbf5c515e [region-isolation] Emit an error when we assign a non-disconnected value into a sending result.
rdar://127318392
2024-07-18 21:29:08 -07:00
Michael Gottesman
ae797d43e9 [region-isolation] Propagate through the whole source operand instead of just the representative of the source value when constructing assign and merge.
This will let me know the exact source operand used instead of the source value
representative. This will ensure that the name associated with the diagnostic is
not of the representative value, but the actual value that was the source of the
assign.

This is an NFCI commit that is an algebraic refactor.
2024-07-18 21:28:22 -07:00
Michael Gottesman
ace94b00ba [region-isolation] Move RepresentativeValue from RegionAnalysis.h -> PartitionUtils.h and add APIs for mapping an ElementID -> Representative.
This is just moving up the declaration in the chain of dependencies so that I
can write logic in PartitionUtils.h using it. I also added entrypoints to lookup
the ReprensetativeValue for our various emitters.
2024-07-18 21:28:22 -07:00
Michael Gottesman
75152e7834 [region-isolation] Teach region isolation how to handle cases where due to compiler bugs, we have a function isolated to self without an isolated parameter.
Closures generally only inherit actor instance isolation if they directly
capture state from the actor instance. In this case, for some reason that is not
true, so we hit an assert that assumes that we will only see a global actor
isolated isolation.

Region Isolation should be able to handle code even if the closure isolation
invariant is violated by the frontend. So to do this, I am introducing a new
singleton actor instance to represent the isolation of a defer or closure
created in an actor instance isolated method. The reason why I am using a
singleton is that closures and defer are not methods so we do not actually know
which parameter is 'self' since it isn't in the abi. But we still need some
value to represent the captured values as belonging to. To square this circle, I
just did what we have done in a similar situation where we did not have a value:
(ActorAccessorInit). In that case, we just use a sentinel to represent the
instance (NOTE: This is represented just via a kind so ActorInstances that are
operator== equal will not &value equal since we are just using a kind).
2024-07-18 21:28:22 -07:00
Michael Gottesman
0b42f35f6a Add operator<<(llvm::raw_ostream &os, SILIsolationInfo|SILDynamicMergedIsolationInfo.
Just slicing off a nice addition. These already had appropriate print methods so
this commit just exposes the print API in the raw_ostream format.
2024-07-18 21:28:22 -07:00
Slava Pestov
d1847ffde7 Merge pull request #75068 from slavapestov/simplify-sub-map
Simplify and optimize SubstitutionMap
2024-07-10 20:45:56 -04:00
Slava Pestov
977b444eb3 AST: Add a new overload of getContextSubstitutionMap() 2024-07-10 13:28:26 -04:00
Michael Gottesman
13dccdeaa5 Merge pull request #75017 from gottesmm/pr-a26b718d5903a343e7c02a0a64befda7e3781f6e
[region-isolation] Improve pattern matching for isolated parameters in SILIsolationInfo by reusing infrastructure from other parts of RegionAnalysis
2024-07-07 01:54:53 -07:00
Michael Gottesman
62c6de7713 [region-isolation] Reuse ActorInstance::lookThroughInsts when computing the actor instance for SILIsolationInfo purposes.
We are already using this routine in other parts of TransferNonSendable to
ensure that we look through common insts that SILGen inserts that do not change
the actual underlying actor instance that we are using. In this case, I added
support for casts, optional formation, optional extraction, existential ref
initialization.

As an example of where this came up is the following test case where we fail to
look through an init_existential_ref.

```swift
public actor MyActor {
  private var intDict: [Int: Int] = [:]

  public func test() async {
    await withTaskGroup(of: Void.self) { taskGroup in
      for (_, _) in intDict {}
      await taskGroup.waitForAll() // Isolation merge failure happens here
    }
  }
}
```

I also added the ability to at the SIL level actual test out this merge
condition using the analysis test runner. I used this to validate that this
functionality works as expected in a precise way.

rdar://130113744
2024-07-06 23:02:11 -07:00
Michael Gottesman
6129f4e833 [region-isolation] Print out SILIsolationInfo's options on all printing routines for SILIsolationInfo.
Before we wouldn't print them in all situations and even more so a few of the
printing routines did not have it at all. This just adds a centralized
SILIsolationInfo::dumpOptions() method and then goes through all of the printing
helpers and changes them to use them as appropriate.
2024-07-06 23:02:11 -07:00
Michael Gottesman
0c254807bf [region-isolation] Allow for unapplied isolated parameter ownership.
Given a function or a partial_apply with an isolated parameter, we do not know
immediately what the actual isolation is of the function or partial_apply since
we do not know which instance will be applied to the function or partial_apply.

In this commit, I introduce a new bit into SILIsolationInfo that tracks this
information upon construction and allows for it to merge with ownership that has
the appropriate type and a specific instance. Since the values that created the
two isolations, will be in the same region this should ensure that the value is
only ever in a flow sensitive manner in a region with only one actor instance
(since regions with isolations with differing actor instances are illegal).
2024-07-06 23:02:11 -07:00
Slava Pestov
fae01d9776 AST: Remove ModuleDecl parameter from more places 2024-07-06 12:05:46 -04:00
Erik Eckstein
3e750f9f1c SimplifyCFG: Fix a missing borrowed-from when doing jump threading
Fixes a compiler crash

rdar://129805179
2024-07-03 13:52:52 +02:00
Michael Gottesman
c20abe570d Merge pull request #74919 from gottesmm/pr-d8b24a45ff257893c8172491f11a617fc00d5589
[region-isolation] Implement support for 'inout sending' diagnostics.
2024-07-02 20:16:25 -07:00