nir: introduce bindgen_return

with vtn_bindgen2, we'll want return values without derefs. this needs some
special handholding.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33099>
This commit is contained in:
Alyssa Rosenzweig
2025-01-17 10:55:42 -05:00
committed by Marge Bot
parent d4ec0fc381
commit 0727b7a079
3 changed files with 26 additions and 12 deletions
+4 -4
View File
@@ -5581,10 +5581,10 @@ bool nir_split_struct_vars(nir_shader *shader, nir_variable_mode modes);
bool nir_lower_returns_impl(nir_function_impl *impl);
bool nir_lower_returns(nir_shader *shader);
void nir_inline_function_impl(struct nir_builder *b,
const nir_function_impl *impl,
nir_def **params,
struct hash_table *shader_var_remap);
nir_def *nir_inline_function_impl(struct nir_builder *b,
const nir_function_impl *impl,
nir_def **params,
struct hash_table *shader_var_remap);
bool nir_inline_functions(nir_shader *shader);
void nir_cleanup_functions(nir_shader *shader);
bool nir_link_shader_functions(nir_shader *shader,
+18 -8
View File
@@ -96,7 +96,7 @@ fixup_cast_deref_mode(nir_deref_instr *deref)
}
}
void
nir_def *
nir_inline_function_impl(struct nir_builder *b,
const nir_function_impl *impl,
nir_def **params,
@@ -106,6 +106,11 @@ nir_inline_function_impl(struct nir_builder *b,
exec_list_append(&b->impl->locals, &copy->locals);
/* Normally, NIR function returns are deref based, but for bindgen, we use a
* sideband here to let us lower derefs ahead-of-time.
*/
nir_def *ret_val = NULL;
nir_foreach_block(block, copy) {
nir_foreach_instr_safe(instr, block) {
switch (instr->type) {
@@ -152,13 +157,16 @@ nir_inline_function_impl(struct nir_builder *b,
}
case nir_instr_type_intrinsic: {
nir_intrinsic_instr *load = nir_instr_as_intrinsic(instr);
if (load->intrinsic != nir_intrinsic_load_param)
break;
unsigned param_idx = nir_intrinsic_param_idx(load);
assert(param_idx < impl->function->num_params);
nir_def_replace(&load->def, params[param_idx]);
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
if (intr->intrinsic == nir_intrinsic_bindgen_return) {
assert(ret_val == NULL && "expected exactly one return write");
ret_val = intr->src[0].ssa;
nir_instr_remove(&intr->instr);
} else if (intr->intrinsic == nir_intrinsic_load_param) {
unsigned param_idx = nir_intrinsic_param_idx(intr);
assert(param_idx < impl->function->num_params);
nir_def_replace(&intr->def, params[param_idx]);
}
break;
}
@@ -191,6 +199,8 @@ nir_inline_function_impl(struct nir_builder *b,
nir_cf_reinsert(&body, nir_before_instr(&nop->instr));
b->cursor = nir_instr_remove(&nop->instr);
}
return ret_val;
}
static bool inline_function_impl(nir_function_impl *impl, struct set *inlined);
+4
View File
@@ -340,6 +340,10 @@ intrinsic("convert_alu_types", dest_comp=0, src_comp=[0],
intrinsic("load_param", dest_comp=0, indices=[PARAM_IDX], flags=[CAN_ELIMINATE])
# Store a scalar value to be used as a return value. Usually store_deref is used
# for this, but vtn_bindgen needs to lower derefs.
intrinsic("bindgen_return", src_comp=[0])
intrinsic("load_deref", dest_comp=0, src_comp=[-1],
indices=[ACCESS], flags=[CAN_ELIMINATE])
intrinsic("store_deref", src_comp=[-1, 0], indices=[WRITE_MASK, ACCESS])