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:
committed by
Marge Bot
parent
d4ec0fc381
commit
0727b7a079
@@ -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,
|
||||
|
||||
@@ -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, ©->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);
|
||||
|
||||
@@ -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])
|
||||
|
||||
Reference in New Issue
Block a user