From 366181d826219b50ae74a5d5db49e885f3bb7c4e Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Thu, 30 Oct 2014 21:04:15 -0700 Subject: [PATCH] nir: Add a parallel copy instruction type Reviewed-by: Connor Abbott --- 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 4100f9770cc..b64ec4073a4 100644 --- a/src/glsl/nir/nir.c +++ b/src/glsl/nir/nir.c @@ -481,6 +481,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) { @@ -1383,6 +1395,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) { @@ -1397,7 +1421,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: @@ -1532,6 +1558,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; @@ -1576,6 +1614,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 5933b5dc447..6c1f6682843 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 6f2a2da43e3..335eaaf180e 100644 --- a/src/glsl/nir/nir_print.c +++ b/src/glsl/nir/nir_print.c @@ -605,6 +605,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) { @@ -643,6 +660,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.30.2