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

[naga] Add some documentation for the uniformity analysis. #5437

Merged
merged 1 commit into from
Mar 28, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 58 additions & 11 deletions naga/src/valid/analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,35 @@ pub struct SamplingKey {
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
/// Information about an expression in a function body.
pub struct ExpressionInfo {
/// Whether this expression is uniform, and why.
///
/// If this expression's value is not uniform, this is the handle
/// of the expression from which this one's non-uniformity
/// originates. Otherwise, this is `None`.
pub uniformity: Uniformity,

/// The number of statements and other expressions using this
/// expression's value.
pub ref_count: usize,

/// The global variable into which this expression produces a pointer.
///
/// This is `None` unless this expression is either a
/// [`GlobalVariable`], or an [`Access`] or [`AccessIndex`] that
/// ultimately refers to some part of a global.
///
/// [`Load`] expressions applied to pointer-typed arguments could
/// refer to globals, but we leave this as `None` for them.
///
/// [`GlobalVariable`]: crate::Expression::GlobalVariable
/// [`Access`]: crate::Expression::Access
/// [`AccessIndex`]: crate::Expression::AccessIndex
/// [`Load`]: crate::Expression::Load
assignable_global: Option<Handle<crate::GlobalVariable>>,

/// The type of this expression.
pub ty: TypeResolution,
}

Expand Down Expand Up @@ -311,14 +336,20 @@ pub enum UniformityDisruptor {
}

impl FunctionInfo {
/// Adds a value-type reference to an expression.
/// Record a use of `expr` of the sort given by `global_use`.
///
/// Bump `expr`'s reference count, and return its uniformity.
///
/// If `expr` is a pointer to a global variable, or some part of
/// a global variable, add `global_use` to that global's set of
/// uses.
#[must_use]
fn add_ref_impl(
&mut self,
handle: Handle<crate::Expression>,
expr: Handle<crate::Expression>,
global_use: GlobalUse,
) -> NonUniformResult {
let info = &mut self.expressions[handle.index()];
let info = &mut self.expressions[expr.index()];
info.ref_count += 1;
// mark the used global as read
if let Some(global) = info.assignable_global {
Expand All @@ -327,22 +358,38 @@ impl FunctionInfo {
info.uniformity.non_uniform_result
}

/// Adds a value-type reference to an expression.
/// Record a use of `expr` for its value.
///
/// This is used for almost all expression references. Anything
/// that writes to the value `expr` points to, or otherwise wants
/// contribute flags other than `GlobalUse::READ`, should use
/// `add_ref_impl` directly.
#[must_use]
fn add_ref(&mut self, handle: Handle<crate::Expression>) -> NonUniformResult {
self.add_ref_impl(handle, GlobalUse::READ)
fn add_ref(&mut self, expr: Handle<crate::Expression>) -> NonUniformResult {
self.add_ref_impl(expr, GlobalUse::READ)
}

/// Adds a potentially assignable reference to an expression.
/// These are destinations for `Store` and `ImageStore` statements,
/// which can transit through `Access` and `AccessIndex`.
/// Record a use of `expr`, and indicate which global variable it
/// refers to, if any.
///
/// Bump `expr`'s reference count, and return its uniformity.
///
/// If `expr` is a pointer to a global variable, or some part
/// thereof, store that global in `*assignable_global`. Leave the
/// global's uses unchanged.
///
/// This is used to determine the [`assignable_global`] for
/// [`Access`] and [`AccessIndex`] expressions that ultimately
/// refer to a global variable. Those expressions don't contribute
/// any usage to the global themselves; that depends on how other
/// expressions use them.
#[must_use]
fn add_assignable_ref(
&mut self,
handle: Handle<crate::Expression>,
expr: Handle<crate::Expression>,
assignable_global: &mut Option<Handle<crate::GlobalVariable>>,
) -> NonUniformResult {
let info = &mut self.expressions[handle.index()];
let info = &mut self.expressions[expr.index()];
info.ref_count += 1;
// propagate the assignable global up the chain, till it either hits
// a value-type expression, or the assignment statement.
Expand Down
Loading