1. builtin "int_expect", which makes the evaluator work on more
integer operations such as left/right shift (with traps) and
integer conversions.
2. builtin "_assertConfiguration", which enables the evaluator
to work with debug stdlib.
3. builtin "ptrtoint", which enables the evaluator to track
StaticString
4. _assertionFailure API, which enables the evaluator to report
stdlib assertion failures encountered during constant evaluation.
Also, enable attaching auxiliary data with the enum "UnknownReason"
and use it to improve diagnostics for UnknownSymbolicValues,
which represent failures during constant evaluation.
The idea is that this can be used to work with things like load_borrow,
begin_borrow, SILFunctionArgument, results of begin_apply(in the future) and the like in a
generic way using exhaustive switches to make sure this code stays up to date.
I refactored code in SemanticARCOpts and some utilities in OwnershipUtils.cpp to
use these new APIs. The code looks a lot nicer and should be quite easy to
expand to handle new borrow introducers (e.x.: end_apply).
Even if a destroy_addr of a trivial type is a no-op, we must not end up with using such a value after a destroy_addr.
The fix is to also handle aggregate fields of trivial types in MemoryLifetime.
rdar://problem/55125020
This mostly requires changing various entry points to pass around a
TypeConverter instead of a SILModule. I've left behind entry points
that take a SILModule for a few methods like SILType::subst() to
avoid creating even more churn.
The weak imported flag is now only set if the attribute is unconditionally
weak linked, which is the case when it or one of its parent contexts has a
@_weakLinked attribute.
To correctly handle weak linking based availability with serialized SIL
functions, we need to serialize the actual version tuple when the SIL function
was introduced. This is because the deployment target of the client app can
be older than the deployment target that the original module was built with.
Fixes <rdar://problem/52783668>.
For some time now we have had the API ValueBase::getSingleUserOfType<T>() but we
never implemented getUsersOfType<T>() using transform/filter iterators.
Since there wasn't a specific API, several incarnations of this API have been
created for BeginBorrow, LoadBorrow, BeginAccess.
In this commit, I introduce the API and use it to excise the redundant code in
those above mentioned 3 instructions.
SILCombiner has a number of conveniences for inserting, replacing, and
removing instructions that involve modifying a worklist as part of their
behavior. Here, that functionality is added to the
SILInstructionWorklist; in a subsequent commit it will be removed from
SILCombiner which will then call through to SILInstructionWorklist.
- Replaced usage of raw map and vector with the type that wraps the
combination (BlotSetVector); that provided a significant deduplication
since a sizeable portion of the worklist's implementation was in
vector and map management now provided by the BlotSetVector.
- Templated over the type of map and vector used by the blot set vector.
- Added SmallSILInstructionWorklist where the map and vector are
specified to be SmallDenseMap and SmallVector respectively.
- Replaced usages of bare ValueBase with usages of SILValue.
- Renamed zap to resetChecked.
Added a bit of functionality to BlotSetVector, specifically to support
SILInstructionWorklist:
- Made insert return not just the index that the potentially-inserted
item is at on return but additionally whether an insertion occurred,
matching the behavior of llvm::DenseMap::insert.
- Added a method to reserve capacity in the backing vector and map:
BlotSetVector::reserve.
- Added a method to free extra storage used by the backing vector and
map: BlotSetVector::clear.
- Modified SmallBlotSetVector's template parameters so that only a value
and size can be specified--that type will always use SmallVector and
SmallDenseMap for its superclass' VectorT and MapT template
parameters.
- Updated variable names.
* Fix multi-threaded IRGen: store the DeclContext in a SILFunction explicitly instead of deriving it from the debug location. It's used in IRGen to decide into which module a function is emitted. With -gsil the debug location is changed and that should not change the module decision.
* Erase debug_value/debug_value_addr instructions when using -gsil. Those instructions are not needed anymore. They can also trigger a verifier error.
SILCombine had a dedicated worklist type that is generally useful. Here
that type is extracted into SIL as SILInstructionWorklist so that it can
be reused. Minor style changes were made as well.
DestroyHoisting moves destroys of memory locations up the control flow as far as possible.
Beside destroy_addr, also "store [assign]" is considered a destroy, because is is equivalent to an destroy_addr + a "store [init]".
The main purpose of this optimization is to minimize copy-on-write operations for arrays, etc. Especially if such COW containers are used as enum payloads and modified in-place. E.g.
switch e {
case .A(var arr):
arr.append(x)
self = .A(arr)
...
In such a case DestroyHoisting can move the destroy of the self-assignment up before the switch and thus let the array buffer only be single-referenced at the time of the append.
When we have ownership SIL throughout the pass pipeline this optimization will replace the current destroy hoisting optimization in CopyForwarding.
For now, this optimization only runs in the mandatory pipeline (but not for -Onone) where we already have ownership SIL.
SR-10605
rdar://problem/50463362
If the lifetime of a value copied out of a let property in a class is dominated by the lifetime
of the base object it was copied from, then we don't need to copy at all, since the value of the
`let` is guaranteed as long as the base object is. `let` globals are in turn always guaranteed.
rdar://problem/54531607
Specifically, we were preferring the always correct ownership kind specified by
the FunctionType and ignoring what we parsed from the argument. This PR changes
ossa to give a nice error when this is detected and fixes the places where this
tests were written incorrectly.
Rather than storing the set of input requirements in a
(SIL)SpecializeAttr, store the specialized generic signature. This
prevents clients from having to rebuild the same specialized generic
signature on every use.
This provides a singular instruction for convert an unmanaged value to a ref,
then strong_retain it. I expanded the definition of UNCHECKED_REF_STORAGE to
include these copy like instructions. This instruction is valid in all SIL.
The reason why I am adding this instruction is that currently when we emit an
access to an unowned (unsafe) ivar, we use an unmanaged_to_ref and a strong
retain. This can look to the optimizer like a strong retain that can potentially
be optimized. By combining the two together into a new instruction, we can avoid
this potential problem since the pattern matching will break.
The name doesn't mean "memory access" colloquially. It specifically
refers to memory operations that take part in formal access scopes
marked by begin_access/end_access instructions. If you aren't working
with those instructions it really doesn't make sense to use it.
A function may be eliminated as dead code after initial builtin lowering
occurs. When this happens, an entry in the profile symbol table for the
function is not guaranteed. Its coverage record should be dropped.
rdar://42564768