1/* _nir_foreach_dest() needs to be ALWAYS_INLINE so that it can inline the 2 * callback if it was declared with ALWAYS_INLINE. 3 */ 4static ALWAYS_INLINE bool 5_nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state) 6{ 7 switch (instr->type) { 8 case nir_instr_type_alu: 9 return cb(&nir_instr_as_alu(instr)->dest.dest, state); 10 case nir_instr_type_deref: 11 return cb(&nir_instr_as_deref(instr)->dest, state); 12 case nir_instr_type_intrinsic: { 13 nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); 14 if (nir_intrinsic_infos[intrin->intrinsic].has_dest) 15 return cb(&intrin->dest, state); 16 return true; 17 } 18 case nir_instr_type_tex: 19 return cb(&nir_instr_as_tex(instr)->dest, state); 20 case nir_instr_type_phi: 21 return cb(&nir_instr_as_phi(instr)->dest, state); 22 case nir_instr_type_parallel_copy: { 23 nir_foreach_parallel_copy_entry(entry, nir_instr_as_parallel_copy(instr)) { 24 if (!cb(&entry->dest, state)) 25 return false; 26 } 27 return true; 28 } 29 30 case nir_instr_type_load_const: 31 case nir_instr_type_ssa_undef: 32 case nir_instr_type_call: 33 case nir_instr_type_jump: 34 break; 35 36 default: 37 unreachable("Invalid instruction type"); 38 break; 39 } 40 41 return true; 42} 43 44static ALWAYS_INLINE bool 45_nir_visit_src(nir_src *src, nir_foreach_src_cb cb, void *state) 46{ 47 if (!cb(src, state)) 48 return false; 49 if (!src->is_ssa && src->reg.indirect) 50 return cb(src->reg.indirect, state); 51 return true; 52} 53 54typedef struct { 55 void *state; 56 nir_foreach_src_cb cb; 57} _nir_visit_dest_indirect_state; 58 59static ALWAYS_INLINE bool 60_nir_visit_dest_indirect(nir_dest *dest, void *_state) 61{ 62 _nir_visit_dest_indirect_state *state = (_nir_visit_dest_indirect_state *) _state; 63 64 if (!dest->is_ssa && dest->reg.indirect) 65 return state->cb(dest->reg.indirect, state->state); 66 67 return true; 68} 69 70static inline bool 71nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state) 72{ 73 return _nir_foreach_dest(instr, cb, state); 74} 75 76static inline bool 77nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state) 78{ 79 switch (instr->type) { 80 case nir_instr_type_alu: { 81 nir_alu_instr *alu = nir_instr_as_alu(instr); 82 for (unsigned i = 0; i < nir_op_infos[alu->op].num_inputs; i++) 83 if (!_nir_visit_src(&alu->src[i].src, cb, state)) 84 return false; 85 break; 86 } 87 case nir_instr_type_deref: { 88 nir_deref_instr *deref = nir_instr_as_deref(instr); 89 90 if (deref->deref_type != nir_deref_type_var) { 91 if (!_nir_visit_src(&deref->parent, cb, state)) 92 return false; 93 } 94 95 if (deref->deref_type == nir_deref_type_array || 96 deref->deref_type == nir_deref_type_ptr_as_array) { 97 if (!_nir_visit_src(&deref->arr.index, cb, state)) 98 return false; 99 } 100 break; 101 } 102 case nir_instr_type_intrinsic: { 103 nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); 104 unsigned num_srcs = nir_intrinsic_infos[intrin->intrinsic].num_srcs; 105 for (unsigned i = 0; i < num_srcs; i++) { 106 if (!_nir_visit_src(&intrin->src[i], cb, state)) 107 return false; 108 } 109 break; 110 } 111 case nir_instr_type_tex: { 112 nir_tex_instr *tex = nir_instr_as_tex(instr); 113 for (unsigned i = 0; i < tex->num_srcs; i++) { 114 if (!_nir_visit_src(&tex->src[i].src, cb, state)) 115 return false; 116 } 117 break; 118 } 119 case nir_instr_type_call: { 120 nir_call_instr *call = nir_instr_as_call(instr); 121 for (unsigned i = 0; i < call->num_params; i++) { 122 if (!_nir_visit_src(&call->params[i], cb, state)) 123 return false; 124 } 125 break; 126 } 127 case nir_instr_type_phi: { 128 nir_phi_instr *phi = nir_instr_as_phi(instr); 129 nir_foreach_phi_src(src, phi) { 130 if (!_nir_visit_src(&src->src, cb, state)) 131 return false; 132 } 133 break; 134 } 135 case nir_instr_type_parallel_copy: { 136 nir_parallel_copy_instr *pc = nir_instr_as_parallel_copy(instr); 137 nir_foreach_parallel_copy_entry(entry, pc) { 138 if (!_nir_visit_src(&entry->src, cb, state)) 139 return false; 140 } 141 break; 142 } 143 case nir_instr_type_jump: { 144 nir_jump_instr *jump = nir_instr_as_jump(instr); 145 146 if (jump->type == nir_jump_goto_if && !_nir_visit_src(&jump->condition, cb, state)) 147 return false; 148 return true; 149 } 150 151 case nir_instr_type_load_const: 152 case nir_instr_type_ssa_undef: 153 return true; 154 155 default: 156 unreachable("Invalid instruction type"); 157 break; 158 } 159 160 _nir_visit_dest_indirect_state dest_state; 161 dest_state.state = state; 162 dest_state.cb = cb; 163 return _nir_foreach_dest(instr, _nir_visit_dest_indirect, &dest_state); 164} 165