summaryrefslogtreecommitdiffstats
path: root/src/amd/compiler/aco_instruction_selection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/amd/compiler/aco_instruction_selection.cpp')
-rw-r--r--src/amd/compiler/aco_instruction_selection.cpp33
1 files changed, 21 insertions, 12 deletions
diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp
index c279f04a031..e935dc11a9b 100644
--- a/src/amd/compiler/aco_instruction_selection.cpp
+++ b/src/amd/compiler/aco_instruction_selection.cpp
@@ -7057,26 +7057,35 @@ static void visit_loop(isel_context *ctx, nir_loop *loop)
* workaround, break the loop when the loop mask is empty instead of
* always continuing. */
ctx->block->kind |= (block_kind_continue_or_break | block_kind_uniform);
-
- /* create "loop_almost_exit" to avoid critical edges */
unsigned block_idx = ctx->block->index;
- Block *loop_almost_exit = ctx->program->create_and_insert_block();
- loop_almost_exit->loop_nest_depth = ctx->cf_info.loop_nest_depth;
- loop_almost_exit->kind = block_kind_uniform;
- bld.reset(loop_almost_exit);
+
+ /* create helper blocks to avoid critical edges */
+ Block *break_block = ctx->program->create_and_insert_block();
+ break_block->loop_nest_depth = ctx->cf_info.loop_nest_depth;
+ break_block->kind = block_kind_uniform;
+ bld.reset(break_block);
bld.branch(aco_opcode::p_branch);
+ add_linear_edge(block_idx, break_block);
+ add_linear_edge(break_block->index, &loop_exit);
- add_linear_edge(block_idx, loop_almost_exit);
- add_linear_edge(loop_almost_exit->index, &loop_exit);
+ Block *continue_block = ctx->program->create_and_insert_block();
+ continue_block->loop_nest_depth = ctx->cf_info.loop_nest_depth;
+ continue_block->kind = block_kind_uniform;
+ bld.reset(continue_block);
+ bld.branch(aco_opcode::p_branch);
+ add_linear_edge(block_idx, continue_block);
+ add_linear_edge(continue_block->index, &ctx->program->blocks[loop_header_idx]);
+ add_logical_edge(block_idx, &ctx->program->blocks[loop_header_idx]);
ctx->block = &ctx->program->blocks[block_idx];
} else {
ctx->block->kind |= (block_kind_continue | block_kind_uniform);
+ if (!ctx->cf_info.parent_loop.has_divergent_branch)
+ add_edge(ctx->block->index, &ctx->program->blocks[loop_header_idx]);
+ else
+ add_linear_edge(ctx->block->index, &ctx->program->blocks[loop_header_idx]);
}
- if (!ctx->cf_info.parent_loop.has_divergent_branch)
- add_edge(ctx->block->index, &ctx->program->blocks[loop_header_idx]);
- else
- add_linear_edge(ctx->block->index, &ctx->program->blocks[loop_header_idx]);
+
bld.reset(ctx->block);
bld.branch(aco_opcode::p_branch);
}