Keep in mind that these are approximations that will not impact correctness
since in all cases I ensured that the SIL will be the same after the
OwnershipModelEliminator has run. The cases that I was unsure of I commented
with SEMANTIC ARC TODO. Once we have the verifier any confusion that may have
occurred here will be dealt with.
rdar://28685236
Today, loads and stores are treated as having @unowned(unsafe) ownership
semantics. This leaves the user to specify ownership changes on the loaded or
stored value independently of the load/store by inserting ARC operations. With
the change to Semantic SIL, this will no longer be true. Instead loads, stores
have ownership semantics that one must reason about such as copy, take, and
trivial.
This change moves us closer to that world by eliminating the default
OwnershipQualification argument from create{Load,Store}. This means that the
compiler developer cannot ignore reasoning about the ownership semantics of the
memory operation that they are creating.
Operationally, this is a NFC change since I have just gone through the compiler
and updated all places where we create loads, stores to pass in the former
default argument ({Load,Store}OwnershipQualifier::Unqualified), to
SILBuilder::create{Load,Store}(...). For now, one can just do that in situations
where one needs to create loads/stores, but over time, I am going to tighten the
semantics up via the verifier.
rdar://28685236
Since we set the unqualified flag before we eliminate any instructions, this
will do the *right* thing and emit the most optimal lowered representation
whether it is a strong_* or *_value instruction.
This ensures that passes that expect values to have the most lowered
representation of instruction to be able to pattern match correctly.
This can up when alloc-box-to-stack was pattern matching on strong_retain on
Boxes, but I was being lazy and emitted retain_value.
rdar://28851920
* [sil-performance-inliner] Re-factor the isProfitableToInline logic. NFC.
* [sil-performance-inliner] Introduce a pre-filter to decide of a generic function should be inlined
This logic is unconditional and is does not require any complex cost models.
The outcome of the check is one of:
- yes, inline this generic function
- no, do not inline this generic function
- None, don't know if it should be inline. Further more complex checks are required.
* [sil-performance-inliner] Handle inlining of generic functions into cold blocks
Generic functions should be inlined into cold blocks only if they should be unconditionally inlined (e.g. when they are always_inline or transparent).
* Allow generic inlining under -sil-inline-generics.
This is a NFC change, since verification still will be behind the flag. But this
will allow me to move copy_value, destroy_value in front of the
EnableSILOwnership flag and verify via SILGen that we are always using those
instructions.
rdar://28851920
Use the following options to enable this flag: -Xllvm -sil-inline-generics
Generic inlining is now handled by a dedicated logic in isProfitableToInlineGeneric. This makes it easier to find this logic. And it will make it easier to extend and improve it in the future.
The initial policy for generic inlining is:
- unconditionally inline generic functions if the -sil-inline-generics flag is used.
- If the flag is not used, only perform generic inlining of always_inline and transparent functions.
There are slight standard library's code-size regressions with this policy. They will be addressed by the future work on the generic inlining.
- Move the common performance inliner functionality into PerformanceInlinerUtils.cpp.
- Move the functionality specific to non-generic inlining into NonGenericPerformanceInliner.cpp
- Temporarily disable the inlining of generics. It will be enabled in the subsequent commit.
The behaviour of ilist has changed in LLVM. It is no longer permissible to
dereference the `end()` value. Add a check to ensure that we do not
accidentally dereference the iterator.
The new instructions are: ref_tail_addr, tail_addr and a new attribute [ tail_elems ] for alloc_ref.
For details see docs/SIL.rst
As these new instructions are not generated so far, this is a NFC.
delete it and recreate new one
This is a compilation time improvement
There are a few small modifications to the tests, as we try to create
different, but equivalent retain/release before even though we can reuse
the old ones.
rdar://28329689
The new instructions are: ref_tail_addr, tail_addr and a new attribute [ tail_elems ] for alloc_ref.
For details see docs/SIL.rst
As these new instructions are not generated so far, this is a NFC.
When applying substitutions to substitution lists in SIL, we would
unpack the ArrayRef<Substitution> into a SubstitutionMap on each
iteration over the original ArrayRef<Substitution>. Discourage
this sort of thing by removing the API in question and refactoring
surrounding code.