Commit Graph

27 Commits

Author SHA1 Message Date
Andrew Savonichev
5aa9d3e29b Add partial_apply support for coroutines (#71653)
The patch adds lowering of partial_apply instructions for coroutines.

This pattern seems to trigger a lot of type mismatch errors in IRGen, because
coroutine functions are not substituted in the same way as regular functions
(see the patch 07f03bd2 "Use pattern substitutions to consistently abstract
yields" for more details). 

Other than that, lowering of partial_apply for coroutines is straightforward: we
generate another coroutine that captures arguments passed to the partial_apply
instructions. It calls the original coroutine for yields (first return) and
yields the resulting values. Then it calls the original function's continuation
for return or unwind, and forwards them to the caller as well.

After IRGen, LLVM's Coroutine pass transforms the generated coroutine (along with
all other coroutines) and eliminates llvm.coro.* intrinsics. LIT tests check
LLVM IR after this transformation.

Co-authored-by: Anton Korobeynikov <anton@korobeynikov.info>
Co-authored-by: Arnold Schwaighofer <aschwaighofer@apple.com>
2024-08-08 18:36:42 -07:00
Tim Kientzle
1098054291 Merge branch 'main' into tbkka-assertions2 2024-06-18 17:52:00 -07:00
Akira Hatanaka
d92f181ace Create two versions (for caller and callee) of the functions that answer questions about parameter convention (#74124)
Create two versions of the following functions:

isConsumedParameter
isGuaranteedParameter
SILParameterInfo::isConsumed
SILParameterInfo::isGuaranteed
SILArgumentConvention::isOwnedConvention
SILArgumentConvention::isGuaranteedConvention

These changes will be needed when we add a new convention for
non-trivial C++ types as the functions will return different answers
depending on whether they are called for the caller or the callee. This
commit doesn't change any functionality.
2024-06-18 09:06:09 -07:00
Tim Kientzle
1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
2024-06-05 19:37:30 -07:00
Nate Chandler
87e4c65e28 [Gardening] SIL: "liferange" -> "liverange" 2024-05-10 15:54:07 -07:00
Ben Barham
f292ec9784 Use the new template deduction guides rather than makeArrayRef
LLVM has removed `make*ArrayRef`, migrate all references to their
constructor equivalent.
2024-02-23 20:04:51 -08:00
Erik Eckstein
6488da99fa SILOptimizer: don't copy move-only partial_apply arguments to temporaries
Instead bail when trying to deleted a dead closure or when performing the apply-of-partial_apply optimization.

TODO: In OSSA this should be solvable without the need of copies to temporaries.
2023-05-11 08:11:44 +02:00
Nate Chandler
14cd090cb9 [PartialApplyCombiner] Handled moved PAIs.
Look through `move_value` instructions when combining `partial_apply`
instructions.

rdar://108386395
2023-04-21 14:59:43 -07:00
Erik Eckstein
d86615830c SILCombine: handle begin_borrow in the partial_apply -> apply peephole optimization 2022-12-01 07:05:02 +01:00
Nate Chandler
bfd865b6b6 [ApplySite] Renamed insertAfterApplication.
Now that it can be called on partial_apply instructions,
insertAfterFullEvaluation does not name what the function does.  One
could imagine a function which inserted after the applies of
(non-escaping) partial_applies.
2022-11-03 13:52:42 -07:00
Allan Shortlidge
4f8d33ffb5 SILOptimizer: Break circular dependency with SIL library by moving extendStoreBorrow(). 2022-10-27 15:29:37 -07:00
Josh Soref
730b16c569 Spelling siloptimizer
* access
* accessed
* accesses
* accessor
* acquiring
* across
* activated
* additive
* address
* addresses'
* aggregated
* analysis
* and
* appropriately
* archetype
* argument
* associated
* availability
* barriers
* because
* been
* beginning
* belongs
* beneficial
* blocks
* borrow
* builtin
* cannot
* canonical
* canonicalize
* clazz
* cleanup
* coalesceable
* coalesced
* comparisons
* completely
* component
* computed
* concrete
* conjunction
* conservatively
* constituent
* construct
* consuming
* containing
* covered
* creates
* critical
* dataflow
* declaration
* defined
* defining
* definition
* deinitialization
* deliberately
* dependencies
* dependent
* deserialized
* destroy
* deterministic
* deterministically
* devirtualizes
* diagnostic
* diagnostics
* differentiation
* disable
* discipline
* dominate
* dominates
* don't
* element
* eliminate
* eliminating
* elimination
* embedded
* encounter
* epilogue
* epsilon
* escape
* escaping
* essential
* evaluating
* evaluation
* evaluator
* executing
* existential
* existentials
* explicit
* expression
* extended
* extension
* extract
* for
* from
* function
* generic
* guarantee
* guaranteed
* happened
* heuristic
* however
* identifiable
* immediately
* implementation
* improper
* include
* infinite
* initialize
* initialized
* initializer
* inside
* instruction
* interference
* interferes
* interleaved
* internal
* intersection
* intractable
* intrinsic
* invalidates
* irreducible
* irrelevant
* language
* lifetime
* literal
* looks
* materialize
* meaning
* mergeable
* might
* mimics
* modification
* modifies
* multiple
* mutating
* necessarily
* necessary
* needsmultiplecopies
* nonetheless
* nothing
* occurred
* occurs
* optimization
* optimizing
* original
* outside
* overflow
* overlapping
* overridden
* owned
* ownership
* parallel
* parameter
* paths
* patterns
* pipeline
* plottable
* possible
* potentially
* practically
* preamble
* precede
* preceding
* predecessor
* preferable
* preparation
* probably
* projection
* properties
* property
* protocol
* reabstraction
* reachable
* recognized
* recursive
* recursively
* redundant
* reentrancy
* referenced
* registry
* reinitialization
* reload
* represent
* requires
* response
* responsible
* retrieving
* returned
* returning
* returns
* rewriting
* rewritten
* sample
* scenarios
* scope
* should
* sideeffects
* similar
* simplify
* simplifycfg
* somewhat
* spaghetti
* specialization
* specializations
* specialized
* specially
* statistically
* substitute
* substitution
* succeeds
* successful
* successfully
* successor
* superfluous
* surprisingly
* suspension
* swift
* targeted
* that
* that our
* the
* therefore
* this
* those
* threshold
* through
* transform
* transformation
* truncated
* ultimate
* unchecked
* uninitialized
* unlikely
* unmanaged
* unoptimized key
* updataflow
* usefulness
* utilities
* villain
* whenever
* writes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-10-03 18:31:33 -04:00
Meghana Gupta
b7c23edfe6 Fix SILCombine of partial_apply to correctly extend store_borrow when needed 2022-08-16 15:08:23 -07:00
Adrian Prantl
2673256a0c Remove spurious anonymous function arguments introduced by PartialApplyCombiner.
Looks like this was a well-intentioned, but counterproductive attempt to
introduce new debug info in for partial applies. SILVerifier is now stricter
about finding clashing anonymous arguments so this becomes a SIL verifier error
rather than a late LLVM crash.
2021-09-04 12:01:36 -07: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
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
Michael Gottesman
94c643cb27 [sil-combine] Enable ownership on all of the apply visitors.
All of the non-SILCombiner specific helpers have already been updated for OSSA,
so this was not too bad.

NOTE: I also added two small combines that delete copy_value, destroy_value with
.none arguments. The reason why I added this is that this is a pretty small
addition and many of the tests of this code rely on SILCombine being able to
eliminate such operations on thin_to_thick_function.

NOTE: I also disabled TypePropagation in OSSA, we are going to redo that code
when we bring up opaque values.
2021-01-19 22:47:18 -08:00
Erik Eckstein
9a10ec7d58 SILBuilder: add an API to insert _after_ an instruction.
... and use that API in FullApplySite::insertAfterInvocation.

Also change FullApplySite::insertAfterInvocation/insertAfterFullEvaluation to directly pass a SILBuilder instead of just an insertion point to the callback.
This makes more sense (given the function names) and simplifies the usages.

It's a NFC.
2020-10-16 17:25:08 +02:00
Meghana Gupta
0a21c4d96f Fix another use-after-free in SILCombine (#34168)
* Fix another use-after-free in SILCombine

swift::endLifetimeAtFrontier also needs to use
swift::emitDestroyOperation and delete instructions via callbacks that
can correctly remove it from the worklist that SILCombine maintains

* Add test for use-after-free in SILCombine
2020-10-06 13:37:05 -07:00
Erik Eckstein
85789367a3 SILOptimizer: restructure the apply(partial_apply) peephole and the dead partial_apply elimination optimizations
Changes:

* Allow optimizing partial_apply capturing opened existential: we didn't do this originally because it was complicated to insert the required alloc/dealloc_stack instructions at the right places. Now we have the StackNesting utility, which makes this easier.

* Support indirect-in parameters. Not super important, but why not? It's also easy to do with the StackNesting utility.

* Share code between dead closure elimination and the apply(partial_apply) optimization. It's a bit of refactoring and allowed to eliminate some code which is not used anymore.

* Fix an ownership problem: We inserted copies of partial_apply arguments _after_ the partial_apply (which consumes the arguments).

* When replacing an apply(partial_apply) -> apply and the partial_apply becomes dead, avoid inserting copies of the arguments twice.

These changes don't have any immediate effect on our current benchmarks, but will allow eliminating curry thunks for existentials.
2020-02-11 12:48:39 +01:00
Michael Gottesman
e5aaa68b52 [sil] Do not eliminate (apply (partial_apply)) if the partial_apply captures an @in parameter and handle @in_guaranteed appropriately.
Otherwise the code as written miscompiles code like:

```
@inline(never)
func consumeSelf<T>(_ t : __owned T) {
  print("Consuming self!")
  print(t)
}

class Klass {}
struct S<T> {
  let t: T? = (Klass() as! T)

  @inline(__always)
  __consuming func foo(_ t: T) {
    consumeSelf(self)
  }
}

public func test<T>(_ t: __owned T) {
  let k = S<T>()
  let f = k.foo

  for _ in 0..<1024 {
    f(t)
  }
}

test(Klass())
```

As one can tell, without annotations it is hard to create an example like the
above, but there is no reason why we couldn't emit more code like this from the
frontend.

If the parameter is guaranteed though, the current impl is fine for
@in_guaranteed since in the loop, we do not need to retain or release the
value.

rdar://58885352
2020-02-04 14:20:58 -08:00
Michael Gottesman
f30b2c9b9f [pa-combiner] Change worklist iteration to use a more canonical worklist form.
We generally do not use a for loop for worklist iteration since one runs into
weird issues around always needing to recompute the worklist size since it may
change per iteration. In contrast, using the while loop approach that just pops
off the back avoids such implicit weirdness.
2019-12-13 13:31:15 -08:00
Michael Gottesman
89ff110c0d [pa-combiner] Use llvm::any_of instead of a for loop. 2019-12-13 13:31:15 -08:00
Michael Gottesman
5acb59aea4 [pa-combiner] Simplify some cleanup code by using FullApplySite::insertAfterFullInvocation. 2019-12-13 12:51:04 -08:00
Michael Gottesman
e4e48e81f1 [pa-combiner] Modernize some appending code to use a range instead of iterators. NFC. 2019-12-12 09:52:28 -08:00
Michael Gottesman
0d88ff1432 [pa-combiner] Some further updates for supporting ossa.
Specifically:

1. I converted a bunch of cases where we were emitting releases/unqualified
loads to use instead the *Operation commands that work in both modes.
2. I renamed some methods/variables that referred to releases to instead refer
to destroys.
2019-12-12 09:52:28 -08:00
Michael Gottesman
113c22a680 [sil] Move partial apply combiner code from SILCombiner into InstOptUtils.h/SILCombinerApplyVisitor.cpp.
This is in preparation for moving this into the mandatory combiner.
2019-12-11 14:48:19 -08:00