--- 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev