It converts a lazily initialized global to a statically initialized global variable.
When this pass runs on a global initializer `[global_init_once_fn]` it tries to create a static initializer for the initialized global.
```
sil [global_init_once_fn] @globalinit {
alloc_global @the_global
%a = global_addr @the_global
%i = some_const_initializer_insts
store %i to %a
}
```
The pass creates a static initializer for the global:
```
sil_global @the_global = {
%initval = some_const_initializer_insts
}
```
and removes the allocation and store instructions from the initializer function:
```
sil [global_init_once_fn] @globalinit {
%a = global_addr @the_global
%i = some_const_initializer_insts
}
```
The initializer then becomes a side-effect free function which let's the builtin-simplification remove the `builtin "once"` which calls the initializer.
Eliminate the redundant instruction pair
```
%t = tuple (%0, %1, %2)
(%3, %4, %5) = destructure_tuple %t
```
and replace the results %3, %4, %5 with %0, %1, %2, respectively.
The same for structs.
* Check if the address in question is even visible from outside the function
* Return the memory effects of the called function
Also, add a new API `Instruction.memoryEffects`, which is internally used by `mayReadFromMemory` et al.
This reverts commit e9dedf3c27.
The revert is required as foreign reference types are available for SwiftStdlib 5.8 and above, but the Swift compiler
sources back deploy to older stdlibs as well.
This is in preparation for wiring up debug info support for noncopyable
values. Originally this flag name made sense since it was set when we performed
consume operator checking. Now I am going to use it for noncopyable types as
well. I think the new name uses_moveable_value_debuginfo actually describes what
the flag is supposed to do, tell IRGen that the value may be moved since it
needs to use moveable value debug info emission.
A type (mostly classes) can be attributed with `@_semantics("arc.immortal")`.
ARC operations on values of such types are eliminated.
This is useful for the bridged SIL objects in the swift compiler sources.
Looking at the SIL I came to the conclusion that `Unmanaged` ins fundamentally broken.
It's easier to directly bitcast between bridged and native SIL objects. It also produces simpler SIL which can be further optimized
Instead of doing the type casts and/or conformance lookup on the swift side, do it on the C++ side.
It makes a significant performance difference because `Operand.value` is a time critical function
The run time of `Value.hasTrivialNonPointerType` is not negligible, because it does a cache lookup of type lowerings.
Only do this check if it's really needed.
The `isEscaping` function is called a lot from ARCSequenceOpt and ReleaseHoisting.
To avoid quadratic complexity for large functions, limit the amount of work what the EscapeUtils are allowed to to.
This keeps the complexity linear.
The arbitrary limit is good enough for almost all functions.
It lets the EscapeUtils do several hundred up/down walks which is much more than needed in most cases.
Fixes a compiler hang
https://github.com/apple/swift/issues/63846
rdar://105795976