You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cleanups around around parameter-passing modes (#8754)
The primary goal of this change is to try to fix (read: *remove*) the
logic that ovewrites the parameter-passing mode of an `out` parameter of
non-copyable type to be a `ref` parameter instead. I need that change in
order to implement a more reasonable pass to check for use of
uninitialized values in IR, because the semantics of an `out` parameter
are quite different from a `ref`, and I need to be able to tell them
apart.
Trying to make a systematic fix for the issue led me to make some more
broad refactoring and cleanup changes to operations that deal with
parameter-passing modes. Most notably, I have cleaned up several key
functions in `slang-lower-to-ir.cpp` to have more clear comments that
explain what they are doing, and why.
The general idea is that determining the parameter-passing mode of a
parameter breaks down into a few phases:
* First, theres the "nominal" (aka "declared") parameter-passing mode.
This is either the mode that is explicitly indicated by modifiers in the
source code (e.g., `in` or `out` on an explicit parameter declaration,
or `[mutating]` to control the implicit `this` parameter of a method),
or a mode that is inferred from other context related to the declaration
(e.g., the implicit `this` parameter of a `set` accessor defaults to
`inout`, but an implicit `this` in the context of a `class` is always
`in`).
* Next there is the "actual" parameter passing mode, which is based on
the nominal mode, but may be adjusted based on the type of the
parameter. For example, a parameter that is declared as `in` but that
has a non-copyable type will be treated as `borrow in`. There's an
additional wrinkled related to how we handle entry-point varying input
parameters (another case where a parameter declared as `in` may be
translated to use `borrow in`).
One of my goals was to try to bottleneck the logic for both
explicitly-declared parameters and the implicit `this` parameter through
the same code path, at least for computing the actual parameter-passing
mode from the nominal mode and parameter type. I don't think the logic
is as clean as it can/should be yet, but this is an incremental step in
a better direction.
The most important concern I have about this change is whether it will
break any existing code, because I have changed cases where a parameter
of non-copyable type would previously have been modified at the AST
level to use `ref` over to use `inout` or `out` instead. It is
reasonable to be concerned that this change could result in IR code
attempting to copy values of non-copyable type, which could break code
that uses non-copyable types like `RayQuery` and `HitObject`. I note
that the compiler already allows parameters of non-copyable type as
`borrow in` parameters (which allow implicit copies to be introduced,
just as for `inout` or `out`), so if the handling of `out` and `inout`
for non-copyable types is broken, it would strongly imply that `borrow
in` parameters of non-copyable types are already broken.
If it turns out that there is no reasonable way to stop passes on Slang
IR from introducing copies of non-copyable types when they use `out` or
`inout` (or even `borrow in`), then it seems like we will need to
introduce even more fine-grained parameter passing modes, to reflect the
difference between what we might call "value" borrows and "memory"
borrows, where the former allow copies to be introduced and the latter
don't. I really hope I don't have to go down that road, though, since it
is already challenging to explain to folks what all the existing
parameter-passing modes mean.
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Co-authored-by: James Helferty (NVIDIA) <jhelferty@nvidia.com>
0 commit comments