diff options
author | Timothy Arceri <tarceri@itsqueeze.com> | 2024-01-26 15:30:06 +1100 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2024-03-12 01:43:03 +0000 |
commit | 1391bc372191db10dff97f279631816555192fc6 (patch) | |
tree | 980a6bffe7a757b411c0f8d1ddb09afbb179a09c /src/compiler/glsl/glsl_to_nir.cpp | |
parent | f06aed8e1d15cf2f41b8163db07689dee35c9c42 (diff) |
glsl_to_nir: never convert instructions after jump
Unlike in GLSL IR it is illegal to add an instruction to a block
following a jump in NIR. Here we add code to the glsl_to_ir pass
to remove any such instructions before they are processed i.e.
we remove them as soon as we process the jumps.
Handling this in glsl to nir allows us to avoid depending on the
lower_jumps() pass being called directly before glsl to nir when
it otherwise doesn't need to be called an additional time.
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27288>
Diffstat (limited to 'src/compiler/glsl/glsl_to_nir.cpp')
-rw-r--r-- | src/compiler/glsl/glsl_to_nir.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp index bcf1f695f7e..68b5bd84045 100644 --- a/src/compiler/glsl/glsl_to_nir.cpp +++ b/src/compiler/glsl/glsl_to_nir.cpp @@ -84,6 +84,7 @@ public: private: void add_instr(nir_instr *instr, unsigned num_components, unsigned bit_size); + void truncate_after_instruction(exec_node *ir); nir_def *evaluate_rvalue(ir_rvalue *ir); nir_alu_instr *emit(nir_op op, unsigned dest_size, nir_def **srcs); @@ -220,6 +221,17 @@ nir_visitor::evaluate_deref(ir_instruction *ir) return this->deref; } +void +nir_visitor::truncate_after_instruction(exec_node *ir) +{ + if (!ir) + return; + + while (!ir->get_next()->is_tail_sentinel()) { + ((ir_instruction *)ir->get_next())->remove(); + } +} + nir_constant * nir_visitor::constant_copy(ir_constant *ir, void *mem_ctx) { @@ -766,6 +778,11 @@ nir_visitor::visit(ir_loop_jump *ir) nir_jump_instr *instr = nir_jump_instr_create(this->shader, type); nir_builder_instr_insert(&b, &instr->instr); + + /* Eliminate all instructions after the jump, since they are unreachable + * and NIR considers adding these instructions illegal. + */ + truncate_after_instruction(ir); } void @@ -785,6 +802,11 @@ nir_visitor::visit(ir_return *ir) nir_jump_instr *instr = nir_jump_instr_create(this->shader, nir_jump_return); nir_builder_instr_insert(&b, &instr->instr); + + /* Eliminate all instructions after the jump, since they are unreachable + * and NIR considers adding these instructions illegal. + */ + truncate_after_instruction(ir); } static void |