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;
}
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);
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);
/* 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);