nir: add nir_instr_can_speculate helper (for LICM)

Acked-by: Job Noorman <job@noorman.info>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36099>
This commit is contained in:
Marek Olšák 2025-03-16 21:44:59 -04:00 committed by Marge Bot
parent 800a861431
commit b4afe848a1
3 changed files with 45 additions and 12 deletions

View file

@ -2728,6 +2728,47 @@ nir_intrinsic_can_reorder(nir_intrinsic_instr *instr)
(info->flags & NIR_INTRINSIC_CAN_REORDER);
}
/* Return whether an instruction returns the same result regardless of where
* it's executed in the shader and regardless of whether it's executed multiple
* times.
*/
bool
nir_instr_can_speculate(nir_instr *instr)
{
nir_intrinsic_instr *intr;
switch (instr->type) {
case nir_instr_type_undef:
case nir_instr_type_load_const:
case nir_instr_type_alu:
case nir_instr_type_deref:
return true;
case nir_instr_type_tex:
return false;
case nir_instr_type_intrinsic:
intr = nir_instr_as_intrinsic(instr);
if (!nir_intrinsic_can_reorder(intr))
return false;
if (nir_intrinsic_has_access(intr))
return nir_intrinsic_access(intr) & ACCESS_CAN_SPECULATE;
/* Intrinsics without ACCESS are speculatable if they can be reordered. */
return true;
case nir_instr_type_call:
case nir_instr_type_jump:
case nir_instr_type_phi:
case nir_instr_type_parallel_copy:
return false;
}
return false;
}
nir_src *
nir_get_shader_call_payload_src(nir_intrinsic_instr *call)
{

View file

@ -2121,7 +2121,7 @@ void nir_rewrite_image_intrinsic(nir_intrinsic_instr *instr,
/* Determine if an intrinsic can be arbitrarily reordered and eliminated. */
bool nir_intrinsic_can_reorder(nir_intrinsic_instr *instr);
bool nir_instr_can_speculate(nir_instr *instr);
bool nir_intrinsic_writes_external_memory(const nir_intrinsic_instr *instr);
static inline bool

View file

@ -102,18 +102,10 @@ typedef struct {
static bool
instr_can_speculate(nir_instr *instr)
{
/* Intrinsics with an ACCESS index can only be speculated if they are
* explicitly CAN_SPECULATE.
*/
if (instr->type == nir_instr_type_intrinsic) {
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
if (instr->type == nir_instr_type_phi)
return true;
if (nir_intrinsic_has_access(intr))
return nir_intrinsic_access(intr) & ACCESS_CAN_SPECULATE;
}
/* For now, everything else can be speculated. TODO: Bindless textures. */
return true;
return nir_instr_can_speculate(instr);
}
static float