summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolai Hähnle <[email protected]>2016-11-29 16:25:21 +0100
committerNicolai Hähnle <[email protected]>2016-12-12 09:04:49 +0100
commitbdf1bf1cb5422a944205ea30b2eb203a73bdd736 (patch)
tree026a9e3ad8318b0c3b31b53123166e4f0adb5d4a
parentbae929f96ee57ec55d15fae87bf80c45a8bd7e4d (diff)
radeonsi: generate an explicit switch instruction over vertex streams
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. Reviewed-by: Marek Olšák <[email protected]>
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 31a0b3047c1..469e0c1cc3d 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -6407,8 +6407,14 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
}
}
+ 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;
@@ -6416,12 +6422,9 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
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) {
@@ -6455,9 +6458,11 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
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 */