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.
This makes it easier to understand conceptually why a ValueOwnershipKind with
Any ownership is invalid and also allowed me to explicitly document the lattice
that relates ownership constraints/value ownership kinds.
Array literals only need to be finalized, if the array is really allocated.
In case of zero elements, no allocation is done, but the empty-array singleton is used.
"Finalization" means to emit an end_cow_mutation instruction on the array.
As the empty-array singleton is a read-only and shared object, it's not legal to do a end_cow_mutation on it.
Prevent SILGen to crash if the compiler is used with a stdlib which does not have the _finalizeUninitializedArray intrinsic function.
rdar://problem/64195028
For COW support in SIL it's required to "finalize" array literals.
_finalizeUninitializedArray is a compiler known stdlib function which is called after all elements of an array literal are stored.
This runtime function marks the array literal as finished.
%uninitialized_result_tuple = apply %_allocateUninitializedArray(%count)
%mutable_array = tuple_extract %uninitialized_result_tuple, 0
%elem_base_address = tuple_extract %uninitialized_result_tuple, 1
...
store %elem_0 to %elem_addr_0
store %elem_1 to %elem_addr_1
...
%final_array = apply %_finalizeUninitializedArray(%mutable_array)
In this commit _finalizeUninitializedArray is still a no-op because the COW support is not used in the Array implementation yet.
suppressGlobalStringTablePointerError of OSLogOptimization pass
that happens because of eagerly deleting instructions while
iterating on them. This was fixed using the InstructionDeleter
utility.
os log APIs, based on the fact that there is already a Sema check for
enforcing the user model.
Suppress the errors generated by for the _globalStringTablePointerBuiltin
when the OSLogOptimization pass emits diagnostics. This elimiantes the
cryptic error that always accompanies the diagnostics emitted by the
OSLogOptimization pass.
code for closures iff the closure is not created by the caller function
where the code is generated. Otherwise, when the closure is created
by the caller, just reuse it after copying and extending its lifetime.
Before this change new closures were created as long as all captures
of the closures were symbolic constants. This patch updates it so that
even if all captures are symbolic constants no code is generated for
closures that are already available in the caller. This avoids doing
needless work and also fixes the following bug.
<rdar://problem/61465764>
Andy and I for some time have been discussing the right name for these two
"ownership concepts". What we realized is that the "ing" on
BorrowScopeIntroducingValue is very unfortunate since this value is the result
of a new borrow scope being introduced. So the name should be really:
BorrowScopeIntroducedValue. Given that is sort of unsatisfying, we settled on
the name BorrowedValue.
Once we found the name BorrowedValue, we naturally realized that
BorrowScopeOperand -> BorrowingOperand followed. This is because the operand is
the operand of the instruction that is creating the new borrow scope. So in a
sense the Operand is the "Use" that causes the original value to become
borrowed. So a BorrowingOperand is where the action is and is "active".
new closures when all captures of the symbolic closure, including address-typed
captures, are symbolic constants. For other closures, they must have been
autoclosures passed to the log call and therefore they need not be duplicated
but reused as such.
This eliminates the need to copy_value the non-constant captured values of
closures. Instead the closure itself is copied as a whole.
Fixes <rdar://problem/60344043>
I also added a comment to getAllBorrowIntroducingValues(...) that explained the
situations where one could have multiple borrow introducing values:
1. True phi arguments.
2. Aggregate forming instructions.
using the new InstructionDeleter utility. The elimination logic
exploits the fact that constant_evaluable function calls have
been evaluated and folded, in order to remove such calls that
may possibly take @inout parameters.
and eliminate dead code. This is meant to be a replacement for the utility:
recursivelyDeleteTriviallyDeadInstructions. The new utility performs more aggresive
dead-code elimination for ownership SIL.
This patch also migrates most non-force-delete uses of
recursivelyDeleteTriviallyDeadInstructions to the new utility.
and migrates one force-delete use of recursivelyDeleteTriviallyDeadInstructions
(in IRGenPrepare) to use the new utility.
function of the OSLogOptimization pass that happens when folding a
guaranteed value with a constant (owned) value. The fix inserts the
constant value at the beginning of the borrowed scope of the guaranteed
value rather than at the definition of the guaranteed value.
Update the SIL tests for the new folding pattern and add a test that
catches this bug.
Also, re-enable the OSLogPrototypeExecTest.swift that was disabled
due to this bug.
This is important both for correctness reasons and for triaging reasons. The
correctness is obvious, but for those unaware there are many triaging utilities
that only verify or print pass output if the pass makes a change as indicated by
invalidating state.
fold a symbolic closure, which is the representation of a closure literal
in the constant evaluator. This commit improves the function
emitCodeForSymbolicValue so that given a symbolic closure it can emit
SIL code for constructing the closure.
This improvement enables folding the arguments array, which is an array
of closures, by its constant value inferred by constant evaluating the
new OSLog calls.
of the OSLogOptimization pass. This commit contain two changes:
- It handles non-OSSA better (but it is meant to be phased out) so
that array and closure folding can be supported
- It fixes a bug in the OSSA folding by making sure that when an
owned value replaces a guaranteed value, the owned value is
borrowed and the borrow is used in place of the guaranteed value.
symbolic values, which are used to represent constant struct and tuple
instances. Associating those symbolic values with the types of the
aggregate they are representing will allow writing some sanity checks,
and will also make constant folding of the symbolic values easier and
more robust.
of OSLogMessage constant evaluable and remove @_transparent annotation
from the methods. Also, improve diagnostics in the OSLogOptimization
pass as now it rely on seeing the appendInterpolation/Literal calls.
add -enable-ownership-stripping-after-serialization flag to OSLog optimization tests,
and update the folding logic and end-of-use discovery logic to handle ownership
and non-ownership SIL.
`cdecl` is a keyword in the non-conforming C++ dialect used on Windows
which expands to `__cdecl`. Simply rename the variable to avoid the
replacement. Although it is possible to `#undef cdecl`, renaming makes
it less confusing for non-Windows developers.
The XXOptUtils.h convention is already established and parallels
the SIL/XXUtils convention.
New:
- InstOptUtils.h
- CFGOptUtils.h
- BasicBlockOptUtils.h
- ValueLifetime.h
Removed:
- Local.h
- Two conflicting CFG.h files
This reorganization is helpful before I introduce more
utilities for block cloning similar to SinkAddressProjections.
Move the control flow utilies out of Local.h, which was an
unreadable, unprincipled mess. Rename it to InstOptUtils.h, and
confine it to small APIs for working with individual instructions.
These are the optimizer's additions to /SIL/InstUtils.h.
Rename CFG.h to CFGOptUtils.h and remove the one in /Analysis. Now
there is only SIL/CFG.h, resolving the naming conflict within the
swift project (this has always been a problem for source tools). Limit
this header to low-level APIs for working with branches and CFG edges.
Add BasicBlockOptUtils.h for block level transforms (it makes me sad
that I can't use BBOptUtils.h, but SIL already has
BasicBlockUtils.h). These are larger APIs for cloning or removing
whole blocks.
discovering the beginning of the string interpolation passed
to os log APIs.
The implementation follows the chain of dependencies starting
from an initializer call to OSLogMessage until the first
instruction of interpolation is discovered. This is more
robust towards changes to the SIL generation of string
interpolation literals.
evaluator to precisely evaluate Builtin.assert_configuration.
Unify UnknownReason::Trap and UnknownReason::AssertionFailure error
values in the constant evaluator, now that we have 'condfail_message'
SIL instruction, which provides an error message for the traps.
@_semantics("constant_evaluable") annotation to denote constant
evaluable functions.
Add a test suite that uses the sil-opt pass ConstantEvaluableSubsetChecker.cpp
to check the constant evaluability of function in the OSLog
overlay.
the builtin.globalStringTablePointer to the new OSLog overlay.
Modify the new OSLog implementation to use this SPI instead of
`withCString` to pass the (compiler-generated) format string to
the C os_log_impl ABI.
Move the OSLogOptimization pass before constant propagation in
the pass pipeline so that the SPI and the builtin it uses can be
folded to a string_literal instruction.
Update OSLogTests to work with the changes in the implementation.