For most uses, some access scopes must be "respected"--if an extended
value's original lifetime originally extends beyond an access scope, its
canonicalized lifetime must not end _within_ such scopes (although
ending before them is fine). Currently, to be conservative, the utility
applies this behavior to all access scopes.
For move-only values, however, lifetimes end at final consumes without
regard to access scopes.
Allow this behavior to be controlled by whether or not a
NonLocalAccessBlockAnalysis is provided to the utility in its
constructor.
rdar://104635319
This is a cleaner separation of concerns. The reason why I did not do this
originally is that I thought I would need to reuse this functionality in the
address checker, but this issue actually does not come up there since we project
the address and then load instead of load and then project.
When encountering inside a borrow scope a non-lexical move_value or a
move_value [lexical] where the borrowed value is itself already lexical,
delete the move_value and regard its uses as uses of the moved-from
value.
This enables us to emit the appropriate error for consuming uses of fields and
also causes us to eliminate copies exposed by using fields of a move only type
in a non-consuming way.
rdar://103271138
If a unit test is miswritten in the sense that the test expects an
instance of one type by an instance of some other type is specified,
print that out.
* for testing: add the option `-simplify-instruction=<instruction-name>` to only run simplification passes for that instruction type
* on the swift side, add `Options.enableSimplification`
* split the `PassContext` into multiple protocols and structs: `Context`, `MutatingContext`, `FunctionPassContext` and `SimplifyContext`
* change how instruction passes work: implement the `simplify` function in conformance to `SILCombineSimplifyable`
* add a mechanism to add a callback for inserted instructions
Previously, the dealloc_stacks created for the alloc_stacks used to pass
@in_guaranteed arguments to on_stack closures were created after the
users of the closure. When SILGen created these alloc_stacks in the
same block as the users, this happened to work. Now that
AddressLowering creates such alloc_stacks elsewhere, this approach
results in invalid SIL.
Here, the dealloc_stacks are instead at the end of each block in the
dominance frontier of the alloc_stack.
Replace the generic `List` with the (non-generic) `InstructionList` and `BasicBlockList`.
The `InstructionList` is now a bit different than the `BasicBlockList` because it supports that instructions are deleted while iterating over the list.
Also add a test pass which tests instruction modification while iteration.
Add `deletableInstructions()` and `reverseDeletableInstructions()` in SILBasicBlock.
It allows deleting instructions while iterating over all instructions of the block.
This is a replacement for `InstructionDeleter::updatingRange()`.
It's a simpler implementation than the existing `UpdatingListIterator` and `UpdatingInstructionIteratorRegistry`, because it just needs to keep the prev/next pointers for "deleted" instructions instead of the iterator-registration machinery.
It's also safer, because it doesn't require to delete instructions via a specific instance of an InstructionDeleter (which can be missed easily).
The current `UpdatingInstructionIteratorRegistry` referenced `this` in
the member initializer list. As per class.cdtor 11.9.5p1, this is UB as
for any class with a non-trivial constructor, referencing the base class
of the object before the constructor begins execution is not permitted.
We attempted to capture `this` in the lambda that was used to initialise
the member. This was being exploited by the MSVC compiler resulting in
incorrect execution of the instruction deleter.
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`
The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.
rdar://102362022
The pass to decide which functions should get stack protection was added in https://github.com/apple/swift/pull/60933, but was disabled by default.
This PR enables stack protection by default, but not the possibility to move arguments into temporaries - to keep the risk low.
Moving to temporaries can be enabled with the new frontend option `-enable-move-inout-stack-protector`.
rdar://93677524
Begin adding support for OSSA to checked-cast jump-threading based on
the new ownership utilities.
TODO:
Finish migrating to the new utilities in OwnershipOptUtils.
Ensure full unit test coverage.
Made bare @instruction and @block more useful. Rather than referring to
the first instruction and block in the current function, instead, they
now refer to the instruction after the test_specification instruction
(which must always exist) and the block containing the
test_specification instruction.
This invalidation kind is used when a compute-effects pass changes function effects.
Also, let optimization passes which don't change effects only invalidate the `FunctionBody` and not `Everything`.
Pass a BasicCalleeAnalysis instance to isDeinitBarrier. This enables
LexicalDestroyHoisting to hoist destroys over applies of functions which
are not deinit barriers.
Pass a BasicCalleeAnalysis instance to isDeinitBarrier. This will allow
ShrinkBorrowScope to hoist end_borrows over applies of functions which
are not deinit barriers.
Added new C++-to-Swift callback for isDeinitBarrier.
And pass it CalleeAnalysis so it can depend on function effects. For
now, the argument is ignored. And, all callers just pass nullptr.
Promoted to API the mayAccessPointer component predicate of
isDeinitBarrier which needs to remain in C++. That predicate will also
depends on function effects. For that reason, it too is now passed a
BasicCalleeAnalysis and is moved into SILOptimizer.
Also, added more conservative versions of isDeinitBarrier and
maySynchronize which will never consider side-effects.