nir: inline nir_foreach_{src,dest}

Compile-time (nir_opt_dce):
Difference at 95.0% confidence
	-319.51 +/- 5.67632
	-12.0627% +/- 0.208076%
	(Student's t, pooled s = 6.70399)

Compile-time (overall):
Difference at 95.0% confidence
	-385.025 +/- 42.1124
	-0.929489% +/- 0.10139%
	(Student's t, pooled s = 49.7367)

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Acked-by: Daniel Schürmann <daniel@schuermann.dev>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7691>
This commit is contained in:
Rhys Perry
2021-01-18 14:43:15 +00:00
committed by Marge Bot
parent 325f627d88
commit 336bcbacd0
3 changed files with 159 additions and 254 deletions

View File

@@ -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,

View File

@@ -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

View File

@@ -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);
}