aboutsummaryrefslogtreecommitdiffstats
path: root/src/freedreno
diff options
context:
space:
mode:
Diffstat (limited to 'src/freedreno')
-rw-r--r--src/freedreno/ir3/ir3.c24
-rw-r--r--src/freedreno/ir3/ir3.h1
-rw-r--r--src/freedreno/ir3/ir3_ra.c11
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);