nir/lower_io: Add support for lowering deref_mode_is
The guts are still missing so it will blow up if it sees any deref_mode_is intrinsic that it can't constant-fold from the mode. Reviewed-by: Jesse Natalie <jenatali@microsoft.com> Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6332>
This commit is contained in:

committed by
Marge Bot

parent
57943112d9
commit
a451f037ff
@@ -216,6 +216,8 @@ intrinsic("get_ubo_size", src_comp=[-1], dest_comp=1,
|
|||||||
# mode checks, a pointer can only have exactly one mode at runtime.
|
# mode checks, a pointer can only have exactly one mode at runtime.
|
||||||
intrinsic("deref_mode_is", src_comp=[-1], dest_comp=1,
|
intrinsic("deref_mode_is", src_comp=[-1], dest_comp=1,
|
||||||
indices=[MEMORY_MODES], flags=[CAN_ELIMINATE, CAN_REORDER])
|
indices=[MEMORY_MODES], flags=[CAN_ELIMINATE, CAN_REORDER])
|
||||||
|
intrinsic("addr_mode_is", src_comp=[-1], dest_comp=1,
|
||||||
|
indices=[MEMORY_MODES], flags=[CAN_ELIMINATE, CAN_REORDER])
|
||||||
|
|
||||||
# a barrier is an intrinsic with no inputs/outputs but which can't be moved
|
# a barrier is an intrinsic with no inputs/outputs but which can't be moved
|
||||||
# around/optimized in general
|
# around/optimized in general
|
||||||
|
@@ -898,6 +898,18 @@ build_addr_for_var(nir_builder *b, nir_variable *var,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static nir_ssa_def *
|
||||||
|
build_runtime_addr_mode_check(nir_builder *b, nir_ssa_def *addr,
|
||||||
|
nir_address_format addr_format,
|
||||||
|
nir_variable_mode mode)
|
||||||
|
{
|
||||||
|
/* The compile-time check failed; do a run-time check */
|
||||||
|
switch (addr_format) {
|
||||||
|
default:
|
||||||
|
unreachable("Unsupported address mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static nir_ssa_def *
|
static nir_ssa_def *
|
||||||
addr_to_index(nir_builder *b, nir_ssa_def *addr,
|
addr_to_index(nir_builder *b, nir_ssa_def *addr,
|
||||||
nir_address_format addr_format)
|
nir_address_format addr_format)
|
||||||
@@ -1708,6 +1720,32 @@ lower_explicit_io_array_length(nir_builder *b, nir_intrinsic_instr *intrin,
|
|||||||
nir_instr_remove(&intrin->instr);
|
nir_instr_remove(&intrin->instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lower_explicit_io_mode_check(nir_builder *b, nir_intrinsic_instr *intrin,
|
||||||
|
nir_address_format addr_format)
|
||||||
|
{
|
||||||
|
if (addr_format_is_global(addr_format, 0)) {
|
||||||
|
/* If the address format is always global, then the driver can use
|
||||||
|
* global addresses regardless of the mode. In that case, don't create
|
||||||
|
* a check, just whack the intrinsic to addr_mode_is and delegate to the
|
||||||
|
* driver lowering that.
|
||||||
|
*/
|
||||||
|
intrin->intrinsic = nir_intrinsic_addr_mode_is;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(intrin->src[0].is_ssa);
|
||||||
|
nir_ssa_def *addr = intrin->src[0].ssa;
|
||||||
|
|
||||||
|
b->cursor = nir_instr_remove(&intrin->instr);
|
||||||
|
|
||||||
|
nir_ssa_def *is_mode =
|
||||||
|
build_runtime_addr_mode_check(b, addr, addr_format,
|
||||||
|
nir_intrinsic_memory_modes(intrin));
|
||||||
|
|
||||||
|
nir_ssa_def_rewrite_uses(&intrin->dest.ssa, nir_src_for_ssa(is_mode));
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
nir_lower_explicit_io_impl(nir_function_impl *impl, nir_variable_mode modes,
|
nir_lower_explicit_io_impl(nir_function_impl *impl, nir_variable_mode modes,
|
||||||
nir_address_format addr_format)
|
nir_address_format addr_format)
|
||||||
@@ -1769,6 +1807,15 @@ nir_lower_explicit_io_impl(nir_function_impl *impl, nir_variable_mode modes,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case nir_intrinsic_deref_mode_is: {
|
||||||
|
nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
|
||||||
|
if (nir_deref_mode_is_in_set(deref, modes)) {
|
||||||
|
lower_explicit_io_mode_check(&b, intrin, addr_format);
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -671,6 +671,7 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case nir_intrinsic_deref_mode_is:
|
case nir_intrinsic_deref_mode_is:
|
||||||
|
case nir_intrinsic_addr_mode_is:
|
||||||
validate_assert(state,
|
validate_assert(state,
|
||||||
util_bitcount(nir_intrinsic_memory_modes(instr)) == 1);
|
util_bitcount(nir_intrinsic_memory_modes(instr)) == 1);
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user