Skip to content
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

Add WGSL support for WaveGetLaneIndex and WaveGetLaneCount #6357

Closed

Conversation

fairywreath
Copy link
Contributor

Closes #6208.

Adds WGSL support for WaveGetLaneIndex and WaveGetLaneCount.

This change introduces an IR legalization step that allows WGSL builtin(system value) parameters to be propagated
to any other function by traversing its call graph. This is because WaveGetLaneIndex and WaveGetLaneCount
are "global functions" in HLSL that can be called anywhere while WGSL implements them through
built-in values that need to be passed in to the entry point parameter(Metal is similar).
Traversing the call graph, adding parameters and updating calls "just works" because it is
performed after all the function calls are resolved and lowered and because there is no
support for pointer-based/proper vtable dynamic dispatches.

The change additionally adds SV_WaveLaneIndex and SV_WaveCount system value semantic names.
This is done so system values can be legalized uniformly for WGSL and Metal targets. It is also
possible to just add these semantic names and add support for these in HLSL(which is easy), while
not supporting WaveGetLane* in WGSL and not have a entry point param -> call graph system value
parameter propagation system. This works for these specific intrinsics but does not really work
for Metal's (future) implementation quadSwap* intrinsics that require this propagation mechanism - this is a future change that will utilize this PR's code.

The code changes consist 3 parts:

  1. SV_WaveLaneIndex and SV_WaveCount system value semantic names.
  2. New implicit system value inst type and legalization step, where relevant function signatures and calls are updated.
    Implementation is placed in one cpp file.
  3. slang-ir-call-graph.cpp updates to also track function calls in addition to entry points.

@fairywreath fairywreath requested a review from a team as a code owner February 13, 2025 21:46
@fairywreath fairywreath marked this pull request as draft February 13, 2025 21:46
Comment on lines +20 to +24

/// Retrieves the set of functions that directly contain the given instruction in their body.
/// Returns nullptr if the instruction is not referenced by any function.
const HashSet<IRFunc*>* getReferencingFunctions(IRInst* inst) const;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is it guaranteed that an instruction is unique to a function body? I see that IRInst has a parent reference. If this is the case then this should return a single IRFunc instead of a set.

@fairywreath
Copy link
Contributor Author

Do tell me if this is too hacky and whether there are cleaner ways to implement this, or whether we should just support a semantic decoration name for these intrinsics.

@fairywreath fairywreath marked this pull request as ready for review February 13, 2025 21:50
@csyonghe
Copy link
Collaborator

I think you can make use of a global variable instead of modifying the call graph.

You can introduce a GetTargetBuiltin(target, builtinVarKind) instruction that is HOISTABLE, and map GetLaneIndex to that intrinsic inst on wgsl.

Then in wgsl legalization pass, rewrite that inst into a load from a compiler introduced global varaible, and insert a write into the global variable from each entrypoint.

@fairywreath
Copy link
Contributor Author

@csyonghe Thanks, I completely forgot that global variables are supported by the language. I have made another PR here #6371.

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.

Support shader subgroup/wave intrinsics for WGSL
2 participants