summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2014-12-15 15:12:59 -0800
committerJason Ekstrand <[email protected]>2015-01-15 07:20:22 -0800
commit193fea9eb6a7ad72360a3ac65b322bab081f9587 (patch)
treeecad1e92bda6a4ff6cf91aad7ece7ca99d172715
parentbc0735857f1f36eede7e8e5382f8e9bbc496fecb (diff)
nir: Add a foreach_ssa_def function
There are some functions whose destinations are SSA-only and so aren't a nir_dest. This provides a function that is capable of iterating over the SSA definitions defined by those functions. If you want registers, you should use the old iterator. v2: Kenneth Graunke <[email protected]>: - Fix nir_foreach_ssa_def's return value. Reviewed-by: Connor Abbott <[email protected]>
-rw-r--r--src/glsl/nir/nir.c40
-rw-r--r--src/glsl/nir/nir.h3
2 files changed, 43 insertions, 0 deletions
diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c
index bbf1a865706..1c9643c67c1 100644
--- a/src/glsl/nir/nir.c
+++ b/src/glsl/nir/nir.c
@@ -1465,6 +1465,46 @@ nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state)
return true;
}
+struct foreach_ssa_def_state {
+ nir_foreach_ssa_def_cb cb;
+ void *client_state;
+};
+
+static inline bool
+nir_ssa_def_visitor(nir_dest *dest, void *void_state)
+{
+ struct foreach_ssa_def_state *state = void_state;
+
+ if (dest->is_ssa)
+ return state->cb(&dest->ssa, state->client_state);
+ else
+ return true;
+}
+
+bool
+nir_foreach_ssa_def(nir_instr *instr, nir_foreach_ssa_def_cb cb, void *state)
+{
+ switch (instr->type) {
+ case nir_instr_type_alu:
+ case nir_instr_type_tex:
+ case nir_instr_type_intrinsic:
+ case nir_instr_type_load_const:
+ case nir_instr_type_phi:
+ case nir_instr_type_parallel_copy: {
+ struct foreach_ssa_def_state foreach_state = {cb, state};
+ return nir_foreach_dest(instr, nir_ssa_def_visitor, &foreach_state);
+ }
+
+ case nir_instr_type_ssa_undef:
+ return cb(&nir_instr_as_ssa_undef(instr)->def, state);
+ case nir_instr_type_call:
+ case nir_instr_type_jump:
+ return true;
+ default:
+ unreachable("Invalid instruction type");
+ }
+}
+
static bool
visit_src(nir_src *src, nir_foreach_src_cb cb, void *state)
{
diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h
index 8887c5815e7..301e58fcc3d 100644
--- a/src/glsl/nir/nir.h
+++ b/src/glsl/nir/nir.h
@@ -1316,8 +1316,11 @@ void nir_instr_insert_after_cf_list(struct exec_list *list, nir_instr *after);
void nir_instr_remove(nir_instr *instr);
+typedef bool (*nir_foreach_ssa_def_cb)(nir_ssa_def *def, void *state);
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);