17ec681f3Smrg/* _nir_foreach_dest() needs to be ALWAYS_INLINE so that it can inline the
27ec681f3Smrg * callback if it was declared with ALWAYS_INLINE.
37ec681f3Smrg */
47ec681f3Smrgstatic ALWAYS_INLINE bool
57ec681f3Smrg_nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state)
67ec681f3Smrg{
77ec681f3Smrg   switch (instr->type) {
87ec681f3Smrg   case nir_instr_type_alu:
97ec681f3Smrg      return cb(&nir_instr_as_alu(instr)->dest.dest, state);
107ec681f3Smrg   case nir_instr_type_deref:
117ec681f3Smrg      return cb(&nir_instr_as_deref(instr)->dest, state);
127ec681f3Smrg   case nir_instr_type_intrinsic: {
137ec681f3Smrg      nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
147ec681f3Smrg      if (nir_intrinsic_infos[intrin->intrinsic].has_dest)
157ec681f3Smrg         return cb(&intrin->dest, state);
167ec681f3Smrg      return true;
177ec681f3Smrg   }
187ec681f3Smrg   case nir_instr_type_tex:
197ec681f3Smrg      return cb(&nir_instr_as_tex(instr)->dest, state);
207ec681f3Smrg   case nir_instr_type_phi:
217ec681f3Smrg      return cb(&nir_instr_as_phi(instr)->dest, state);
227ec681f3Smrg   case nir_instr_type_parallel_copy: {
237ec681f3Smrg      nir_foreach_parallel_copy_entry(entry, nir_instr_as_parallel_copy(instr)) {
247ec681f3Smrg         if (!cb(&entry->dest, state))
257ec681f3Smrg            return false;
267ec681f3Smrg      }
277ec681f3Smrg      return true;
287ec681f3Smrg   }
297ec681f3Smrg
307ec681f3Smrg   case nir_instr_type_load_const:
317ec681f3Smrg   case nir_instr_type_ssa_undef:
327ec681f3Smrg   case nir_instr_type_call:
337ec681f3Smrg   case nir_instr_type_jump:
347ec681f3Smrg      break;
357ec681f3Smrg
367ec681f3Smrg   default:
377ec681f3Smrg      unreachable("Invalid instruction type");
387ec681f3Smrg      break;
397ec681f3Smrg   }
407ec681f3Smrg
417ec681f3Smrg   return true;
427ec681f3Smrg}
437ec681f3Smrg
447ec681f3Smrgstatic ALWAYS_INLINE bool
457ec681f3Smrg_nir_visit_src(nir_src *src, nir_foreach_src_cb cb, void *state)
467ec681f3Smrg{
477ec681f3Smrg   if (!cb(src, state))
487ec681f3Smrg      return false;
497ec681f3Smrg   if (!src->is_ssa && src->reg.indirect)
507ec681f3Smrg      return cb(src->reg.indirect, state);
517ec681f3Smrg   return true;
527ec681f3Smrg}
537ec681f3Smrg
547ec681f3Smrgtypedef struct {
557ec681f3Smrg   void *state;
567ec681f3Smrg   nir_foreach_src_cb cb;
577ec681f3Smrg} _nir_visit_dest_indirect_state;
587ec681f3Smrg
597ec681f3Smrgstatic ALWAYS_INLINE bool
607ec681f3Smrg_nir_visit_dest_indirect(nir_dest *dest, void *_state)
617ec681f3Smrg{
627ec681f3Smrg   _nir_visit_dest_indirect_state *state = (_nir_visit_dest_indirect_state *) _state;
637ec681f3Smrg
647ec681f3Smrg   if (!dest->is_ssa && dest->reg.indirect)
657ec681f3Smrg      return state->cb(dest->reg.indirect, state->state);
667ec681f3Smrg
677ec681f3Smrg   return true;
687ec681f3Smrg}
697ec681f3Smrg
707ec681f3Smrgstatic inline bool
717ec681f3Smrgnir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state)
727ec681f3Smrg{
737ec681f3Smrg   return _nir_foreach_dest(instr, cb, state);
747ec681f3Smrg}
757ec681f3Smrg
767ec681f3Smrgstatic inline bool
777ec681f3Smrgnir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state)
787ec681f3Smrg{
797ec681f3Smrg   switch (instr->type) {
807ec681f3Smrg   case nir_instr_type_alu: {
817ec681f3Smrg      nir_alu_instr *alu = nir_instr_as_alu(instr);
827ec681f3Smrg      for (unsigned i = 0; i < nir_op_infos[alu->op].num_inputs; i++)
837ec681f3Smrg         if (!_nir_visit_src(&alu->src[i].src, cb, state))
847ec681f3Smrg            return false;
857ec681f3Smrg      break;
867ec681f3Smrg   }
877ec681f3Smrg   case nir_instr_type_deref: {
887ec681f3Smrg      nir_deref_instr *deref = nir_instr_as_deref(instr);
897ec681f3Smrg
907ec681f3Smrg      if (deref->deref_type != nir_deref_type_var) {
917ec681f3Smrg         if (!_nir_visit_src(&deref->parent, cb, state))
927ec681f3Smrg            return false;
937ec681f3Smrg      }
947ec681f3Smrg
957ec681f3Smrg      if (deref->deref_type == nir_deref_type_array ||
967ec681f3Smrg          deref->deref_type == nir_deref_type_ptr_as_array) {
977ec681f3Smrg         if (!_nir_visit_src(&deref->arr.index, cb, state))
987ec681f3Smrg            return false;
997ec681f3Smrg      }
1007ec681f3Smrg      break;
1017ec681f3Smrg   }
1027ec681f3Smrg   case nir_instr_type_intrinsic: {
1037ec681f3Smrg      nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
1047ec681f3Smrg      unsigned num_srcs = nir_intrinsic_infos[intrin->intrinsic].num_srcs;
1057ec681f3Smrg      for (unsigned i = 0; i < num_srcs; i++) {
1067ec681f3Smrg         if (!_nir_visit_src(&intrin->src[i], cb, state))
1077ec681f3Smrg            return false;
1087ec681f3Smrg      }
1097ec681f3Smrg      break;
1107ec681f3Smrg   }
1117ec681f3Smrg   case nir_instr_type_tex: {
1127ec681f3Smrg      nir_tex_instr *tex = nir_instr_as_tex(instr);
1137ec681f3Smrg      for (unsigned i = 0; i < tex->num_srcs; i++) {
1147ec681f3Smrg         if (!_nir_visit_src(&tex->src[i].src, cb, state))
1157ec681f3Smrg            return false;
1167ec681f3Smrg      }
1177ec681f3Smrg      break;
1187ec681f3Smrg   }
1197ec681f3Smrg   case nir_instr_type_call: {
1207ec681f3Smrg      nir_call_instr *call = nir_instr_as_call(instr);
1217ec681f3Smrg      for (unsigned i = 0; i < call->num_params; i++) {
1227ec681f3Smrg         if (!_nir_visit_src(&call->params[i], cb, state))
1237ec681f3Smrg            return false;
1247ec681f3Smrg      }
1257ec681f3Smrg      break;
1267ec681f3Smrg   }
1277ec681f3Smrg   case nir_instr_type_phi: {
1287ec681f3Smrg      nir_phi_instr *phi = nir_instr_as_phi(instr);
1297ec681f3Smrg      nir_foreach_phi_src(src, phi) {
1307ec681f3Smrg         if (!_nir_visit_src(&src->src, cb, state))
1317ec681f3Smrg            return false;
1327ec681f3Smrg      }
1337ec681f3Smrg      break;
1347ec681f3Smrg   }
1357ec681f3Smrg   case nir_instr_type_parallel_copy: {
1367ec681f3Smrg      nir_parallel_copy_instr *pc = nir_instr_as_parallel_copy(instr);
1377ec681f3Smrg      nir_foreach_parallel_copy_entry(entry, pc) {
1387ec681f3Smrg         if (!_nir_visit_src(&entry->src, cb, state))
1397ec681f3Smrg            return false;
1407ec681f3Smrg      }
1417ec681f3Smrg      break;
1427ec681f3Smrg   }
1437ec681f3Smrg   case nir_instr_type_jump: {
1447ec681f3Smrg      nir_jump_instr *jump = nir_instr_as_jump(instr);
1457ec681f3Smrg
1467ec681f3Smrg      if (jump->type == nir_jump_goto_if && !_nir_visit_src(&jump->condition, cb, state))
1477ec681f3Smrg         return false;
1487ec681f3Smrg      return true;
1497ec681f3Smrg   }
1507ec681f3Smrg
1517ec681f3Smrg   case nir_instr_type_load_const:
1527ec681f3Smrg   case nir_instr_type_ssa_undef:
1537ec681f3Smrg      return true;
1547ec681f3Smrg
1557ec681f3Smrg   default:
1567ec681f3Smrg      unreachable("Invalid instruction type");
1577ec681f3Smrg      break;
1587ec681f3Smrg   }
1597ec681f3Smrg
1607ec681f3Smrg   _nir_visit_dest_indirect_state dest_state;
1617ec681f3Smrg   dest_state.state = state;
1627ec681f3Smrg   dest_state.cb = cb;
1637ec681f3Smrg   return _nir_foreach_dest(instr, _nir_visit_dest_indirect, &dest_state);
1647ec681f3Smrg}
165