Commit Graph

2441 Commits

Author SHA1 Message Date
Michael Gottesman
421addacce [ownership] Change store_borrow to be an interior pointer and update interior pointer formalism to use it.
For those who are unaware, a store_borrow is an instruction that is needed so
that we can without adding ARC traffic materialize a guaranteed object value
into memory so we can pass it as an in_guaranteed argument. It has not had its
model completely implemented due to time. I am going to add some information
about it in this commit message for others.

From a model semantic perspective, a store_borrow is meant to allow for a
guaranteed value to be materialized into memory safely for a scoped region of
time and be able to guarantee that:

1. The guaranteed value that was stored is always live.
2. The memory is never written to within that region.

The natural way to model this type of guaranteeing behavior from an object to an
address is via a safe interior pointer formulation and thus with that in mind I
made it so that store_borrow returned an address that was an interior pointer of
the guaranteed value. Sadly, we have not changed the compiler yet to use this
effectively since we in store_borrow code paths generally just use the input
address. That being said, in this PR I begin to move us toward this world by
making store_borrow's src operand an InteriorPointerOperand. This means that we
will require the borrowed value to be alive at all use points of the
store_borrow result. That will not have a large effect today but I am going to
loop back around and extend that.

There is additional work here that I wish to accomplish in the future is that I
would like to define an end_store_borrow instruction to explicitly end the scope
in which there is a condition on the borrow. Then we would require that the
memory we are using to for sure never be written to in that region and maybe
additionally try to give some sort of guarantee around exclusivity (consider if
we made it so that we could only store_borrow into an alloc_stack with certain
conditions). Not sure about the last one yet. But philosophically since we are
using this to just handle reabstraction suggests we can do something more
constrained.
2021-02-08 10:53:56 -08:00
Richard Wei
18fe723543 Merge pull request #35811 from rxwei/69980056-differentiable-reverse
[AutoDiff] Add '@differentiable(reverse)'.
2021-02-08 04:32:27 -08:00
Richard Wei
af8942d940 [AutoDiff] Rename '@differentiable' to '@differentiable(reverse)'.
Compiler:
- Add `Forward` and `Reverse` to `DifferentiabilityKind`.
- Expand `DifferentiabilityMask` in `ExtInfo` to 3 bits so that it now holds all 4 cases of `DifferentiabilityKind`.
- Parse `@differentiable(reverse)` and `@differentiable(_forward)` declaration attributes and type attributes.
- Emit a warning for `@differentiable` without `reverse`.
- Emit an error for `@differentiable(_forward)`.
- Rename `@differentiable(linear)` to `@differentiable(_linear)`.
- Make `@differentiable(reverse)` type lowering go through today's `@differentiable` code path. We will specialize it to reverse-mode in a follow-up patch.

ABI:
- Add `Forward` and `Reverse` to `FunctionMetadataDifferentiabilityKind`.
- Extend `TargetFunctionTypeFlags` by 1 bit to store the highest bit of differentiability kind (linear). Note that there is a 2-bit gap in `DifferentiabilityMask` which is reserved for `AsyncMask` and `ConcurrentMask`; `AsyncMask` is ABI-stable so we cannot change that.

_Differentiation module:
- Replace all occurrences of `@differentiable` with `@differentiable(reverse)`.
- Delete `_transpose(of:)`.

Resolves rdar://69980056.
2021-02-07 14:09:46 -08:00
Slava Pestov
ed247a1fa1 Sema: Allow 'lazy' local variables 2021-02-06 08:56:38 -05:00
Meghana Gupta
e2563e63d2 Merge pull request #35766 from meg-gupta/csechangespr
CSE OSSA: look through ownership instructions for some additional instructions
2021-02-05 12:50:40 -08:00
Michael Gottesman
fbad9b61cd Merge pull request #35774 from gottesmm/pr-aed4f36ace8254f8ea9b635f05a8c903fd964553
[capture-promotion] Emit a warning when the pass fails to promote a capture of a concurrent function to a by value capture instead of by ref capture.
2021-02-05 11:01:23 -08:00
Michael Gottesman
fa19cc9ab4 [capture-promotion] Emit a warning when the pass fails to promote a capture of a concurrent function to a by value capture instead of by ref capture.
I also added a SILVerifier check that once we are in canonical SIL all
concurrent functions that are partial applied are banned from having Box
arguments.

I have not added support yet for this for address only types, so we do not crash
on that yet.
2021-02-05 00:26:59 -08:00
Michael Gottesman
7849e0feed [ownership] Change "AnyForwardingInst" with trivial return type to return OwnershipKind::None even if they forward non-OwnershipKind::none ownership.
Otherwise the forwarding instruction will return a trivial value with
non-OwnershipKind::None ownership. This inevitably causes an ownership violation
since any place that we use that trivial value will expect the value to have
OwnershipKind::None, showing the inconsistency that this problem yields.
2021-02-04 19:09:40 -08:00
Michael Gottesman
62d554669c [ownership] Rename OwnershipForwardingMixin::{get,set}OwnershipKind() -> {get,set}ForwardingOwnershipKind().
TLDR: This is just an NFC rename in preparation for changing
SILValue::getOwnershipKind() of any forwarding instructions to return
OwnershipKind::None if they have a trivial result despite forwarding ownership
that isn't OwnershipKind::None (consider an unchecked_enum_data of a trivial
payload from a non-trivial enum).

This ensures that one does not by mistake use this routine instead of
SILValue::getOwnershipKind(). The reason why these two things must be
distinguished is that the forwarding ownership kind of an instruction that
inherits from OwnershipForwardingMixin is explicitly not the ValueOwnershipKind
of the result of the instruction. Instead it is a separate piece of state that:

1. For certain forwarding instructions, defines the OwnershipConstraint of the
forwarding instruction.

2. Defines the ownership kind of the result of the value. If the result of the
value is non-trivial then it is exactly the set ownership kind. If the result is
trivial, we use OwnershipKind::None instead. As an example of this, consider an
unchecked_enum_data that extracts from a non-trivial enum a trivial payload:

```
enum Either {
case int(Int)
case obj(Klass)
}

%1 = load_borrow %0 : $*Either
%2 = unchecked_enum_data %1 : $Either, #Either.int!enumelt.1 // Int type
end_borrow %1 : $Either
```

If we were to identify the forwarding ownership kind (guaranteed) of
unchecked_enum_data with the value ownership kind of its result, we would
violate ownership since we would be passing a guaranteed value to the operand of
the unchecked_enum_data that will only accept values with
OwnershipKind::None. =><=.
2021-02-04 16:53:50 -08:00
Meghana Gupta
487e8ebd0d Fix InstructionComparer for ref_element_addr
InstructionComparer should only check for equality on additional state,
not operands. Fix visitRefElementAddr which was not using this common
pattern.
2021-02-04 11:58:17 -08:00
Meghana Gupta
f176ea9176 Merge pull request #35675 from meg-gupta/fixmayrelease
Handle unchecked_ownership_conversion in SILInstruction::mayRelease
2021-02-03 15:09:27 -08:00
Josh Learn
e8bbbb70a3 Merge pull request #35636 from guitard0g/oslog_opt_animation_begin
[os_log][SIL Optimizer] Modify OSLogOptimization pass to skip folding on evaluation failure of non-strings
2021-02-02 12:44:03 -08:00
Josh Learn
b4a7475d8e [os_log][SIL Optimizer] Modify OSLogOptimization pass to skip folding on evaluation failure of non-strings and mark array.finalize_intrinsic as not foldable 2021-02-01 15:18:49 -08:00
Meghana Gupta
dae076d0ba Handle unchecked_ownership_conversion in SILInstruction::mayRelease 2021-01-30 22:31:09 -08:00
Adrian Prantl
a9f05c8c30 Merge remote-tracking branch 'origin/main' into rebranch
Conflicts:
	lib/IRGen/IRGenDebugInfo.cpp
2021-01-29 16:17:10 -08:00
Doug Gregor
c97637cb96 Merge pull request #35655 from DougGregor/concurrent-function-types-sil
[SIL] Add `@concurrent` function types to SIL
2021-01-29 15:43:45 -08:00
Erik Eckstein
65208c0642 SIL: efficiently store SILLocation in SILInstruction
Store the 1-byte kindAndFlags of SILLocation in the instruction's SILNode bitfield and only store SILLocation::storage in SILInstruction directly.
This reduces the space for the location from 2 to 1 word in SILInstruction.
2021-01-29 20:28:21 +01:00
Erik Eckstein
462e58d3cb SILLocation: a big refactoring and reducing its size from 3 to 2 words
My goal was to reduce the size of SILLocation. It now contains only of a storage union, which is basically a pointer and a bitfield containing the Kind, StorageKind and flags. By far, most locations are only single pointers to an AST node. For the few cases where more data needs to be stored, this data is allocated separately: with the SILModule's bump pointer allocator.

While working on this, I couldn't resist to do a major refactoring to simplify the code:

* removed unused stuff
* The term "DebugLoc" was used for 3 completely different things:
    - for `struct SILLocation::DebugLoc` -> renamed it to `FilePosition`
    - for `hasDebugLoc()`/`getDebugSourceLoc()` -> renamed it to `hasASTNodeForDebugging()`/`getSourceLocForDebugging()`
    - for `class SILDebugLocation` -> kept it as it is (though, `SILScopedLocation` would be a better name, IMO)
* made SILLocation more "functional", i.e. replaced some setters with corresponding constructors
* replaced the hand-written bitfield `KindData` with C bitfields
* updated and improved comments
2021-01-29 20:28:21 +01:00
Erik Eckstein
fd85e0e1e0 SILLocation: remove unused flag bits.
PointsToStartBit: was never set.
IsInTopLevel: was never checked (except for SIL printing)
2021-01-29 20:28:21 +01:00
Doug Gregor
99f8d7a5e8 [SIL] Add @concurrent function types to SIL
Add @concurrent to SIL function types, mirroring what's available on
AST function types. @concurrent function types will have by-value
capture semantics.
2021-01-29 11:16:17 -08:00
swift-ci
c47946ab05 Merge remote-tracking branch 'origin/main' into rebranch 2021-01-28 19:12:47 -08:00
Michael Gottesman
ac2ef83951 [sil-combine] Enable cond_br canonicalizations in ossa.
The key thing is that all of these while they do modify the branches of the CFG
do not invalidate block level CFG analyses like dominance and dead end
blocks.
2021-01-28 12:10:15 -08:00
swift-ci
2f5c3d3e51 Merge remote-tracking branch 'origin/main' into rebranch 2021-01-27 11:12:39 -08:00
eeckstein
c8766a0082 Merge pull request #35615 from eeckstein/simplify-silnode
SIL: let SingleValueInstruction only inherit from a single SILNode (2nd try)
2021-01-27 20:08:40 +01:00
swift-ci
9aad33b08f Merge remote-tracking branch 'origin/main' into rebranch 2021-01-27 10:32:29 -08:00
Dave Lee
c36c32027e Merge pull request #35568 from apple/SIL-Gate-checkForLeaksAfterDestruction-to-asserts-builds
SIL: Gate checkForLeaksAfterDestruction to asserts builds
2021-01-27 10:30:47 -08:00
Erik Eckstein
011358edd6 SIL: let SingleValueInstruction only inherit from a single SILNode.
This removes the ambiguity when casting from a SingleValueInstruction to SILNode, which makes the code simpler. E.g. the "isRepresentativeSILNode" logic is not needed anymore.
Also, it reduces the size of the most used instruction class - SingleValueInstruction - by one pointer.

Conceptually, SILInstruction is still a SILNode. But implementation-wise SILNode is not a base class of SILInstruction anymore.
Only the two sub-classes of SILInstruction - SingleValueInstruction and NonSingleValueInstruction - inherit from SILNode. SingleValueInstruction's SILNode is embedded into a ValueBase and its relative offset in the class is the same as in NonSingleValueInstruction (see SILNodeOffsetChecker).
This makes it possible to cast from a SILInstruction to a SILNode without knowing which SILInstruction sub-class it is.
Casting to SILNode cannot be done implicitly, but only with an LLVM `cast` or with SILInstruction::asSILNode(). But this is a rare case anyway.
2021-01-27 16:40:15 +01:00
Erik Eckstein
da197240c1 SIL: simplify the SILNode getParent functions.
A small cleanup, NFC.
2021-01-27 16:40:15 +01:00
Erik Eckstein
0523158d25 SILPrinter: split printUsersOfSILNode into printUsersOfValue and printUsersOfInstruction.
A small cleanup, NFC.
2021-01-27 16:40:14 +01:00
swift-ci
e349794517 Merge remote-tracking branch 'origin/main' into rebranch 2021-01-27 04:12:41 -08:00
Erik Eckstein
2f890dcbbf SIL: some improvements to the BasicBlockBitfield utilities
* add a BasicBlockSetVector class
* add a second argument to BasicBlockFlag::set, for the set value.
* rename BasicBlockSet::remove -> BasicBlockSet::erase.
* add a MaxBitfieldID statistics value in SILFunction.cpp
2021-01-27 10:31:17 +01:00
swift-ci
ef7f76b7ba Merge remote-tracking branch 'origin/main' into rebranch 2021-01-26 20:12:44 -08:00
Dave Lee
9760533fe2 add explanatory comment 2021-01-26 12:40:27 -08:00
swift-ci
6137579b93 Merge remote-tracking branch 'origin/main' into rebranch 2021-01-26 10:12:52 -08:00
Eric Miotto
8e7f9c9cbd Revert "SIL: let SingleValueInstruction only inherit from a single SILNode." 2021-01-26 10:02:24 -08:00
Andrew Trick
9a48d0e7f9 Fix SILInstruction::mayRelease to handle unmanaged_release_value.
Apparently this API was never called from any OSSA passes.

Fixes rdar://73507733 ([SR-14090]: [Source Compat] swift-futures 5.1
fails to build from main branch)
2021-01-25 20:48:08 -08:00
swift-ci
a45f6a4518 Merge remote-tracking branch 'origin/main' into rebranch 2021-01-25 03:32:36 -08:00
Erik Eckstein
ff1991740a SIL: let SingleValueInstruction only inherit from a single SILNode.
This removes the ambiguity when casting from a SingleValueInstruction to SILNode, which makes the code simpler. E.g. the "isRepresentativeSILNode" logic is not needed anymore.
Also, it reduces the size of the most used instruction class - SingleValueInstruction - by one pointer.

Conceptually, SILInstruction is still a SILNode. But implementation-wise SILNode is not a base class of SILInstruction anymore.
Only the two sub-classes of SILInstruction - SingleValueInstruction and NonSingleValueInstruction - inherit from SILNode. SingleValueInstruction's SILNode is embedded into a ValueBase and its relative offset in the class is the same as in NonSingleValueInstruction (see SILNodeOffsetChecker).
This makes it possible to cast from a SILInstruction to a SILNode without knowing which SILInstruction sub-class it is.
Casting to SILNode cannot be done implicitly, but only with an LLVM `cast` or with SILInstruction::asSILNode(). But this is a rare case anyway.
2021-01-25 09:30:04 +01:00
Erik Eckstein
40f0980abf SIL: simplify the SILNode getParent functions.
A small cleanup, NFC.
2021-01-25 09:30:04 +01:00
Erik Eckstein
5dab47c310 SILPrinter: split printUsersOfSILNode into printUsersOfValue and printUsersOfInstruction.
A small cleanup, NFC.
2021-01-25 09:30:04 +01:00
swift-ci
d303fac16e Merge remote-tracking branch 'origin/main' into rebranch 2021-01-22 19:12:50 -08:00
Michael Gottesman
1e039cce38 Merge pull request #35563 from gottesmm/pr-cd7c9e97e46a0141e37f10fbfb74c094e0576ff3-followups
[ownership] cd7c9e97e4 followups
2021-01-22 19:05:12 -08:00
Dave Lee
4a349f9397 SIL: Gate checkForLeaksAfterDestruction to asserts builds 2021-01-22 17:25:29 -08:00
Michael Gottesman
90b23a6990 [sil] Replace a thinko in getNextInstruction().
We were using std::next on the pointer, not the iterator meaning we were
accessing bad memory.
2021-01-22 16:02:12 -08:00
swift-ci
0fdc995041 Merge remote-tracking branch 'origin/main' into rebranch 2021-01-22 04:04:55 -08:00
Erik Eckstein
47c596d645 SIL: Use TinyPtrVector for the argument list in SILBasicBlock
A TinyPtrVector is the right choice, because ~98% of blocks have 0 or 1 arguments.
2021-01-22 10:05:09 +01:00
Erik Eckstein
2c7027da97 SIL: fix a header-file layering violation: SILArgument.h should not include SILFunction.h
"Containers" should include their "content" and not the other way round.
Also, remove some unused stuff of SILArgument.
2021-01-22 10:05:09 +01:00
swift-ci
5dec637c83 Merge remote-tracking branch 'origin/main' into rebranch 2021-01-21 23:44:22 -08:00
Erik Eckstein
65976fd0c5 SIL: add a utility which can manage per-block bitfields and flags efficiently.
It is very efficient: no memory allocation is needed an initialization is at zero cost.
2021-01-21 21:31:41 +01:00
swift-ci
798a91c688 Merge remote-tracking branch 'origin/main' into rebranch 2021-01-21 12:05:30 -08:00