Commit Graph

699 Commits

Author SHA1 Message Date
Robert Widmann
d86551de67 Lift Requirement and Parameter Accessors up to GenericSignature
Start treating the null {Can}GenericSignature as a regular signature
with no requirements and no parameters. This not only makes for a much
safer abstraction, but allows us to simplify a lot of the clients of
GenericSignature that would previously have to check for null before
using the abstraction.
2021-07-22 23:27:05 -07:00
Min-Yih Hsu
5a42c27826 Merge pull request #38378 from mshockwave/dev-sil-diexpression
[DebugInfo] Adding DIExpression into SIL
2021-07-22 13:19:24 -07:00
Becca Royal-Gordon
04775d41ea Merge pull request #38419 from beccadax/the-generic-bound-is-cheaper
[IRGen] Fix crashes involving ObjC generic params
2021-07-21 10:15:23 -07:00
Min-Yih Hsu
377bdfaf12 [SIL][DebugInfo][Patch 1/2] Initial SIL DIExpression support
Currently the debug info infrastructure inside SIL can only associate a
source variable with a single (simple) SSA value. Which is insufficient
to preserve (correct) debug info across SIL-level optimizations -- for
example, SROA that decompose or even eliminate aggregate-type obejcts.

By adding DIExpression into SIL, we are able to reconstruct the
connection between a source variable and its SSA value counterpart, even
across optimizations. This patch adds such support into in-memory
representation for SIL instructions and the SILParser/Printer. The
following patch will add changes for the IRGen part.
2021-07-21 09:26:45 -07:00
Becca Royal-Gordon
9da193ec8f [NFC] Unify helpers for checking for ObjC generics
There were two differently-named and slightly differently-implemented checks on nominal type decls. Clean this up a bit.
2021-07-19 19:59:26 -07:00
Slava Pestov
8d65042d22 SIL: Fix verifier failure when witness_method's lookup type involves dynamic Self
Fixes rdar://problem/80296242.
2021-07-19 21:25:05 -04:00
Andrew Trick
573df892e7 Fix BorrowingOperand more.
Don't allow an owned call argument to be considered a valid BorrowingOperand.

More generally, make sure there is a perfect equivalence between valid
BorrowingOperand and the corresponding OperandOwnership kind.
2021-06-30 15:20:19 -07:00
Andrew Trick
faedffaf42 Merge pull request #38148 from atrick/fix-borrow-branch
Fix BorrowingOperand for branches.
2021-06-30 12:45:40 -07:00
Andrew Trick
87ba9ccea6 Fix BorrowingOperand for branches.
An owned phi is obviously not a borrowing operand.
2021-06-28 21:48:00 -07:00
Erik Eckstein
2755d6552b MemoryLifetimeVerifier: handle stores of tuples with trivial enums
The MemoryLifetimeVerifier issued a false alarm if a tuple with a trivial enum-case (e.g. an Optional nil) is stored to a memory location.

rdar://79781939
2021-06-28 15:09:41 +02:00
Andrew Trick
1f42e86719 Add checkOperandOwnershipInvariants for OSSA verification
A place to define invariants on OperandOwnership that passes can rely
on for convenience.

Starting with a simple invariant the OperandOwnership::Borrow is a
valid BorrowingOperand.
2021-06-14 19:45:03 -07:00
Michael Gottesman
c972b16c59 [ownership] Teach the load_borrow verifier that value_metatype of an address isn't a write.
Just a case where the verifier was too sensitive. The only places that we use
this in terms of optimization would just not optimize in this case, so no
miscompiles are possible. That being said, we should ensure that SILGen doesn't
hit a verifier error after it emits code.

rdar://78698170 [SR-14680]
2021-06-07 12:51:06 -07:00
Michael Gottesman
8085754f09 [sil][debug-info] Refactor from the SILVerifier structural verification of debug info on SILInstructions into a method on SILInstruction.
The verifier just invokes this method, so we aren't losing any verification in
the SILVerifier itself.

The reason why I am extracting this information into a helper is that often
times one hits these structural assertions in the verifier making one have to
track down where in a pass the bad location was actually inserted. To make these
easier to find, I am going to change the SILBuilder to invoke these structural
comparisons so that we can catch these problems at the call site making it
easier to fix code.
2021-05-19 19:07:15 -07:00
John McCall
ec5215bf4f Remove the implicit nil inhabitant of Builtin.Executor,
and traffic in Optional<Builtin.Executor> in various places.
2021-04-30 03:11:56 -04:00
John McCall
186c53000d Introduce basic support for custom executors.
- Introduce an UnownedSerialExecutor type into the concurrency library.
- Create a SerialExecutor protocol which allows an executor type to
  change how it executes jobs.
- Add an unownedExecutor requirement to the Actor protocol.
- Change the ABI for ExecutorRef so that it stores a SerialExecutor
  witness table pointer in the implementation field.  This effectively
  makes ExecutorRef an `unowned(unsafe) SerialExecutor`, except that
  default actors are represented without a witness table pointer (just
  a bit-pattern).
- Synthesize the unownedExecutor method for default actors (i.e. actors
  that don't provide an unownedExecutor property).
- Make synthesized unownedExecutor properties `final`, and give them
  a semantics attribute specifying that they're for default actors.
- Split `Builtin.buildSerialExecutorRef` into a few more precise
  builtins.  We're not using the main-actor one yet, though.

Pitch thread:
  https://forums.swift.org/t/support-custom-executors-in-swift-concurrency/44425
2021-04-30 03:11:56 -04:00
Erik Eckstein
eecb9fa975 SILModule: track opened archetypes per function.
In theory we could map opened archetypes per module because opened archetypes _should_ be unique across the module.
But currently in some rare cases SILGen re-uses the same opened archetype in multiple functions.
The fix is to add the SILFunction to the map's key.
That also requires that we update the map whenever instructions are moved from one function to another.

This fixes a compiler crash.

rdar://76916931
2021-04-23 14:13:26 +02:00
Azoy
9ed732f0ab Introduce isDecl and getDeclType
fix enum logic issue

fix tests

guard against null types
2021-04-20 02:22:16 -04:00
Erik Eckstein
6ec788ff09 SIL: remove the SILOpenedArchetypesTracker
Instead, put the archetype->instrution map into SIlModule.

SILOpenedArchetypesTracker tried to maintain and reconstruct the mapping locally, e.g. during a use of SILBuilder.
Having a "global" map in SILModule makes the whole logic _much_ simpler.

I'm wondering why we didn't do this in the first place.

This requires that opened archetypes must be unique in a module - which makes sense. This was the case anyway, except for keypath accessors (which I fixed in the previous commit) and in some sil test files.
2021-04-14 08:36:10 +02:00
Erik Eckstein
df2a89f3b3 SIL: introduce a PlaceholderValue and use it in the parser and deserializer.
... instead of a GlobalAddrInst.
This is cleaner and makes the handling of forward-referenced values in the deserializer a bit simpler.
2021-04-14 08:17:58 +02:00
Doug Gregor
e77a27e8ed [Concurrency] Introduce runtime detection of data races.
Through various means, it is possible for a synchronous actor-isolated
function to escape to another concurrency domain and be called from
outside the actor. The problem existed previously, but has become far
easier to trigger now that `@escaping` closures and local functions
can be actor-isolated.

Introduce runtime detection of such data races, where a synchronous
actor-isolated function ends up being called from the wrong executor.
Do this by emitting an executor check in actor-isolated synchronous
functions, where we query the executor in thread-local storage and
ensure that it is what we expect. If it isn't, the runtime complains.
The runtime's complaints can be controlled with the environment
variable `SWIFT_UNEXPECTED_EXECUTOR_LOG_LEVEL`:

  0 - disable checking
  1 - warn when a data race is detected
  2 - error and abort when a data race is detected

At an implementation level, this introduces a new concurrency runtime
entry point `_checkExpectedExecutor` that checks the given executor
(on which the function should always have been called) against the
executor on which is called (which is in thread-local storage). There
is a special carve-out here for `@MainActor` code, where we check
against the OS's notion of "main thread" as well, so that `@MainActor`
code can be called via (e.g.) the Dispatch library's
`DispatchQueue.main.async`.

The new SIL instruction `extract_executor` performs the lowering of an
actor down to its executor, which is implicit in the `hop_to_executor`
instruction. Extend the LowerHopToExecutor pass to perform said
lowering.
2021-04-12 15:19:51 -07:00
eeckstein
e4f406d330 Merge pull request #36862 from eeckstein/remove-mv-result-nodes
SIL: remove the sub-classes of MultipleValueInstructionResult
2021-04-12 08:23:08 +02:00
Erik Eckstein
09755659a1 SIL: remove the sub-classes of MultipleValueInstructionResult
They are not really needed, because they don't contain any stored properties and for isa-checks we can check the parent instruction.
2021-04-11 19:14:34 +02:00
Erik Eckstein
0456d95cb0 SIL: Use StackList in BasicBlockWorklist and BasicBlockSetVector
plus: I moved both data structures into a separate header file.
2021-04-11 14:07:26 +02:00
John McCall
4f6f8b3377 Rewrite hop_to_executor so that it takes a Builtin.Executor in IRGen
The comment in LowerHopToActor explains the design here.
We want SILGen to emit hops to actors, ignoring executors,
because it's easier to fully optimize in a world where deriving
an executor is a non-trivial operation.  But we also want something
prior to IRGen to lower the executor derivation because there are
useful static optimizations we can do, such as doing the derivation
exactly once on a dominance path and strength-reducing the derivation
(e.g. exploiting static knowledge that an actor is a default actor).

There are probably phase-ordering problems with doing this so late,
but hopefully they're restricted to situations like actors that
share an executor.  We'll want to optimize that eventually, but
in the meantime, this unblocks the executor work.
2021-03-30 20:08:41 -04:00
Erik Eckstein
7d4f7bdc4e SILVerifier: fix a wrong debug-scope verifier crash
Remove the "initialization loop" for LastSeenScope in verifyDebugScopeHoles.
It's not required because LastSeenScope is initialized the same way in the main loop.
And most importantly: this loop was missing the check for cleanup locations.

rdar://75374671
2021-03-23 11:15:47 +01:00
Doug Gregor
52096a640e SE-0302: Rename ConcurrentValue/@concurrent to Sendable/@Sendable. 2021-03-18 23:48:21 -07:00
Erik Eckstein
b9c8e57d7a MemoryLifetimeVerifier: also verify locations with trivial types.
It helps to catch more problems
2021-03-13 10:41:30 +01:00
Erik Eckstein
1baf009c06 refactoring: Split MemoryLifetime.cpp/h into three separate files
And rename MemoryDataflow -> BitDataflow.

MemoryLifetime contained MemoryLocations, MemoryDataflow and the MemoryLifetimeVerifier.
Three independent things, for which it makes sense to have them in three separated files.

NFC.
2021-03-13 10:41:30 +01:00
Andrew Trick
97ec127d25 Lower and emit debug_value [poison].
OwnershipEliminator lowers destroy_value [poison] to debug_value
[poison].

IRGen overwrites all references in shadow copies with a sentinel value
in place of debug_value [poison].

Part 2/2: rdar://75012368 (-Onone compiler support for early object
deinitialization with sentinel dead references)
2021-03-12 19:33:23 -08:00
Erik Eckstein
0307b43c2f MemoryLifetime: fix a miscompile in DestroyHoisting
DestroyHoisting moved a destroy_addr above a partial_apply with an inout argument.
rdar://75267199
2021-03-11 18:33:19 +01:00
Erik Eckstein
9f1ccdebe9 MemoryLifetime: support select_enum_addr, existential_metatype, value_metatype, is_unique and fix_lifetime 2021-03-07 09:10:22 +01:00
Erik Eckstein
45f08bd7c4 MemoryLifetime: support init_existential_addr and open_existential_addr
Also, relax the check for enums a bit. Instead of only accepting single-payload enums, just require that the payload type is the same for an enum location.
2021-03-07 09:10:22 +01:00
Erik Eckstein
b73285d20d MemoryLifetime: support unchecked_ref_cast_addr and unconditional_checked_cast_addr instructions 2021-03-07 09:10:22 +01:00
Erik Eckstein
54e0a5403e MemoryLifetime: support checked_cast_addr_br 2021-03-07 09:10:22 +01:00
Meghana Gupta
6e0e4dcb88 Merge pull request #36174 from meg-gupta/fixcastoptimizer
Fix verifier error in CastOptimizer
2021-03-05 21:52:27 -08:00
Slava Pestov
4769f215e3 Merge pull request #36224 from slavapestov/reasync-sil-codegen
SIL: Preliminary support for 'apply [noasync]' calls
2021-03-05 12:46:55 -05:00
Slava Pestov
7ccc41a7b7 SIL: Preliminary support for 'apply [noasync]' calls
Refactor SILGen's ApplyOptions into an OptionSet, add a
DoesNotAwait flag to go with DoesNotThrow, and sink it
all down into SILInstruction.h.

Then, replace the isNonThrowing() flag in ApplyInst and
BeginApplyInst with getApplyOptions(), and plumb it
through to TryApplyInst as well.

Set the flag when SILGen emits a sync call to a reasync
function.

When set, this disables the SIL verifier check against
calling async functions from sync functions.

Finally, this allows us to add end-to-end tests for
rdar://problem/71098795.
2021-03-04 22:41:46 -05:00
Andrew Trick
e0a440c036 Add a poison flag to SIL destroy_value.
When the IRGen side is implemented, this will overwrite shadow debug
variables with a poison sentinel for all references within the value.
2021-03-04 17:26:18 -08:00
Meghana Gupta
b3615f6c0f Add verification of end_lifetime instruction 2021-03-04 13:24:29 -08:00
Andrew Trick
291467c8a5 Merge branch 'main' into mandatory-copyprop 2021-03-03 05:53:51 -08:00
Andrew Trick
76139d0112 MemoryLifetimeVerifier: disable non-address-lowered indirect args.
Otherwise the verifier will fail on trivial cases like this:

sil hidden [ossa] @testAssign : $@convention(thin) <T> (@inout T, @in T) -> () {
bb0(%0 : $*T, %1 : @owned $T):
  store %1 to [assign] %0 : $*T
  %3 = tuple ()
  return %3 : $()
}

SIL memory lifetime failure in @testAssign: memory is initialized at
function return but shouldn't memory location:
  %1 = argument of bb0 : $T
2021-03-02 22:20:13 -08:00
Erik Eckstein
aa16864a2c SIL: verify store_borrow
Verify that
* the destination address is an alloc_stack
* the stack location is not modified beside a store_borrow
* the stack location has been initialized when used
2021-03-02 12:02:54 +01:00
Erik Eckstein
d6736e93e0 MemoryLifetime: support partial_apply arguments in memory lifetime verification. 2021-03-02 12:02:54 +01:00
Erik Eckstein
7336bfadff SIL: handle hop_to_executor in the LoadBorrowImmutabilityChecker
Fixes a verification failure.

rdar://74660131
2021-02-25 13:31:35 +01:00
swift-ci
b1445274fd Merge pull request #36143 from meg-gupta/fixcloneforwardingownership 2021-02-24 23:40:29 -08:00
Meghana Gupta
a6f828d244 Fix forwardingOwnershipKind of all OWnershipForwardingMixin's while
cloning

forwardingOwnershipKind can differ from the operand's ownershipKind. We
need to copy forwardingOwnershipKind while cloning these instructions.

Also print the forwarding ownership kind when it differs from its
operand's ownershipKind

This is a follow up of #36063
2021-02-24 17:53:13 -08:00
Erik Eckstein
65a6d9a22a MemoryLifetimeVerifier: support verifying enum memory locations.
This is kind of complicated, because an enum can be trivial for one case and not trivial for another case. We need to check at which parts of the function we can prove that the enum does (or could) have a trivial case. In such a branch, it's not required in SIL to destroy the enum location.

Also, document the rules and requirements for enum memory locations in SIL.rst.

rdar://73770085
2021-02-23 08:08:34 +01:00
Adrian Prantl
c4c99811e6 Fix a case where guard let bindings were not emitted in their own scope.
This is a follow-up to e9d557ae28.  The
debug_value for the guard let binding is introduced by SGF.emitStmtCondition(),
so we also need to enter the debug scope before running that function.

rdar://74538257
2021-02-19 18:11:00 -08:00
Andrew Trick
75fd1fe32e Merge pull request #35967 from atrick/verify-condbr
OSSA: Disable cond_br arguments
2021-02-15 08:55:42 -08:00
Michael Gottesman
47be53da3c [memory-lifetime] Disable memory lifetime on tuple typed alloc_stack that have at least one enum tuple sub-elt.
Just until MemoryLifetime can handle enums completely.
2021-02-12 23:20:17 -08:00