summaryrefslogtreecommitdiff
path: root/src/compiler/glsl/glsl_to_nir.cpp
diff options
context:
space:
mode:
authorTimothy Arceri <tarceri@itsqueeze.com>2024-01-26 15:30:06 +1100
committerMarge Bot <emma+marge@anholt.net>2024-03-12 01:43:03 +0000
commit1391bc372191db10dff97f279631816555192fc6 (patch)
tree980a6bffe7a757b411c0f8d1ddb09afbb179a09c /src/compiler/glsl/glsl_to_nir.cpp
parentf06aed8e1d15cf2f41b8163db07689dee35c9c42 (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.cpp22
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