ir3: Prevent propagating shared regs out of loops
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6752>
This commit is contained in:
parent
394c597b1b
commit
590efd180b
|
@ -563,6 +563,8 @@ struct ir3_block {
|
||||||
uint32_t dom_pre_index;
|
uint32_t dom_pre_index;
|
||||||
uint32_t dom_post_index;
|
uint32_t dom_post_index;
|
||||||
|
|
||||||
|
uint32_t loop_id;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
uint32_t serialno;
|
uint32_t serialno;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2861,6 +2861,8 @@ emit_block(struct ir3_context *ctx, nir_block *nblock)
|
||||||
|
|
||||||
list_addtail(&ctx->block->node, &ctx->ir->block_list);
|
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: */
|
/* re-emit addr register in each block if needed: */
|
||||||
for (int i = 0; i < ARRAY_SIZE(ctx->addr0_ht); i++) {
|
for (int i = 0; i < ARRAY_SIZE(ctx->addr0_ht); i++) {
|
||||||
_mesa_hash_table_destroy(ctx->addr0_ht[i], NULL);
|
_mesa_hash_table_destroy(ctx->addr0_ht[i], NULL);
|
||||||
|
@ -2915,8 +2917,11 @@ emit_if(struct ir3_context *ctx, nir_if *nif)
|
||||||
static void
|
static void
|
||||||
emit_loop(struct ir3_context *ctx, nir_loop *nloop)
|
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);
|
emit_cf_list(ctx, &nloop->body);
|
||||||
ctx->so->loops++;
|
ctx->so->loops++;
|
||||||
|
ctx->loop_id = old_loop_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -110,6 +110,8 @@ struct ir3_context {
|
||||||
*/
|
*/
|
||||||
unsigned stack, max_stack;
|
unsigned stack, max_stack;
|
||||||
|
|
||||||
|
unsigned loop_id;
|
||||||
|
|
||||||
/* a common pattern for indirect addressing is to request the
|
/* a common pattern for indirect addressing is to request the
|
||||||
* same address register multiple times. To avoid generating
|
* same address register multiple times. To avoid generating
|
||||||
* duplicate instruction sequences (which our backend does not
|
* duplicate instruction sequences (which our backend does not
|
||||||
|
|
|
@ -310,6 +310,17 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
|
||||||
{
|
{
|
||||||
struct ir3_instruction *src = ssa(reg);
|
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)) {
|
if (is_eligible_mov(src, instr, true)) {
|
||||||
/* simple case, no immed/const/relativ, only mov's w/ ssa src: */
|
/* simple case, no immed/const/relativ, only mov's w/ ssa src: */
|
||||||
struct ir3_register *src_reg = src->srcs[0];
|
struct ir3_register *src_reg = src->srcs[0];
|
||||||
|
|
Loading…
Reference in New Issue