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