to SILBuilder::createUncheckedForwardingCast
It would be disastrous to confuse this utility with a bit cast. A bit
cast always produces an Unowned value which must immediately be copied
to be used. This utility always forwards ownership. It cannot be used
to truncate values.
Also, be careful not to convert "reinterpret cast"
(e.g. Builtin.reinterpretCast) into a "value cast" since ownership
will be incorrect and the reinterpreted types might not have
equivalent layout.
* [SILOptimizer] Add prespecialization for arbitray reference types
* Fix benchmark Package.swift
* Move SimpleArray to utils
* Fix multiple indirect result case
* Remove leftover code from previous attempt
* Fix test after rebase
* Move code to compute type replacements to SpecializedFunction
* Fix ownership when OSSA is enabled
* Fixes after rebase
* Changes after rebasing
* Add feature flag for layout pre-specialization
* Fix pre_specialize-macos.swift
* Add compiler flag to benchmark build
* Fix benchmark SwiftPM flags
Currently the SROA just overwrites already-existing expressions on
variables. When SROA is recursively run on a data structure this leads to
nonsensical expressions such as
type $*Outer, expr op_fragment:#Inner.x
instead of
type $*Outer, expr op_fragment:#Outer.inner op_fragment:#Inner.x
The (nonsensical) LLVM IR generated from this violates some assumptions in LLVM
for example, if a struct has multiple members of the same type, you can end up
with multiple dbg.declare intrinsics claiming to describe the same variable). As
a quick fix, this patch detects this situation and drops the debug info. A
proper fix shouldn't be too difficult to implement though.
rdar://99874371
Previously, when attempting to pattern-match bridged ObjC properties,
there was an assertion about the location of destroy_value instructions
in the code that we were trying to match. Instead, bail in the face of
an unexpected pattern.
rdar://99873905
Instead of checking if the end_borrow is ending the lifetime of the store_borrow of the asi under consideration,
this code was checking if the store_borrow source is the runningValue which is incorrect in cases where a store_borrow
src to another destination gets replaced during mem2reg. This PR fixes the issue.
This is a dedicated instruction for incrementing a
profiler counter, which lowers to the
`llvm.instrprof.increment` intrinsic. This
replaces the builtin instruction that was
previously used, and ensures that its arguments
are statically known. This ensures that SIL
optimization passes do not invalidate the
instruction, fixing some code coverage cases in
`-O`.
rdar://39146527
By using the keyword instead of the function, we actually get a much simpler
implementation since we avoid all of the machinery of SILGenApply. Given that we
are going down that path, I am removing the old builtin implementation since it
is dead code.
The reason why I am removing this now is that in a subsequent commit, I want to
move all of the ownership checking passes to run /before/ mandatory inlining. I
originally placed the passes after mandatory inlining since the function version
of the move keyword was transparent and needing to be inlined before we could
process it. Since we use the keyword now, that is no longer an issue.
These will never appear in the source language, but can arise
after substitution when the original type is a tuple type with
a pack expansion type.
Two examples:
- original type: (Int, T...), substitution T := {}
- original type: (T...), substitution T := {Int}
We need to model these correctly to maintain invariants.
Callers that previously used to rely on TupleType::get()
returning a ParenType now explicitly check for the one-element
case instead.
Arguments whose lifetimes are not lexical should be hoisted without
respect to deinit barriers. On the other hand, inout arguments
explicitly annotated @_lexical should respect deinit barriers.
Previously, whenever an alloc_stack [lexical] was seen, optimization
bailed conservatively.
In the fullness of time, we should optimize an alloc_stack [lexical] so
long as:
(1) the root of the source of the store/copy_addr is lexical
(2) the range in which the alloc_stack [lexical] contains the value
store'd/copy_addr'd into it (i.e. the range ending at
destroy_addr/etc) is contained within the live range of that lexical
root
Here, an incremental step in that direction is taken: if the base of the
accessed storage of the source of a copy_addr is a guaranteed function
argument, then we know
(1) the base is lexical--guaranteed function arguments are always
lexical
(2) the range in which the alloc_stack contains the value copy_addr'd in
is trivially contained within the range of that lexical root--the
live range of a guaranteed function argument is the whole function
Added TODOs for the full optimization.
Previously, whenever an alloc_box that was promoted to an alloc_stack,
the new alloc_stack would be lexical. The result was that alloc_boxes
which didn't need (or explicitly didn't want, in the case of eager move
vars) received lexical alloc_stacks.
Here, only add the lexical flag to the new alloc_stack instruction if
any of the box's uses are `begin_borrow [lexical]`. That way,
alloc_boxes end up having lexical alloc_stacks only if they were
"lexical alloc_boxes".
With the change to include `SmallVector.h` directly in `LLVM.h` rather
than forward declaring in the only case it matters (ie. Clang <= 5),
these fixes are no longer needed. Since defaulted version is preferred
when there's no better choice (which is presumably the case if that's
how they were originally added), use it instead. Some uses were instead
changed to add `llvm::` so remove that too.
Andy some time ago already created the new API but didn't go through and update
the old occurences. I did that in this PR and then deprecated the old API. The
tree is clean, so I could just remove it, but I decided to be nicer to
downstream people by deprecating it first.
Previously, for the BridgedProperty pattern, there were two flavors of
outlined function that would be formed, varying on the ownership of the
instance whose field is being access:
(1) guaranteed_in -- for use by addresses
(2) unowned -- for use by values which were not destroyed until some
time after the pattern of interest is matched
Now that the lifetime of the instance may be shortened to just after the
call to the objc method, the latter of these is not appropriate for
values. We would have to re-extend the lifetime until after the method
returns.
Instead, here, we add a new variant
(3) owned -- for use by values which were destroyed just after the objc
method call
Doing so requires new mangling.
Thanks to CopyPropagation canonicalizing all values, not just those for
which there is a copy_value instruction, the lifetime of the value that
is loaded in the BridgedProperty pattern is shortened and the
destroy_value appears right after its use rather than after the full CFG
for the bridged property. Updated the BridgedProperty pattern to match
that newly hoisted instruction.
Previously, the lifetimes of only values which were copied were
canonicalized during the non-mandatory CopyPropagation pass. The
mandatory pass (i.e. MandatoryCopyPropagation) has been disabled,
meaning that non-copied values lifetimes were never canonicalized. So
enable canonicalization of all lifetimes during regular CopyPropagation.
rdar://54335055
Previously, the match failed to find the larger sequence that began with
load [copy] and ended with destroy_value because the iterator advanced
after finding the load [copy]. Advanced the iterator here.
Enables reverting the test outlining test changes introduced in
a52b8966c6.
In case of a borrowed `alloc_box`, the optimization didn't look through the `begin_borrow` when calculating the final release of the box.
This resulted in inserting the destroy of the inserted `alloc_stack` too early.
rdar://97087762
This was missing. It's not a big problem, but should be done correctly.
I noticed this because changes didn't get printed when I used `-sil-print-function`.
The new intrinsic, exposed via static functions on Task<T, Never> and
Task<T, Error> (rethrowing), begins an asynchronous context within a
synchronous caller's context. This is only available for use under the
task-to-thread concurrency model, and even then only under SPI.
Co-routines (called by `begin_apply`) may allocate and therefore it’s important to always inline them.
Also, refactor the code a bit to fix the if-changed-then-return-true logic.
rdar://94833845