diff options
Diffstat (limited to 'src/freedreno/ir3')
-rw-r--r-- | src/freedreno/ir3/ir3.c | 24 | ||||
-rw-r--r-- | src/freedreno/ir3/ir3.h | 1 | ||||
-rw-r--r-- | src/freedreno/ir3/ir3_ra.c | 11 |
3 files changed, 34 insertions, 2 deletions
diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index 9678389e8b5..d4fcd995ed0 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -1155,11 +1155,33 @@ ir3_count_instructions(struct ir3 *ir) unsigned cnt = 1; foreach_block (block, &ir->block_list) { block->start_ip = cnt; + foreach_instr (instr, &block->instr_list) { + instr->ip = cnt++; + } block->end_ip = cnt; + } + return cnt; +} + +/* When counting instructions for RA, we insert extra fake instructions at the + * beginning of each block, where values become live, and at the end where + * values die. This prevents problems where values live-in at the beginning or + * live-out at the end of a block from being treated as if they were + * live-in/live-out at the first/last instruction, which would be incorrect. + * In ir3_legalize these ip's are assumed to be actual ip's of the final + * program, so it would be incorrect to use this everywhere. + */ + +unsigned +ir3_count_instructions_ra(struct ir3 *ir) +{ + unsigned cnt = 1; + foreach_block (block, &ir->block_list) { + block->start_ip = cnt++; foreach_instr (instr, &block->instr_list) { instr->ip = cnt++; - block->end_ip = instr->ip; } + block->end_ip = cnt++; } return cnt; } diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 351490aecf7..6cb882002f0 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -594,6 +594,7 @@ void ir3_block_clear_mark(struct ir3_block *block); void ir3_clear_mark(struct ir3 *shader); unsigned ir3_count_instructions(struct ir3 *ir); +unsigned ir3_count_instructions_ra(struct ir3 *ir); void ir3_find_ssa_uses(struct ir3 *ir, void *mem_ctx, bool falsedeps); diff --git a/src/freedreno/ir3/ir3_ra.c b/src/freedreno/ir3/ir3_ra.c index 72682dc6988..f74174498d0 100644 --- a/src/freedreno/ir3/ir3_ra.c +++ b/src/freedreno/ir3/ir3_ra.c @@ -541,7 +541,7 @@ ra_init(struct ir3_ra_ctx *ctx) unsigned n, base; ir3_clear_mark(ctx->ir); - n = ir3_count_instructions(ctx->ir); + n = ir3_count_instructions_ra(ctx->ir); ctx->instrd = rzalloc_array(NULL, struct ir3_ra_instr_data, n); @@ -950,6 +950,15 @@ ra_calc_block_live_values(struct ir3_ra_ctx *ctx, struct ir3_block *block) /* the remaining live should match liveout (for extra sanity testing): */ if (RA_DEBUG) { + unsigned new_dead = 0; + BITSET_FOREACH_SET (name, live, ctx->alloc_count) { + /* Is this the last use? */ + if (ctx->use[name] != block->end_ip) + continue; + new_dead += name_size(ctx, name); + d("NEW_DEAD: %u (new_dead=%u)", name, new_dead); + BITSET_CLEAR(live, name); + } unsigned liveout = 0; BITSET_FOREACH_SET (name, bd->liveout, ctx->alloc_count) { liveout += name_size(ctx, name); |