The use of 'nocapture' for parameters and return values is incorrect for C++ types, as they can actually capture a pointer into its own value (e.g. std::string in libstdc++)
rdar://115062687
Mandatory copy propagation was primarily a stop-gap until lexcial
lifetimes were implemented. It supposedly made variables lifetimes
more consistent between -O and -Onone builds. Now that lexical
lifetimes are enabled, it is no longer needed for that purpose (and
will never satisfactorily meet that goal anyway).
Mandatory copy propagation may be enabled again later as a -Onone "
optimization. But that requires a more careful audit of the effect on
debug information.
For now, it should be disabled.
The effect of passing -enable-copy-propagation is both to enable the
CopyPropagation pass to shorten object lifetimes and also to enable
lexical lifetimes to ensure that object lifetimes aren't shortened while
a variable is still in scope and used.
Add a new flag, -enable-lexical-borrow-scopes=true to override
-enable-copy-propagation's effect (setting it to ::ExperimentalLate) on
SILOptions::LexicalLifetimes that sets it to ::Early even in the face of
-enable-copy-propagation. The old flag -disable-lexical-lifetimes is
renamed to -enable-lexical-borrow-scopes=false but continues to set that
option to ::Off even when -enable-copy-propagation is passed.
This feature degrades the debugging experience and causes a large
number of unit test failures.
These were both known issues, but our planned debugger improvements
won't be ready for a while. Until then, we'll leave the feature under
a compiler option, and developers can adopt it at there own speed for
now when they are ready to fix lifetime issues in their code.
rdar://76177280 (Disable mandatory-copy-propagation (-Onone only))
This shortens -Onone lifetimes.
To eliminate ARC traffic, the optimizer reorders object
destruction. This changes observable program behavior. If a custom
deinitializer produces side effects, code may observe those side
effects earlier after optimization. Similarly, code that dereferences
a weak reference may observe a 'nil' reference after optimization,
while the unoptimized code observed a valid object.
Developers have overwhelmingly requested that object lifetimes have
similar behavior in -Onone and -O builds in order to find and diagnose
program bugs involving weak references and other lifetime assumptions.
Enabling the copy propagation at -Onone is simply a matter of flipping
a switch. -Onone runtime and code size will improve. By design, copy
propagation, has no direct affect on compile time. It will indirectly
improve optimized compile times, but in debug builds, it simply isn't
a factor.
To support debugging, a "poison" flag was (in prior commits) added to
new destroy_value instructions generated by copy propagation. When
OwnershipModelEliminator lowers destroy_value [poison] it will
generate new debug_value instructions with a “poison” flag.
These additional poison stores to the stack could increase both code
size and -Onone runtime.
rdar://75012368 (-Onone compiler support for early object deinitialization with sentinel dead references)
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.
The 'fake use' asm gadget does not always keep variables alive. E.g., in
rdar://57754659, llvm was unable to preserve two local variables despite
the use of these gadgets. These variables were backed by a LoadInst and
an ExtractValueInst respectively. Instead of emitting shadow copies for
just those kinds of instructions, use shadow copies exclusively. This
may cause more variables to appear in the debugger window before they
are initialized, but should result in fewer variables being dropped.
rdar://57754659