microsoft/compiler: Move kill-unused/undefined varying pass from spirv to common

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28535>
This commit is contained in:
Jesse Natalie
2024-03-31 20:46:27 -07:00
committed by Marge Bot
parent b6b5514a5b
commit 230bed221e
3 changed files with 142 additions and 139 deletions
+137
View File
@@ -2842,3 +2842,140 @@ dxil_nir_lower_coherent_loads_and_stores(nir_shader *s)
nir_metadata_block_index | nir_metadata_dominance | nir_metadata_loop_analysis,
NULL);
}
static bool
kill_undefined_varyings(struct nir_builder *b,
nir_instr *instr,
void *data)
{
const nir_shader *prev_stage_nir = data;
if (instr->type != nir_instr_type_intrinsic)
return false;
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
if (intr->intrinsic != nir_intrinsic_load_deref)
return false;
nir_variable *var = nir_intrinsic_get_var(intr, 0);
if (!var || var->data.mode != nir_var_shader_in)
return false;
/* Ignore most builtins for now, some of them get default values
* when not written from previous stages.
*/
if (var->data.location < VARYING_SLOT_VAR0 &&
var->data.location != VARYING_SLOT_POS)
return false;
uint32_t loc = var->data.patch ?
var->data.location - VARYING_SLOT_PATCH0 : var->data.location;
uint64_t written = var->data.patch ?
prev_stage_nir->info.patch_outputs_written :
prev_stage_nir->info.outputs_written;
if (BITFIELD64_RANGE(loc, glsl_varying_count(var->type)) & written)
return false;
b->cursor = nir_after_instr(instr);
/* Note: zero is used instead of undef, because optimization is not run here, but is
* run later on. If we load an undef here, and that undef ends up being used to store
* to position later on, that can cause some or all of the components in that position
* write to be removed, which is problematic especially in the case of all components,
* since that would remove the store instruction, and would make it tricky to satisfy
* the DXIL requirements of writing all position components.
*/
nir_def *zero = nir_imm_zero(b, intr->def.num_components,
intr->def.bit_size);
nir_def_rewrite_uses(&intr->def, zero);
nir_instr_remove(instr);
return true;
}
bool
dxil_nir_kill_undefined_varyings(nir_shader *shader,
const nir_shader *prev_stage_shader)
{
if (!nir_shader_instructions_pass(shader,
kill_undefined_varyings,
nir_metadata_dominance |
nir_metadata_block_index |
nir_metadata_loop_analysis,
(void *)prev_stage_shader))
return false;
nir_remove_dead_derefs(shader);
nir_remove_dead_variables(shader, nir_var_shader_in, NULL);
return true;
}
static bool
kill_unused_outputs(struct nir_builder *b,
nir_instr *instr,
void *data)
{
uint64_t kill_mask = *((uint64_t *)data);
if (instr->type != nir_instr_type_intrinsic)
return false;
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
if (intr->intrinsic != nir_intrinsic_store_deref)
return false;
nir_variable *var = nir_intrinsic_get_var(intr, 0);
if (!var || var->data.mode != nir_var_shader_out)
return false;
unsigned loc = var->data.patch ?
var->data.location - VARYING_SLOT_PATCH0 :
var->data.location;
if (!(BITFIELD64_RANGE(loc, glsl_varying_count(var->type)) & kill_mask))
return false;
nir_instr_remove(instr);
return true;
}
bool
dxil_nir_kill_unused_outputs(nir_shader *shader,
const nir_shader *next_stage_shader)
{
uint64_t kill_var_mask =
shader->info.outputs_written & ~next_stage_shader->info.inputs_read;
bool progress = false;
/* Don't kill buitin vars */
kill_var_mask &= BITFIELD64_MASK(MAX_VARYING) << VARYING_SLOT_VAR0;
if (nir_shader_instructions_pass(shader,
kill_unused_outputs,
nir_metadata_dominance |
nir_metadata_block_index |
nir_metadata_loop_analysis,
(void *)&kill_var_mask))
progress = true;
if (shader->info.stage == MESA_SHADER_TESS_CTRL) {
kill_var_mask =
(shader->info.patch_outputs_written |
shader->info.patch_outputs_read) &
~next_stage_shader->info.patch_inputs_read;
if (nir_shader_instructions_pass(shader,
kill_unused_outputs,
nir_metadata_dominance |
nir_metadata_block_index |
nir_metadata_loop_analysis,
(void *)&kill_var_mask))
progress = true;
}
if (progress) {
nir_opt_dce(shader);
nir_remove_dead_derefs(shader);
nir_remove_dead_variables(shader, nir_var_shader_out, NULL);
}
return progress;
}
+3
View File
@@ -89,6 +89,9 @@ bool dxil_nir_analyze_io_dependencies(struct dxil_module *mod, nir_shader *s);
bool dxil_nir_guess_image_formats(nir_shader *s);
bool dxil_nir_lower_coherent_loads_and_stores(nir_shader *s);
bool dxil_nir_kill_undefined_varyings(nir_shader *shader, const nir_shader *prev_stage_shader);
bool dxil_nir_kill_unused_outputs(nir_shader *shader, const nir_shader *next_stage_shader);
#ifdef __cplusplus
}
#endif
+2 -139
View File
@@ -551,143 +551,6 @@ dxil_spirv_nir_discard_point_size_var(nir_shader *shader)
return true;
}
static bool
kill_undefined_varyings(struct nir_builder *b,
nir_instr *instr,
void *data)
{
const nir_shader *prev_stage_nir = data;
if (instr->type != nir_instr_type_intrinsic)
return false;
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
if (intr->intrinsic != nir_intrinsic_load_deref)
return false;
nir_variable *var = nir_intrinsic_get_var(intr, 0);
if (!var || var->data.mode != nir_var_shader_in)
return false;
/* Ignore most builtins for now, some of them get default values
* when not written from previous stages.
*/
if (var->data.location < VARYING_SLOT_VAR0 &&
var->data.location != VARYING_SLOT_POS)
return false;
uint32_t loc = var->data.patch ?
var->data.location - VARYING_SLOT_PATCH0 : var->data.location;
uint64_t written = var->data.patch ?
prev_stage_nir->info.patch_outputs_written :
prev_stage_nir->info.outputs_written;
if (BITFIELD64_RANGE(loc, glsl_varying_count(var->type)) & written)
return false;
b->cursor = nir_after_instr(instr);
/* Note: zero is used instead of undef, because optimization is not run here, but is
* run later on. If we load an undef here, and that undef ends up being used to store
* to position later on, that can cause some or all of the components in that position
* write to be removed, which is problematic especially in the case of all components,
* since that would remove the store instruction, and would make it tricky to satisfy
* the DXIL requirements of writing all position components.
*/
nir_def *zero = nir_imm_zero(b, intr->def.num_components,
intr->def.bit_size);
nir_def_rewrite_uses(&intr->def, zero);
nir_instr_remove(instr);
return true;
}
static bool
dxil_spirv_nir_kill_undefined_varyings(nir_shader *shader,
const nir_shader *prev_stage_shader)
{
if (!nir_shader_instructions_pass(shader,
kill_undefined_varyings,
nir_metadata_dominance |
nir_metadata_block_index |
nir_metadata_loop_analysis,
(void *)prev_stage_shader))
return false;
nir_remove_dead_derefs(shader);
nir_remove_dead_variables(shader, nir_var_shader_in, NULL);
return true;
}
static bool
kill_unused_outputs(struct nir_builder *b,
nir_instr *instr,
void *data)
{
uint64_t kill_mask = *((uint64_t *)data);
if (instr->type != nir_instr_type_intrinsic)
return false;
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
if (intr->intrinsic != nir_intrinsic_store_deref)
return false;
nir_variable *var = nir_intrinsic_get_var(intr, 0);
if (!var || var->data.mode != nir_var_shader_out)
return false;
unsigned loc = var->data.patch ?
var->data.location - VARYING_SLOT_PATCH0 :
var->data.location;
if (!(BITFIELD64_RANGE(loc, glsl_varying_count(var->type)) & kill_mask))
return false;
nir_instr_remove(instr);
return true;
}
static bool
dxil_spirv_nir_kill_unused_outputs(nir_shader *shader,
nir_shader *next_stage_shader)
{
uint64_t kill_var_mask =
shader->info.outputs_written & ~next_stage_shader->info.inputs_read;
bool progress = false;
/* Don't kill buitin vars */
kill_var_mask &= BITFIELD64_MASK(MAX_VARYING) << VARYING_SLOT_VAR0;
if (nir_shader_instructions_pass(shader,
kill_unused_outputs,
nir_metadata_dominance |
nir_metadata_block_index |
nir_metadata_loop_analysis,
(void *)&kill_var_mask))
progress = true;
if (shader->info.stage == MESA_SHADER_TESS_CTRL) {
kill_var_mask =
(shader->info.patch_outputs_written |
shader->info.patch_outputs_read) &
~next_stage_shader->info.patch_inputs_read;
if (nir_shader_instructions_pass(shader,
kill_unused_outputs,
nir_metadata_dominance |
nir_metadata_block_index |
nir_metadata_loop_analysis,
(void *)&kill_var_mask))
progress = true;
}
if (progress) {
nir_opt_dce(shader);
nir_remove_dead_derefs(shader);
nir_remove_dead_variables(shader, nir_var_shader_out, NULL);
}
return progress;
}
struct lower_pntc_data {
const struct dxil_spirv_runtime_conf *conf;
nir_variable *pntc;
@@ -906,8 +769,8 @@ dxil_spirv_nir_link(nir_shader *nir, nir_shader *prev_stage_nir,
}
}
NIR_PASS_V(nir, dxil_spirv_nir_kill_undefined_varyings, prev_stage_nir);
NIR_PASS_V(prev_stage_nir, dxil_spirv_nir_kill_unused_outputs, nir);
NIR_PASS_V(nir, dxil_nir_kill_undefined_varyings, prev_stage_nir);
NIR_PASS_V(prev_stage_nir, dxil_nir_kill_unused_outputs, nir);
nir->info.inputs_read =
dxil_reassign_driver_locations(nir, nir_var_shader_in,