Commit Graph

514 Commits

Author SHA1 Message Date
Slava Pestov
c133e13efd Merge pull request #34916 from slavapestov/with-unsafe-continuation
Concurrency: Implement withUnsafe[Throwing]Continuation
2020-12-03 11:18:49 -05:00
Michael Gottesman
09ae2ef071 [ownership] Centralize all info about SILInstruction forwarding in the SILInstruction class hierarchy itself.
This commit is doing a few things:

1. It is centralizing all decisions about whether an operand's owner instruction
or a value's parent instruction is forwarding in each SILInstruction
itself. This will prevent this information from getting out of sync.

2. This allowed me to hide the low level queries in OwnershipUtils.h that
determined if a SILNodeKind was "forwarding". I tried to minimize the amount of
churn in this PR and thus didn't remove the
is{Owned,Ownership,Guaranteed}Forwarding{Use,Value} checks. Instead I left them
alone but added in asserts to make sure that if the old impl ever returns true,
the neew impl does as well. In a subsequent commit, I am going to remove the old
impl in favor of isa queries.

3. I also in the process discovered that there were some instructions that were
being inconsistently marked as forwarding. All of the asserts in the PR caught
these and I fixed these inconsistencies.
2020-12-01 17:36:19 -08:00
Slava Pestov
a2dbdecdab SIL: Refactor get_async_continuation[_addr] to return a RawUnsafeContinuation 2020-12-01 20:04:09 -05:00
Erik Eckstein
80d6e6c478 SILVerifier: don't dump the whole module in case of a verifier failure.
... because modules can be _very_ large.
Only dump the module if the new option -verify-dump-module-on-failure is set.
2020-11-19 16:10:35 +01:00
Erik Eckstein
5ccf3a852c SILVerifier: don't enforce that there must be an unreachable after a no-return apply.
This condition does not hold after each pass. It's only the case after running some cleanup-passes.
This verifier condition makes it impossible to bisect the optimization passes.
2020-11-19 16:08:22 +01:00
Michael Gottesman
c35ff33a1f [ownership] Add a subclass for all OwnershipForwarding instructions and fix the classof to the various ownership abstract classes so isa/dyn_cast work.
I think what was happening here was that we were using one of the superclass
classofs and were getting lucky since in the place I was using this I was
guaranteed to have single value instructions and that is what I wrote as my
first case X ).

I also added more robust checks tieing the older isGuaranteed...* APIs to the
ForwardingOperand API. I also eliminated the notion of Branch being an owned
forwarding instruction. We only used this in one place in the compiler (when
finding owned value introducers), yet we treat a phi as an introducer, so we
would never hit a branch in our search since we would stop at the phi argument.
The bigger picture here is that this means that all "forwarding instructions"
either forward ownership for everything or for everything but owned/unowned.

And for those listening in, I did find one instruction that was from an
ownership forwarding subclass but was not marked as forwarding:
DifferentiableFunctionInst. With this change, we can no longer by mistake have
such errors enter the code base.
2020-11-18 12:34:18 -08:00
Andrew Trick
c4abccb405 Merge pull request #34742 from atrick/fix-unchecked-ownership
Specify the unchecked_ownership_conversion instruction
2020-11-16 21:13:11 -08:00
Meghana Gupta
744767b57b Fix SILVerifier assert for witness_method with dynamic self type (#34738) 2020-11-16 10:00:06 -08:00
Andrew Trick
257b7e60b8 Specify the unchecked_ownership_conversion instruction.
All SIL instructions need their semantics specified in SIL.rst and their
constraints specified in SILVerifier.
2020-11-13 16:33:30 -08:00
Michael Gottesman
58d4191470 [ownership] Try harder to make sure we do not propagate ownership info when ownership is disabled.
Specifically, I made it so that assuming our instruction is inserted into a
block already that we:

1. Return a constraint of {OwnershipKind::Any, UseLifetimeConstraint::NonLifetimeEnding}.
2. Return OwnershipKind::None for all values.

Noticed above I said that if the instruction is already inserted into a block
then we do this. The reason why is that if this is called before an instruction
is inserted into a block, we can't get access to the SILFunction that has the
information on whether or not we are in OSSA form. The only time this can happen
is if one is using these APIs from within SILBuilder since SILBuilder is the
only place where we allow this to happen. In SILBuilder, we already know whether
or not our function is in ossa or not and already does different things as
appropriate (namely in non-ossa does not call getOwnershipKind()). So we know
that if these APIs are called in such a situation, we will only be calling it if
we are in OSSA already. Given that, we just assume we are in OSSA if we do not
have a function.

To make sure that no mistakes are made as a result of that assumption, I put in
a verifier check that all values when ownership is disabled return a
OwnershipKind::None from getOwnershipKind().

The main upside to this is this means that we can write code for both
OSSA/non-OSSA and write code for non-None ownership without needing to check if
ownership is enabled.
2020-11-11 18:56:59 -08:00
Michael Gottesman
c026e95cce [ownership] Extract out SILOwnershipKind from ValueOwnershipKind into its own type and rename Invalid -> Any.
This makes it easier to understand conceptually why a ValueOwnershipKind with
Any ownership is invalid and also allowed me to explicitly document the lattice
that relates ownership constraints/value ownership kinds.
2020-11-10 14:29:11 -08:00
Michael Gottesman
93d1524cc0 Merge pull request #34634 from gottesmm/pr-88f0c52a3c1db5fb272598e5c5596ce3594d804c
[ownership] Make checked_cast_br, destructure_struct, and destructure_tuple real forwarding instructions
2020-11-09 15:28:45 -08:00
Andrew Trick
c2b13cdd51 Merge pull request #34635 from atrick/verify-critedge
Verify non-critical edges in OSSA
2020-11-09 08:59:08 -08:00
Michael Gottesman
d1b555f59a [ownership] Make destructure_{struct,tuple} true forwarding instructions instead of inferring from results/arguments. 2020-11-08 23:55:10 -08:00
Michael Gottesman
d74dbebf3b [ownership] Make checked_cast_br a true Ownership Forwarding inst instead of always inferring from the SILPhiArguments.
This is an analogous change to the previous change I just made to SwitchEnumInst.
2020-11-08 23:55:10 -08:00
Andrew Trick
0287a3d820 Verify no SIL critical edges.
There are multiple reasons this is needed.

1. Most passes do not perform CFG transformations. However, we often
need to split critical edges and remember to invalidate all SIL
analyses at the end of virtually every pass. This is very innefficient
and highly bug prone.

2. Many SIL analysis algorithms needs to reason about CFG
edges. Avoiding critical edges leads to far simpler and more efficient
designs when edges can be identified by blocks.

3. Handling block arguments on conditional branches create complexity
at the lowest level of the SIL interface. This complexity is difficult
to abstract over and bleeds until any algorithm that needs to reason
about phi operands. It's far easier to work with phis if we can easily
recover the phi operand with only a reference to the predecessor
block.

4. Attempting to preserve critical edges in high and mid level IR
blocks optimizations that otherwise have no business optimizing
branches. Branch optimization should always be defered to machine
level IR where the most relevant heuristics are employed to remove
unconditional branches. If code didn't need to be placed on a critical
edges, then a branch optimization can easily remove that code from the
critical edge.
2020-11-08 21:34:24 -08:00
Michael Gottesman
264955ccb3 [ownership] Convert switch_enum to be an ownership forwarding inst and store the forwarding ownership kind within it.
Previously, we always inferred the ownership of the switch_enum from its phi
operands. This forced us to need to model a failure to find a good
OperandOwnershipKindMap in OperandOwnership.cpp. We want to eliminate such
conditions so that we can use failing to find a constraint to mean that a value
can accept any value rather than showing a failure.
2020-11-08 20:32:20 -08:00
Doug Gregor
9566d2e665 [Concurrency] Add a builtin to get the current task in an async function.
This introduces a new builtin, `getCurrentAsyncTask()`, that produces a
reference to the current task. This builtin can only be used within
`async` functions, and IR generation merely grabs the task argument
and packages it up.

The type of this function is `() -> Builtin.NativeObject`, because we
don't currently have a Swift-level representation of tasks, and can
probably handle everything through builtins or runtime calls.
2020-11-05 10:43:33 -08:00
Erik Eckstein
0accc022d5 [concurrency] SILVerifier: don't complain about async function pointers created in non-async functions
It's possible to materialize an async function pointer, e.g. with partial_apply, in a non-async function - as long as no async function is called.
2020-11-05 13:58:40 +01:00
Meghana Gupta
288ef583e7 SILVerifier: async functions can be called from async functions only 2020-10-30 17:35:18 -07:00
Andrew Trick
fce43daab0 Merge pull request #34502 from atrick/simplifycfg-critedge
Rewrite SimplifyCFG trampoline removal to generalize it (avoid critical edges as a side-effect)
2020-10-30 12:06:25 -07:00
Andrew Trick
7d88d720b9 Add information to SILVerifier stack nesting diagnostic. 2020-10-29 15:25:20 -07:00
Andrew Trick
acc3398fed Add -allow-critical-edges flag.
Provide a mechanism to gradually migrate unit tests away from allowing
critical edges via -allow-critical-edges=false.

This will be the default in OSSA very soon, and will hopefully become
the default eventually for all SIL stages.

Note that not all required optimization pass changes have been
committed yet. I have pending changes in:
- SimplifyCFG
- SILCloner subclasses
- EagerSpecializer
- ArraySpecialization
- LoopUtils
- LoopRotate

There are multiple reasons we need to disallow critical edges:

1. Most passes do not perform CFG transformations. However, we often
need to split critical edges and remember to invalidate all SIL
analyses at the end of virtually every pass. This is very innefficient
and highly bug prone.

2. Many SIL analysis algorithms needs to reason about CFG
edges. Avoiding critical edges leads to far simpler and more efficient
designs when edges can be identified by blocks.

3. Handling block arguments on conditional branches create complexity
at the lowest level of the SIL interface. This complexity is difficult
to abstract over and bleeds until any algorithm that needs to reason
about phi operands. It's far easier to work with phis if we can easily
recover the phi operand with only a reference to the predecessor
block.

4. Attempting to preserve critical edges in high and mid level IR
blocks optimizations that otherwise have no business optimizing
branches. Branch optimization should always be defered to machine
level IR where the most relevant heuristics are employed to remove
unconditional branches. If code didn't need to be placed on a critical
edges, then a branch optimization can easily remove that code from the
critical edge.
2020-10-29 11:51:29 -07:00
Slava Pestov
360e406d3a SIL: Rename SILFunction::hasSelfMetadataParam()/getSelfMetadataArgument()
These are only for class types and are related to the usage of the
DynamicSelfType, so rename them to {has,get}DynamicSelfMetadata().
2020-10-23 21:35:11 -04:00
Andrew Trick
8e3fb44f2d Rewrite LoadBorrowImmutabilityChecker using AccessPath.
The verification will now be as complete as it can be within the
capability of our SIL utilities. It is much more aggressive with
respect to boxes, references, and pointers. It's more efficient in
that it only considers "overlapping" uses.

It is also now wholly consistent with the utilities that it uses, so
can be reenabled.

We could probably go even further and remove the switch statement
entirely, relying on AccessPath to recognize any operations that
propagate addresses, boxes, or pointers. But I didn't want to
potentially weaken enforcement without more careful consideration.
2020-10-21 15:02:08 -07:00
Andrew Trick
4f05d8a857 LoadBorrowImmutabilityChecker renaming.
Limit names to a straightforward and unambiguous statement of
purpose. They should not pose additional questions which can only be
answered by reading the code. Nuanced meaning belongs in descriptions
and code comments.

These are all examples that legitimately made reading the code very
difficult for me:

- LoadBorrowInvalidationChecker: what does "invalidation" mean in this
  context? How does that extend the meaning of "checker"? How can
  something ever pass a checker and not be invalid?

- constructValuesForKey outside of an ADT does not state purpose at all.

- wellBehavedWriteAccumulator: Raises questions about what writes are
  included and the broader semantics of the parent function. It turns
  out that well-behavedness is handled by the function's return value
  and has nothing to do with the accumulator.
2020-10-21 13:09:40 -07:00
Andrew Trick
b0bda13543 LoadBorrowInvalidation: fix mysteriously inverted boolean returns. 2020-10-21 13:09:40 -07:00
Andrew Trick
f31296d63b Fix isRCIdentityPreservingCast to handle trivial-to-reference casts
And add assertions.
2020-10-20 16:57:24 -07:00
Joe Groff
3364c51b1d SIL: Verify invariants of async_continuation instructions.
- Enforce types of continuations and resume/error BBargs for await
- Can't access the continuation again or exit the function mid-suspend
2020-10-09 14:57:38 -07:00
Andrew Trick
5ae231eaab Rename getFieldNo() to getFieldIndex().
Do I really need to justify this?
2020-09-24 22:44:13 -07:00
Erik Eckstein
56c857afa9 SIL: Check for leaked instructions in the SILVerifier and in the SILModule destructor. 2020-09-11 11:09:30 +02:00
Erik Eckstein
61f2e7b793 SILVerifier: remove the unused -verify-skip-unreachable-must-be-last option
It had no effect, because such SIL is never generated anyway.
2020-09-11 11:09:29 +02:00
Nate Chandler
94b5f76654 Revert "[SIL] Add SILFunctionType flag for async."
This reverts commit 9b8828848d.
2020-08-25 13:37:26 -07:00
Nate Chandler
9b8828848d [SIL] Add SILFunctionType flag for async. 2020-08-19 11:29:58 -07:00
Dan Zheng
bf2ef3934d [AutoDiff] NFC: make LinearFunctionExtractInst inherit UnaryInstructionBase. (#33418)
Remove ad-hoc operand list and operand getters.
2020-08-11 22:20:58 -07:00
Varun Gandhi
29188e3fe7 [AST] Update equality for ExtInfo to take Clang types into account.
In the future, we will remove the UseClangFunctionTypes language option, but we
temporarily need the scaffolding for equality checks to be consistent in all
places.
2020-07-31 13:55:55 -07:00
Varun Gandhi
f219e58ada [NFC] Refactor ExtInfo to use a builder-pattern based API.
Since the two ExtInfos share a common ClangTypeInfo, and C++ doesn't let us
forward declare nested classes, we need to hoist out AnyFunctionType::ExtInfo
and SILFunctionType::ExtInfo to the top-level.

We also add some convenience APIs on (AST|SIL)ExtInfo for frequently used
withXYZ methods. Note that all non-default construction still goes through the
builder's build() method.

We do not add any checks for invariants here; those will be added later.
2020-07-31 13:55:55 -07:00
Joe Groff
90f0f7c627 Merge pull request #32359 from jckarter/enable-prune-vtables
Add PruneVTables to the performance optimizer passes.
2020-07-27 11:10:53 -07:00
Meghana Gupta
b34791a0a0 Update code as per Apple Style Guide
whitelist -> allowlist
blacklist -> denylist
2020-07-24 11:37:15 -07:00
Joe Groff
cc358ba8fb PruneVTables: Keep SILModule's vtable lookup table in sync with updates.
And add a verifier check to ensure the cache remains synced.
2020-07-23 20:40:49 -07:00
Andrew Trick
9fda3f565c Verify OSSA address phis.
Verify that address phis are prohibited in all OSSA passes.

Eventually they should be prohibited in all passes. This at least
allows preserving access markers in OSSA passes.
2020-07-19 17:47:04 -07:00
Andrew Trick
5826e75b00 Generalize the MemAccessUtils API.
For use outside access enforcement passes.

Add isUniquelyIdentifiedAfterEnforcement.

Rename functions for clarity and generality.

Rename isUniquelyIdentifiedOrClass to isFormalAccessBase.

Rename findAccessedStorage to identifyFormalAccess.

Rename findAccessedStorageNonNested to findAccessedStorage.

Part of generalizing the utility for use outside the access
enforcement passes.
2020-07-17 10:13:20 -07:00
Michael Gottesman
5e36ae1c7c [sil] Add a forwarding cast called unchecked_value_cast.
Today unchecked_bitwise_cast returns a value with ObjCUnowned ownership. This is
important to do since the instruction can truncate memory meaning we want to
treat it as a new object that must be copied before use.

This means that in OSSA we do not have a purely ossa forwarding unchecked
layout-compatible assuming cast. This role is filled by unchecked_value_cast.
2020-07-09 21:14:32 -07:00
Hamish Knight
0c9c606d28 Remove MergePartialModules from SILOptions
Its use in deserialization can be replaced with a
more general check for whether we're deserializing
into the same module. Its use in the SILVerifier
is subsumed by the check for whether the SILModule
is canonical, which it isn't during merge-modules.
2020-07-01 23:14:50 -07:00
Joe Groff
04c8f0df42 IRGen: Don't reify internal vtable entries that are marked overridden.
Private and internal classes shouldn't have ABI constraints on their concrete vtable layout, so if methods
don't have overrides in practice, we can elide their vtable entries.
2020-06-12 11:59:24 -07:00
David Zarzycki
e077b6ffd9 [SIL] NFC: Make SILVTable follow C++ and LLVM best practices
1) Convert the `Entry` type to a class with getters/setters
2) Use llvm::TrailingObjects
3) Use llvm::PointerIntPair
2020-06-11 07:51:42 -04:00
David Zarzycki
017ee7bf04 [SIL] NFC: Simplify SILVTable and save 8 bytes per SILVTable
We were not using the primary benefits of an intrusive list, namely the
ability to insert or remove from the middle of the list, so let's switch
to a plain vector. This also avoids linked-list pointer chasing.
2020-06-10 07:54:23 -04:00
Dan Zheng
d3b6b89de6 [AutoDiff] Support multiple differentiability result indices in SIL. (#32206)
`DifferentiableFunctionInst` now stores result indices.
`SILAutoDiffIndices` now stores result indices instead of a source index.

`@differentiable` SIL function types may now have multiple differentiability
result indices and `@noDerivative` resutls.

`@differentiable` AST function types do not have `@noDerivative` results (yet),
so this functionality is not exposed to users.

Resolves TF-689 and TF-1256.

Infrastructural support for TF-983: supporting differentiation of `apply`
instructions with multiple active semantic results.
2020-06-05 16:25:17 -07:00
Michael Gottesman
8ea7009437 Merge pull request #32177 from gottesmm/pr-f5820e0408ca527e9c54f4b3c46468e4706e7c80
[memory-lifetime] Teach the verifier that select_enum_addr doesn't write to memory.
2020-06-04 12:34:50 -07:00
Michael Gottesman
ebf291c484 [memory-lifetime] Teach the verifier that select_enum_addr doesn't write to memory.
This is an older verifier that checks that uses of addresses from things like
in_guaranteed parameters are never written to. We just never hit this before.

<rdar://problem/63188699>
2020-06-03 19:33:55 -07:00