Commit Graph

97 Commits

Author SHA1 Message Date
Erik Eckstein
44cd8d71d5 SIL: remove some const from decl arguments in SILBasicBlock and SILArgument APIs
It's not needed and would just introduce some const_casts.
2024-10-02 07:10:28 +02:00
Michael Gottesman
3e27bfc03b [region-isolation] Treat sending indirect_results as disconnected even if it is a return value of an actor isolated function.
rdar://134623227
2024-08-24 14:02:41 -04:00
Meghana Gupta
470fa2f365 Remove resultDependsOn/resultDependsOnSelf 2024-06-05 11:36:16 -07:00
Michael Gottesman
e3e78ad6bb [sending] Change the internals of sending to be based around 'sending' instead of 'transferring'.
We still only parse transferring... but this sets us up for adding the new
'sending' syntax by first validating that this internal change does not mess up
the current transferring impl since we want both to keep working for now.

rdar://128216574
2024-05-16 12:20:45 -07:00
Ben Barham
ef8825bfe6 Migrate llvm::Optional to std::optional
LLVM has removed llvm::Optional, move over to std::optional. Also
clang-format to fix up all the renamed #includes.
2024-02-21 11:20:06 -08:00
Michael Gottesman
26a75fe5e6 [region-isolation] Implement checking for transferring parameters.
NOTE: This does not handle yet assignment into transferring parameters. In the
next commit, I am going to teach the checker that assigning into such a
parameter is a transfer.
2024-01-18 13:20:28 -08:00
Meghana Gupta
1a1a8ec679 Make _resultDependsOnSelf available on SILFunction 2023-12-29 02:00:21 -08:00
Meghana Gupta
d3e921dc47 Make _resultDependsOn available on SILFunctionArgument 2023-12-29 01:57:19 -08:00
Slava Pestov
eac491ccd2 SIL: Fix memory lifetime verifier check for the thrown error result 2023-10-27 17:37:43 -04:00
John McCall
65e2e8c2fe Fix some SILArgument infrastructure for pack results.
Getting this right convinces the memory verifier to not complain
about untouched empty pack result arguments, which should be
innocuous.
2023-06-30 02:08:57 -04:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
                     bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".

I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
2023-06-27 09:03:52 -07:00
Meghana Gupta
73c962f190 Add pointer_escape flag to move_value/begin_borrow/alloc_box 2023-05-30 12:45:26 -07:00
Meghana Gupta
2c6139dce4 Rename SILArgument::isEscaping -> SILArgument::hasPointerEscape 2023-05-26 15:58:30 -07:00
Meghana Gupta
1dc713e2f7 Add new flags "reborrow" and "escaping" to SILArgument.
"reborrow" flag on the SILArgument avoids transitive walk over the phi operandsi
to determine if it is a reborrow in multiple utilities.
SIL transforms must keep the flag up-to-date by calling SILArgument::setReborrow.
SILVerifier checks to ensure the flag is not invalidated.

Currently "escaping" is not used anywhere.
2023-05-11 12:31:37 -07:00
John McCall
7505a8a487 Merge pull request #64517 from rjmccall/arity-reabstraction-closures
Implement arity reabstraction for closures
2023-03-22 14:14:23 -04:00
John McCall
3fe46464c7 Allow a SILFunctionArgument to be a parameter pack.
We might want to record the *sequence* of parameter decls associated
with a parameter pack, but currently we're not doing that.
2023-03-21 17:36:05 -04:00
Erik Eckstein
47ac2d2818 Swift Bridging: use C++ instead of C bridging for BridgedArgument 2023-03-21 15:33:09 +01:00
Anton Korobeynikov
869fc1792e [AutoDiff] Ensure autodiff code does not ignore getSingleTerminatorOperands return value (#64200)
Also extend activity analysis to handle `try_apply` normal result properly. Add testcase from #63728
2023-03-08 10:10:22 -08:00
Nate Chandler
7ea4523ee6 [SIL] Phi with incoming lexical value is lexical.
Added SILPhiArgument::isLexical.  It's true for phis which have an
incoming value that's lexical.  Dispatch to this member from
ValueBase::isLexical.
2023-02-23 16:26:44 -08:00
Nate Chandler
5d4b9154bc [SIL] Marked visitTransitiveIncomingPhis const. 2023-02-23 16:03:41 -08:00
Andrew Trick
0a9484597f Add findEnclosingDefs and findBorrowIntroducers utilities.
These APIs are essential for complete OSSA liveness analysis.  The
existing ad-hoc OSSA logic always misses some of the cases handled by
these new utilities. We need to start replacing that ad-hoc logic with
new utilities built on top of these APIs to define away potential
latent bugs.

Add FIXMEs to the inverse API: visitAdjacentBorrowsOfPhi. It should
probably be redesigned in terms of these new APIs.
2023-01-03 09:33:39 -08:00
Michael Gottesman
9e44011e4d [sil] Add a new attribute called @closureCaptured to SILFunctionArguments that are closure capture arguments.
I am adding this to make it easy to determine if a SILFunction that is not inout
aliasable is captured. This is useful when emitting certain types of
diagnostics like I need to emit with move only.
2022-12-14 15:16:43 -08:00
Andrew Trick
f9861ec9c0 Add APIs for terminator results that forward ownership.
Add TermInst::forwardedOperand.

Add SILArgument::forwardedTerminatorResultOperand. This API will be
moved into a proper TerminatorResult abstraction.

Remove getSingleTerminatorOperand, which could be misused because it's
not necessarilly forwarding ownership.

Remove the isTransformationTerminator API, which is not useful or well
defined.

Rewrite several instances of complex logic to handle block arguments
with the simple terminator result API. This defines away potential
bugs where we don't detect casts that perform implicit conversion.

Replace uses of the SILPhiArgument type and code that explicitly
handle block arguments. Control flow is irrelevant in these
situations. SILPhiArgument needs to be deleted ASAP. Instead, use
simple APIs like SILArgument::isTerminatorResult(). Eventually this
will be replaced by a TerminatorResult type.
2022-12-12 12:37:35 -08:00
Erik Eckstein
0eacaabfef SIL: add SILArgument::isErased()
Similar to SILInstruction, it's now possible to check if an argument was erased from a SILBasicBlock.
2022-11-11 07:58:51 +01:00
Nate Chandler
8074ce087d [SIL] Function args may have lifetime annotations.
By default, whether a function argument's lifetime is determined by its
type.  To allow that behavior to be overridden on an
argument-by-argument basis, the argument may have its own lifetime.
2022-08-21 21:44:31 -07:00
Nate Chandler
8450e37ddb [SIL] Removed SILArgument::isNoImplicitCopy.
The attribute can't be applied to non-function arguments and may cause
confusion by being available on them.
2022-08-21 21:44:30 -07:00
nate-chandler
83d97819ad Merge pull request #60121 from nate-chandler/rdar94346482
[SILOpt] Handle reborrows of owned phis in CanonicalizeOSSALifetime.
2022-07-22 11:08:02 -07:00
Nate Chandler
8c44d36bc8 [SIL] Add utility to transitively visit operands.
The new utility looks through operands whose values are themselves
SILPhiArguments and visits those arguments' operands.
2022-07-18 16:22:13 -07:00
Erik Eckstein
64ba6fdf5d SIL: simplify the SILNode inline bitfields.
The use of the SWIFT_INLINE_BITFIELD macros in SILNode were a constant source of confusion and bugs.
With this refactoring I tried to simplify the definition of "shared fields" in SILNode, SILValue and SILInstruction classes:

* Move `kind`, `locationKindAndFlags` and the 32-bit fields out of the 64-bitfield into their own member variables. This avoids _a lot_ of manual bit position computations.
* Now we have two separate "shared fields": an 8-bit field (e.g. for boolean flags) and a 32-bit field (e.g. for indices, which can potentially get large). Both fields can be used independently. Also, they are not "bit fields" per se. Instructions can use the field e.g. as a `bool`, `uint32_t`, or  - if multiple flags are to be stored - as a packed bit field.
* With these two separate fields, we don't have the need for defining bitfields both in a base class _and_ in a derived value/instruction class. We can get rid of the complex logic which handles such cases. Just keep a check to catch accidental overlaps of fields in base and derived classes.
* Still use preprocessor macros for the implementation, but much simpler ones than before.
* Add documentation.
2022-07-11 17:27:29 +02:00
Andrew Trick
83b01d8ebe Improve the SILPhiArgument API
This subclass of SILArgument should be eliminated--it's not always a
phi, and whether it is a "phi argument" has nothing whatsoever to do
with the opcode. That is a property of a value's uses, not a property of the
value.

Until then, provide a logical and useful API within the type. This
often avoids the need to explicitly cast to a SILPhiArgument type and
avoids a lot of boilerplate in code that deals with phis.

Note: PhiOperand and PhiValue are improved abstractions on top of this
API. But the SILArgument-level API is still an important bridge
between SILArgument and other phi abstractions.
2022-02-15 13:28:46 -08:00
Michael Gottesman
4cd1201bab [noImplicitCopy] Add support for marking a SILArgument as being a NoImplicitCopy argument.
I am purposely doing this in SILGen rather than at the type system level to
avoid having to have to add a bunch of boilerplate to the type system. Instead
of doing that, I am in SILGen checking for the isNoImplicitCopy bit on the
ParamDecl when we emit arguments. At that point, I set on the specific
SILArgument being emitted the bit that it is no implicit copy. In terms of
printing at the SIL level, I just printed it in front of the function argument
type like @owned, e.x.:

  func myFunc(_ x: @_noImplicitCopy T) -> T {
  ...
  }

becomes:

  bb0(%0 : @noImplicitCopy @owned $T):

Some notes:

* Just to be explicit, I am making it so that no implicit copy parameters by
  default are always passed at +1. The reason why I think this makes sense is
  that this is the natural way of working with a move only value.

* As always, one can not write no implicit copy the attribute without passing
  the flag -enable-experimental-move-only so this is NFC.

rdar://83957088
2021-11-01 09:34:38 -07:00
Andrew Trick
f822349ec4 Rename getTerminatorForResultArg to getTerminatorForResult. 2021-07-17 18:31:24 -07:00
Erik Eckstein
8080465e77 libswift: basic SIL and SIL bridging
This is the initial version of a buildable SIL definition in libswift.
It defines an initial set of SIL classes, like Function, BasicBlock, Instruction, Argument, and a few instruction classes.
The interface between C++ and SIL is a bridging layer, implemented in C.
It contains all the required bridging data structures used to access various SIL data structures.
2021-06-09 11:28:57 +02:00
Andrew Trick
0d594fd643 Add SILArgument::getTerminatorForResultArg(). 2021-03-18 00:14:13 -07:00
Andrew Trick
a50b09b810 Add SILArgument::isTerminatorResult() and getTransformingTerminator(). 2021-03-18 00:14:13 -07:00
Michael Gottesman
f73276259e [loop-rotate] In OSSA, instead of creating address phis, sneak the address through the phi using a RawPointer.
In OSSA, we do not allow for address phis, but in certain cases the logic of
LoopRotate really wants them. To work around this issue, I added some code in
this PR to loop rotate that as a post-pass fixes up any address phis by
inserting address <-> raw pointer adapters and changing the address phi to
instead be of raw pointer type.
2021-02-12 23:20:17 -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
Eric Miotto
8e7f9c9cbd Revert "SIL: let SingleValueInstruction only inherit from a single SILNode." 2021-01-26 10:02:24 -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
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
Michael Gottesman
0bed967ce7 [semantic-arc-opts] Create an explicit composition type for "ownership phi operands".
This is letting me refactor the implementation of every place that I work with
branches as "ownership phi operands" to instead work with
OwnershipPhiOperand. In a future commit, I am going to use this to add support
for optimizing structs and tuples that have multiple owned incoming values.

<rdar://problem/63950481>
2020-06-03 16:32:56 -07:00
Erik Eckstein
ad99b9d4f8 SILOptimizer: a new phi-argument expansion optimization.
If only a single field of a struct phi-argument is used, replace the argument by the field value.

     br bb(%str)
   bb(%phi):
     %f = struct_extract %phi, #Field // the only use of %phi
     use %f

is replaced with

     %f = struct_extract %str, #Field
     br bb(%f)
   bb(%phi):
     use %phi

This also works if the phi-argument is in a def-use cycle.

The new PhiExpansionPass is in the same file as the RedundantPhiEliminationPass. Therefore I renamed the source file to PhiArgumentOptimizations.cpp
2020-05-25 09:36:09 +02:00
Michael Gottesman
bd68964c41 [silargument] Implement getIncomingPhiOperand methods and reimplement getIncomingPhiValue methods ontop.
Operands are generally better to return than values since the operand also
enables you to get to the terminator instruction as well. Since so much code in
the compiler already uses the getIncomingPhiValue methods, I reimplemented them
on top of the operand methods.
2020-03-05 19:47:41 -08:00
Michael Gottesman
92864f1a60 [sil] Add SILArgument::getSingleTerminator() helper.
This is just like SILArgument::getSingleTerminatorOperand() except that it
returns the actual Terminator rather than the terminator's argument.
2020-02-02 13:54:18 -08:00
Saleem Abdulrasool
01d5652999 remove VS2015 workaround (NFC)
VS2015 had an issue with the deletion of an operator.  Since VS2017 is
the minimum version that LLVM uses, we can assume that VS2017+ is in use
(_MSC_VER >= 1910).  Clean up the now defunct workaround.
2019-12-23 11:55:10 -08:00
Michael Gottesman
4c6d2f04f2 [sil] Change usages of SILArguments in SILArgument.h to use exhaustive switches over ArgumentKinds.
This will ensure we get uncovered switch warnings when we add new argument
kinds, easing adding of such arguments without introducing errors.
2019-12-02 14:44:54 -08:00
Michael Gottesman
37dcacf4e8 [sil] Add 'const' to SILArgument methods that are actually 'const' 2019-11-27 09:50:23 -08:00
Michael Gottesman
5d2137b4ca [gardening] Cleanup SILArgument a little bit by reorganizing the declaration.
I fixed up variable names to be camelCase, moved constructors to be right
beneath field declarations.
2019-11-27 09:50:23 -08:00
Michael Gottesman
d93eacdb95 [gardening] Remove llvm:: from references to SmallVectorImpl in SILArgument.h 2019-11-27 09:50:23 -08:00
Michael Gottesman
f196fc09e0 [sil] Create SILArgumentKind for allowing for one to exhaustively switch over all arguments.
This ensures that we can use exhaustive switches over arguments and thus get
missing case warnings when we add new argument types.

rdar://44807744
2018-09-26 14:27:33 -07:00