From: Nicolai Hähnle <nicolai.haeh...@amd.com>

SimplifyCFG generates a switch instruction anyway when all four streams
are present, but is simultaneously not smart enough to eliminate some
redundant jumps that it generates.

The generated assembly is still a bit silly, probably because the
control flow annotation doesn't know how to handle a switch with uniform
condition.
---
 src/gallium/drivers/radeonsi/si_shader.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c 
b/src/gallium/drivers/radeonsi/si_shader.c
index 6aaf318..0eeff19 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -6256,35 +6256,38 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
        for (i = 0; i < gsinfo->num_outputs; ++i) {
                outputs[i].semantic_name = gsinfo->output_semantic_name[i];
                outputs[i].semantic_index = gsinfo->output_semantic_index[i];
 
                for (int chan = 0; chan < 4; chan++) {
                        outputs[i].vertex_stream[chan] =
                                (gsinfo->output_streams[i] >> (2 * chan)) & 3;
                }
        }
 
+       LLVMBasicBlockRef end_bb;
+       LLVMValueRef switch_inst;
+
+       end_bb = LLVMAppendBasicBlockInContext(gallivm->context, ctx.main_fn, 
"end");
+       switch_inst = LLVMBuildSwitch(builder, stream_id, end_bb, 4);
+
        for (int stream = 0; stream < 4; stream++) {
-               struct lp_build_if_state if_ctx_stream;
+               LLVMBasicBlockRef bb;
 
                if (!gsinfo->num_stream_output_components[stream])
                        continue;
 
                if (stream > 0 && !gs_selector->so.num_outputs)
                        continue;
 
-               LLVMValueRef is_stream =
-                       LLVMBuildICmp(builder, LLVMIntEQ,
-                                     stream_id,
-                                     lp_build_const_int32(gallivm, stream), 
"");
-
-               lp_build_if(&if_ctx_stream, gallivm, is_stream);
+               bb = LLVMInsertBasicBlockInContext(gallivm->context, end_bb, 
"out");
+               LLVMAddCase(switch_inst, lp_build_const_int32(gallivm, stream), 
bb);
+               LLVMPositionBuilderAtEnd(builder, bb);
 
                /* Fetch vertex data from GSVS ring */
                for (i = 0; i < gsinfo->num_outputs; ++i) {
                        for (unsigned chan = 0; chan < 4; chan++) {
                                if (outputs[i].vertex_stream[chan] != stream) {
                                        outputs[i].values[chan] = 
ctx.soa.bld_base.base.undef;
                                        continue;
                                }
 
                                args[2] = lp_build_const_int32(
@@ -6304,23 +6307,25 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
                /* Streamout and exports. */
                if (gs_selector->so.num_outputs) {
                        si_llvm_emit_streamout(&ctx, outputs,
                                               gsinfo->num_outputs,
                                               stream);
                }
 
                if (stream == 0)
                        si_llvm_export_vs(bld_base, outputs, 
gsinfo->num_outputs);
 
-               lp_build_endif(&if_ctx_stream);
+               LLVMBuildBr(builder, end_bb);
        }
 
+       LLVMPositionBuilderAtEnd(builder, end_bb);
+
        LLVMBuildRetVoid(gallivm->builder);
 
        /* Dump LLVM IR before any optimization passes */
        if (sscreen->b.debug_flags & DBG_PREOPT_IR &&
            r600_can_dump_shader(&sscreen->b, PIPE_SHADER_GEOMETRY))
                LLVMDumpModule(bld_base->base.gallivm->module);
 
        si_llvm_finalize_module(&ctx,
                r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_GEOMETRY));
 
-- 
2.7.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to