Skip to content

[NFC] SIL: Clarified deinit barrier APIs. #70774

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

nate-chandler
Copy link
Contributor

@nate-chandler nate-chandler commented Jan 8, 2024

This PR adds three commits on top of #70773 .

An instruction is a deinit barrier whenever one of three component predicates is true for it. In the case of applies, it is true whenever one of those three predicates is true for any of the instructions in any of its callees; that fact is cached in the side-effect analysis of every function.

If side-effect analysis or callee analysis is unavailable, in order to define each of those three component predicates on a FullApplySite/EndApplyInst/AbortApplyInst, it would be necessary to define them to conservatively return true: it isn't known whether any of the instructions in any of the callees were deinit barriers.

Refactored the two versions of the deinit barrier predicate (namely Instruction.isDeinitBarrier(_:) and swift::mayBeDeinitBarrierNotConsideringSideEffects) to handle FullApplySite/EndApplyInst/AbortApplyInsts specially first (to look up the callees' side-effect and to conservatively bail, respectively). Asserted that the three component predicates are not called with FullApplySite/EndApplyInst/AbortApplyInsts. Callers should instead use the isDeinitBarrier APIs.

An alternative would be to conservatively return true from the three components. That seems more likely to result in direct calls to these member predicates, however, and at the moment at least there is no reason for such calls to exist. If some other caller besides the deinit-barrier predicates needs to call this function, side-effect analysis should be updated to cache these three properties separately at that point.

When an instruction `mayReadOrWriteMemory`, the `mayAccessPointer`
predicate relies on the `visitAccessedAddress` utility to determine
whether an instruction may access a pointer.  That utility doesn't (and
can't, without changing the representation of the builtin) visit
`RawPointer` operands as used by memmove/memcpy builtins.

Previously, this resulted `mayAccessPointer` returning `false` for such
builtins.  Here, this is fixed by making the predicate handle
`BuiltinInsts` separately.  Instead of just always returning `true` in
the face of a builtin, rely on the BuiltinInfo associated with a
BuiltinInst and use `mayReadOrWriteMemory`.

rdar://120656227
Dropped the NotConsideringSideEffects suffix.
Copy link
Contributor

@atrick atrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM; although in all three APIs, I think Builtins that mayReadOrWriteMemory should be treated conservatively.

@nate-chandler nate-chandler force-pushed the nfc/20240108/1/deinit-barrier-component-predicates branch from c47e7d2 to 30cacdf Compare January 8, 2024 22:44
The three predicates are all now defined and defined correctly on
builtins to return true whenever mayReadOrWriteMemory is true.
An instruction is a deinit barrier whenever one of three component
predicates is true for it.  In the case of applies, it is true whenever
one of those three predicates is true for any of the instructions in any
of its callees; that fact is cached in the side-effect analysis of every
function.

If side-effect analysis or callee analysis is unavailable, in order to
define each of those three component predicates on a
`FullApplySite`/`EndApplyInst`/`AbortApplyInst`, it would be necessary
to define them to conservatively return true: it isn't known whether any
of the instructions in any of the callees were deinit barriers.

Refactored the two versions of the deinit barrier predicate (namely
`Instruction.isDeinitBarrier(_:) and
`swift::mayBeDeinitBarrierNotConsideringSideEffects`) to handle
`FullApplySite`/`EndApplyInst`/`AbortApplyInst`s specially first (to
look up the callees' side-effect and to conservatively bail,
respectively).  Asserted that the three component predicates are not
called with `FullApplySite`/`EndApplyInst`/`AbortApplyInst`s.  Callers
should instead use the `isDeinitBarrier` APIs.

An alternative would be to conservatively return true from the three
components.  That seems more likely to result in direct calls to these
member predicates, however, and at the moment at least there is no
reason for such calls to exist.  If some other caller besides the
deinit-barrier predicates needs to call this function, side-effect
analysis should be updated to cache these three properties separately at
that point.
@nate-chandler nate-chandler force-pushed the nfc/20240108/1/deinit-barrier-component-predicates branch from 30cacdf to 82b7495 Compare January 8, 2024 23:34
@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@nate-chandler nate-chandler merged commit 7365f9f into swiftlang:main Jan 9, 2024
@nate-chandler nate-chandler deleted the nfc/20240108/1/deinit-barrier-component-predicates branch January 9, 2024 14:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants