ir3: Prevent propagating shared regs out of loops

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6752>
This commit is contained in:
Connor Abbott 2021-05-27 17:28:09 +02:00 committed by Marge Bot
parent 394c597b1b
commit 590efd180b
4 changed files with 20 additions and 0 deletions

View File

@ -563,6 +563,8 @@ struct ir3_block {
uint32_t dom_pre_index;
uint32_t dom_post_index;
uint32_t loop_id;
#ifdef DEBUG
uint32_t serialno;
#endif

View File

@ -2861,6 +2861,8 @@ emit_block(struct ir3_context *ctx, nir_block *nblock)
list_addtail(&ctx->block->node, &ctx->ir->block_list);
ctx->block->loop_id = ctx->loop_id;
/* re-emit addr register in each block if needed: */
for (int i = 0; i < ARRAY_SIZE(ctx->addr0_ht); i++) {
_mesa_hash_table_destroy(ctx->addr0_ht[i], NULL);
@ -2915,8 +2917,11 @@ emit_if(struct ir3_context *ctx, nir_if *nif)
static void
emit_loop(struct ir3_context *ctx, nir_loop *nloop)
{
unsigned old_loop_id = ctx->loop_id;
ctx->loop_id = ctx->so->loops + 1;
emit_cf_list(ctx, &nloop->body);
ctx->so->loops++;
ctx->loop_id = old_loop_id;
}
static void

View File

@ -110,6 +110,8 @@ struct ir3_context {
*/
unsigned stack, max_stack;
unsigned loop_id;
/* a common pattern for indirect addressing is to request the
* same address register multiple times. To avoid generating
* duplicate instruction sequences (which our backend does not

View File

@ -310,6 +310,17 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
{
struct ir3_instruction *src = ssa(reg);
/* Values that are uniform inside a loop can become divergent outside
* it if the loop has a divergent trip count. This means that we can't
* propagate a copy of a shared to non-shared register if it would
* make the shared reg's live range extend outside of its loop. Users
* outside the loop would see the value for the thread(s) that last
* exited the loop, rather than for their own thread.
*/
if ((src->dsts[0]->flags & IR3_REG_SHARED) &&
src->block->loop_id != instr->block->loop_id)
return false;
if (is_eligible_mov(src, instr, true)) {
/* simple case, no immed/const/relativ, only mov's w/ ssa src: */
struct ir3_register *src_reg = src->srcs[0];