[Mesa-dev] [PATCH 055/133] nir: Add a parallel copy instruction type
Jason Ekstrand
jason at jlekstrand.net
Mon Dec 15 22:05:05 PST 2014
---
src/glsl/nir/nir.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
src/glsl/nir/nir.h | 23 +++++++++++++++++++++++
src/glsl/nir/nir_print.c | 21 +++++++++++++++++++++
3 files changed, 88 insertions(+), 1 deletion(-)
diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c
index 27e903e..d3fd084 100644
--- a/src/glsl/nir/nir.c
+++ b/src/glsl/nir/nir.c
@@ -475,6 +475,18 @@ nir_phi_instr_create(void *mem_ctx)
return instr;
}
+nir_parallel_copy_instr *
+nir_parallel_copy_instr_create(void *mem_ctx)
+{
+ nir_parallel_copy_instr *instr = ralloc(mem_ctx, nir_parallel_copy_instr);
+ instr_init(&instr->instr, nir_instr_type_parallel_copy);
+
+ instr->at_end = false;
+ exec_list_make_empty(&instr->copies);
+
+ return instr;
+}
+
nir_ssa_undef_instr *
nir_ssa_undef_instr_create(void *mem_ctx)
{
@@ -1377,6 +1389,18 @@ 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)
+{
+ foreach_list_typed(nir_parallel_copy_copy, copy, node, &instr->copies) {
+ if (!cb(©->dest, state))
+ return false;
+ }
+
+ return true;
+}
+
bool
nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state)
{
@@ -1391,7 +1415,9 @@ nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state)
return visit_load_const_dest(nir_instr_as_load_const(instr), cb, state);
case nir_instr_type_phi:
return visit_phi_dest(nir_instr_as_phi(instr), cb, state);
- break;
+ case nir_instr_type_parallel_copy:
+ return visit_parallel_copy_dest(nir_instr_as_parallel_copy(instr),
+ cb, state);
case nir_instr_type_ssa_undef:
case nir_instr_type_call:
@@ -1526,6 +1552,18 @@ visit_phi_src(nir_phi_instr *instr, nir_foreach_src_cb cb, void *state)
return true;
}
+static bool
+visit_parallel_copy_src(nir_parallel_copy_instr *instr,
+ nir_foreach_src_cb cb, void *state)
+{
+ foreach_list_typed(nir_parallel_copy_copy, copy, node, &instr->copies) {
+ if (!visit_src(©->src, cb, state))
+ return false;
+ }
+
+ return true;
+}
+
typedef struct {
void *state;
nir_foreach_src_cb cb;
@@ -1570,6 +1608,11 @@ nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state)
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:
case nir_instr_type_ssa_undef:
return true;
diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h
index 988a135..2ebf826 100644
--- a/src/glsl/nir/nir.h
+++ b/src/glsl/nir/nir.h
@@ -396,6 +396,7 @@ typedef enum {
nir_instr_type_jump,
nir_instr_type_ssa_undef,
nir_instr_type_phi,
+ nir_instr_type_parallel_copy,
} nir_instr_type;
typedef struct {
@@ -933,6 +934,24 @@ typedef struct {
nir_dest dest;
} nir_phi_instr;
+typedef struct {
+ struct exec_node node;
+ nir_src src;
+ nir_dest dest;
+} nir_parallel_copy_copy;
+
+typedef struct {
+ nir_instr instr;
+
+ /* Indicates that this is the parallel copy at the end of the block.
+ * When isolating phi nodes, we create 2 parallel copies in most blocks;
+ * this flag helps tell them apart.
+ */
+ bool at_end;
+
+ struct exec_list copies;
+} nir_parallel_copy_instr;
+
#define nir_instr_as_alu(_instr) exec_node_data(nir_alu_instr, _instr, instr)
#define nir_instr_as_call(_instr) exec_node_data(nir_call_instr, _instr, instr)
#define nir_instr_as_jump(_instr) exec_node_data(nir_jump_instr, _instr, instr)
@@ -946,6 +965,8 @@ typedef struct {
exec_node_data(nir_ssa_undef_instr, _instr, instr)
#define nir_instr_as_phi(_instr) \
exec_node_data(nir_phi_instr, _instr, instr)
+#define nir_instr_as_parallel_copy(_instr) \
+ exec_node_data(nir_parallel_copy_instr, _instr, instr)
/*
@@ -1251,6 +1272,8 @@ nir_tex_instr *nir_tex_instr_create(void *mem_ctx, unsigned num_srcs);
nir_phi_instr *nir_phi_instr_create(void *mem_ctx);
+nir_parallel_copy_instr *nir_parallel_copy_instr_create(void *mem_ctx);
+
nir_ssa_undef_instr *nir_ssa_undef_instr_create(void *mem_ctx);
nir_deref_var *nir_deref_var_create(void *mem_ctx, nir_variable *var);
diff --git a/src/glsl/nir/nir_print.c b/src/glsl/nir/nir_print.c
index 4981110..0140f4e 100644
--- a/src/glsl/nir/nir_print.c
+++ b/src/glsl/nir/nir_print.c
@@ -607,6 +607,23 @@ print_phi_instr(nir_phi_instr *instr, FILE *fp)
}
static void
+print_parallel_copy_instr(nir_parallel_copy_instr *instr, FILE *fp)
+{
+ bool first = true;
+ fprintf(fp, "pcopy: ");
+ foreach_list_typed(nir_parallel_copy_copy, copy, node, &instr->copies) {
+ if (!first)
+ fprintf(fp, "; ");
+
+ print_dest(©->dest, fp);
+ fprintf(fp, " = ");
+ print_src(©->src, fp);
+
+ first = false;
+ }
+}
+
+static void
print_instr(nir_instr *instr, print_var_state *state, unsigned tabs, FILE *fp)
{
print_tabs(tabs, fp);
@@ -644,6 +661,10 @@ print_instr(nir_instr *instr, print_var_state *state, unsigned tabs, FILE *fp)
print_phi_instr(nir_instr_as_phi(instr), fp);
break;
+ case nir_instr_type_parallel_copy:
+ print_parallel_copy_instr(nir_instr_as_parallel_copy(instr), fp);
+ break;
+
default:
unreachable("Invalid instruction type");
break;
--
2.2.0
More information about the mesa-dev
mailing list