diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index a5e0733e342..747f07af533 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -1017,85 +1017,6 @@ nir_index_local_regs(nir_function_impl *impl) impl->reg_alloc = index; } -static bool -visit_alu_dest(nir_alu_instr *instr, nir_foreach_dest_cb cb, void *state) -{ - return cb(&instr->dest.dest, state); -} - -static bool -visit_deref_dest(nir_deref_instr *instr, nir_foreach_dest_cb cb, void *state) -{ - return cb(&instr->dest, state); -} - -static bool -visit_intrinsic_dest(nir_intrinsic_instr *instr, nir_foreach_dest_cb cb, - void *state) -{ - if (nir_intrinsic_infos[instr->intrinsic].has_dest) - return cb(&instr->dest, state); - - return true; -} - -static bool -visit_texture_dest(nir_tex_instr *instr, nir_foreach_dest_cb cb, - void *state) -{ - return cb(&instr->dest, state); -} - -static bool -visit_phi_dest(nir_phi_instr *instr, nir_foreach_dest_cb cb, void *state) -{ - return cb(&instr->dest, state); -} - -static bool -visit_parallel_copy_dest(nir_parallel_copy_instr *instr, - nir_foreach_dest_cb cb, void *state) -{ - nir_foreach_parallel_copy_entry(entry, instr) { - if (!cb(&entry->dest, state)) - return false; - } - - return true; -} - -bool -nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state) -{ - switch (instr->type) { - case nir_instr_type_alu: - return visit_alu_dest(nir_instr_as_alu(instr), cb, state); - case nir_instr_type_deref: - return visit_deref_dest(nir_instr_as_deref(instr), cb, state); - case nir_instr_type_intrinsic: - return visit_intrinsic_dest(nir_instr_as_intrinsic(instr), cb, state); - case nir_instr_type_tex: - return visit_texture_dest(nir_instr_as_tex(instr), cb, state); - case nir_instr_type_phi: - return visit_phi_dest(nir_instr_as_phi(instr), cb, state); - case nir_instr_type_parallel_copy: - return visit_parallel_copy_dest(nir_instr_as_parallel_copy(instr), - cb, state); - - case nir_instr_type_load_const: - case nir_instr_type_ssa_undef: - case nir_instr_type_call: - case nir_instr_type_jump: - break; - - default: - unreachable("Invalid instruction type"); - break; - } - - return true; -} - struct foreach_ssa_def_state { nir_foreach_ssa_def_cb cb; void *client_state; @@ -1185,179 +1106,6 @@ nir_instr_ssa_def(nir_instr *instr) unreachable("Invalid instruction type"); } -static bool -visit_src(nir_src *src, nir_foreach_src_cb cb, void *state) -{ - if (!cb(src, state)) - return false; - if (!src->is_ssa && src->reg.indirect) - return cb(src->reg.indirect, state); - return true; -} - -static bool -visit_alu_src(nir_alu_instr *instr, nir_foreach_src_cb cb, void *state) -{ - for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) - if (!visit_src(&instr->src[i].src, cb, state)) - return false; - - return true; -} - -static bool -visit_deref_instr_src(nir_deref_instr *instr, - nir_foreach_src_cb cb, void *state) -{ - if (instr->deref_type != nir_deref_type_var) { - if (!visit_src(&instr->parent, cb, state)) - return false; - } - - if (instr->deref_type == nir_deref_type_array || - instr->deref_type == nir_deref_type_ptr_as_array) { - if (!visit_src(&instr->arr.index, cb, state)) - return false; - } - - return true; -} - -static bool -visit_tex_src(nir_tex_instr *instr, nir_foreach_src_cb cb, void *state) -{ - for (unsigned i = 0; i < instr->num_srcs; i++) { - if (!visit_src(&instr->src[i].src, cb, state)) - return false; - } - - return true; -} - -static bool -visit_intrinsic_src(nir_intrinsic_instr *instr, nir_foreach_src_cb cb, - void *state) -{ - unsigned num_srcs = nir_intrinsic_infos[instr->intrinsic].num_srcs; - for (unsigned i = 0; i < num_srcs; i++) { - if (!visit_src(&instr->src[i], cb, state)) - return false; - } - - return true; -} - -static bool -visit_call_src(nir_call_instr *instr, nir_foreach_src_cb cb, void *state) -{ - for (unsigned i = 0; i < instr->num_params; i++) { - if (!visit_src(&instr->params[i], cb, state)) - return false; - } - - return true; -} - -static bool -visit_phi_src(nir_phi_instr *instr, nir_foreach_src_cb cb, void *state) -{ - nir_foreach_phi_src(src, instr) { - if (!visit_src(&src->src, cb, state)) - return false; - } - - return true; -} - -static bool -visit_parallel_copy_src(nir_parallel_copy_instr *instr, - nir_foreach_src_cb cb, void *state) -{ - nir_foreach_parallel_copy_entry(entry, instr) { - if (!visit_src(&entry->src, cb, state)) - return false; - } - - return true; -} - -static bool -visit_jump_src(nir_jump_instr *instr, nir_foreach_src_cb cb, void *state) -{ - if (instr->type != nir_jump_goto_if) - return true; - - return visit_src(&instr->condition, cb, state); -} - -typedef struct { - void *state; - nir_foreach_src_cb cb; -} visit_dest_indirect_state; - -static bool -visit_dest_indirect(nir_dest *dest, void *_state) -{ - visit_dest_indirect_state *state = (visit_dest_indirect_state *) _state; - - if (!dest->is_ssa && dest->reg.indirect) - return state->cb(dest->reg.indirect, state->state); - - return true; -} - -bool -nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state) -{ - switch (instr->type) { - case nir_instr_type_alu: - if (!visit_alu_src(nir_instr_as_alu(instr), cb, state)) - return false; - break; - case nir_instr_type_deref: - if (!visit_deref_instr_src(nir_instr_as_deref(instr), cb, state)) - return false; - break; - case nir_instr_type_intrinsic: - if (!visit_intrinsic_src(nir_instr_as_intrinsic(instr), cb, state)) - return false; - break; - case nir_instr_type_tex: - if (!visit_tex_src(nir_instr_as_tex(instr), cb, state)) - return false; - break; - case nir_instr_type_call: - if (!visit_call_src(nir_instr_as_call(instr), cb, state)) - return false; - break; - case nir_instr_type_load_const: - /* Constant load instructions have no regular sources */ - break; - case nir_instr_type_phi: - if (!visit_phi_src(nir_instr_as_phi(instr), cb, state)) - return false; - break; - case nir_instr_type_parallel_copy: - if (!visit_parallel_copy_src(nir_instr_as_parallel_copy(instr), - cb, state)) - return false; - break; - case nir_instr_type_jump: - return visit_jump_src(nir_instr_as_jump(instr), cb, state); - case nir_instr_type_ssa_undef: - return true; - - default: - unreachable("Invalid instruction type"); - break; - } - - visit_dest_indirect_state dest_state; - dest_state.state = state; - dest_state.cb = cb; - return nir_foreach_dest(instr, visit_dest_indirect, &dest_state); -} - bool nir_foreach_phi_src_leaving_block(nir_block *block, nir_foreach_src_cb cb, diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index bb64fad5bfd..7ce848406c6 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -3865,8 +3865,8 @@ typedef bool (*nir_foreach_dest_cb)(nir_dest *dest, void *state); typedef bool (*nir_foreach_src_cb)(nir_src *src, void *state); bool nir_foreach_ssa_def(nir_instr *instr, nir_foreach_ssa_def_cb cb, void *state); -bool nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state); -bool nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state); +static inline bool nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state); +static inline bool nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state); bool nir_foreach_phi_src_leaving_block(nir_block *instr, nir_foreach_src_cb cb, void *state); @@ -5170,6 +5170,8 @@ nir_addition_might_overflow(nir_shader *shader, struct hash_table *range_ht, nir_ssa_scalar ssa, unsigned const_val, const nir_unsigned_upper_bound_config *config); +#include "nir_inline_helpers.h" + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/compiler/nir/nir_inline_helpers.h b/src/compiler/nir/nir_inline_helpers.h new file mode 100644 index 00000000000..1698e06271e --- /dev/null +++ b/src/compiler/nir/nir_inline_helpers.h @@ -0,0 +1,155 @@ +static inline bool +nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state) +{ + switch (instr->type) { + case nir_instr_type_alu: + return cb(&nir_instr_as_alu(instr)->dest.dest, state); + case nir_instr_type_deref: + return cb(&nir_instr_as_deref(instr)->dest, state); + case nir_instr_type_intrinsic: { + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); + if (nir_intrinsic_infos[intrin->intrinsic].has_dest) + return cb(&intrin->dest, state); + return true; + } + case nir_instr_type_tex: + return cb(&nir_instr_as_tex(instr)->dest, state); + case nir_instr_type_phi: + return cb(&nir_instr_as_phi(instr)->dest, state); + case nir_instr_type_parallel_copy: { + nir_foreach_parallel_copy_entry(entry, nir_instr_as_parallel_copy(instr)) { + if (!cb(&entry->dest, state)) + return false; + } + return true; + } + + case nir_instr_type_load_const: + case nir_instr_type_ssa_undef: + case nir_instr_type_call: + case nir_instr_type_jump: + break; + + default: + unreachable("Invalid instruction type"); + break; + } + + return true; +} + +static ALWAYS_INLINE bool +_nir_visit_src(nir_src *src, nir_foreach_src_cb cb, void *state) +{ + if (!cb(src, state)) + return false; + if (!src->is_ssa && src->reg.indirect) + return cb(src->reg.indirect, state); + return true; +} + +typedef struct { + void *state; + nir_foreach_src_cb cb; +} _nir_visit_dest_indirect_state; + +static ALWAYS_INLINE bool +_nir_visit_dest_indirect(nir_dest *dest, void *_state) +{ + _nir_visit_dest_indirect_state *state = (_nir_visit_dest_indirect_state *) _state; + + if (!dest->is_ssa && dest->reg.indirect) + return state->cb(dest->reg.indirect, state->state); + + return true; +} + +static inline bool +nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state) +{ + switch (instr->type) { + case nir_instr_type_alu: { + nir_alu_instr *alu = nir_instr_as_alu(instr); + for (unsigned i = 0; i < nir_op_infos[alu->op].num_inputs; i++) + if (!_nir_visit_src(&alu->src[i].src, cb, state)) + return false; + break; + } + case nir_instr_type_deref: { + nir_deref_instr *deref = nir_instr_as_deref(instr); + + if (deref->deref_type != nir_deref_type_var) { + if (!_nir_visit_src(&deref->parent, cb, state)) + return false; + } + + if (deref->deref_type == nir_deref_type_array || + deref->deref_type == nir_deref_type_ptr_as_array) { + if (!_nir_visit_src(&deref->arr.index, cb, state)) + return false; + } + break; + } + case nir_instr_type_intrinsic: { + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); + unsigned num_srcs = nir_intrinsic_infos[intrin->intrinsic].num_srcs; + for (unsigned i = 0; i < num_srcs; i++) { + if (!_nir_visit_src(&intrin->src[i], cb, state)) + return false; + } + break; + } + case nir_instr_type_tex: { + nir_tex_instr *tex = nir_instr_as_tex(instr); + for (unsigned i = 0; i < tex->num_srcs; i++) { + if (!_nir_visit_src(&tex->src[i].src, cb, state)) + return false; + } + break; + } + case nir_instr_type_call: { + nir_call_instr *call = nir_instr_as_call(instr); + for (unsigned i = 0; i < call->num_params; i++) { + if (!_nir_visit_src(&call->params[i], cb, state)) + return false; + } + break; + } + case nir_instr_type_phi: { + nir_phi_instr *phi = nir_instr_as_phi(instr); + nir_foreach_phi_src(src, phi) { + if (!_nir_visit_src(&src->src, cb, state)) + return false; + } + break; + } + case nir_instr_type_parallel_copy: { + nir_parallel_copy_instr *pc = nir_instr_as_parallel_copy(instr); + nir_foreach_parallel_copy_entry(entry, pc) { + if (!_nir_visit_src(&entry->src, cb, state)) + return false; + } + break; + } + case nir_instr_type_jump: { + nir_jump_instr *jump = nir_instr_as_jump(instr); + + if (jump->type == nir_jump_goto_if && !_nir_visit_src(&jump->condition, cb, state)) + return false; + return true; + } + + case nir_instr_type_load_const: + case nir_instr_type_ssa_undef: + return true; + + default: + unreachable("Invalid instruction type"); + break; + } + + _nir_visit_dest_indirect_state dest_state; + dest_state.state = state; + dest_state.cb = cb; + return nir_foreach_dest(instr, _nir_visit_dest_indirect, &dest_state); +}