freedreno/ir3: don't be confused by eliminated indirects
authorRob Clark <robclark@freedesktop.org>
Thu, 2 Jul 2015 19:38:34 +0000 (15:38 -0400)
committerRob Clark <robclark@freedesktop.org>
Fri, 3 Jul 2015 12:56:09 +0000 (08:56 -0400)
If an instruction using address register value gets eliminated, we need
to remove it from the indirects list, otherwise it causes mayhem in
sched for scheduling address register usage.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/ir3/ir3_depth.c
src/gallium/drivers/freedreno/ir3/ir3_sched.c

index 3a108243479da0379f1b4eb4aa80828194bc8335..0f346b26f4aa1b600c2ead722548d12da9502f0d 100644 (file)
@@ -167,6 +167,15 @@ ir3_depth(struct ir3 *ir)
                remove_unused_by_block(block);
        }
 
+       /* note that we can end up with unused indirects, but we should
+        * not end up with unused predicates.
+        */
+       for (i = 0; i < ir->indirects_count; i++) {
+               struct ir3_instruction *instr = ir->indirects[i];
+               if (instr->depth == DEPTH_UNUSED)
+                       ir->indirects[i] = NULL;
+       }
+
        /* cleanup unused inputs: */
        for (i = 0; i < ir->ninputs; i++) {
                struct ir3_instruction *in = ir->inputs[i];
index 414d14e0f0db1af88e81d744e66f2c9d90f637ce..0cb1589eb4dded4d38db1f37659a2fd4dcd9e088 100644 (file)
@@ -299,6 +299,8 @@ add_eligible_instrs(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
                        bool ready = false;
                        for (unsigned i = 0; (i < ir->indirects_count) && !ready; i++) {
                                struct ir3_instruction *indirect = ir->indirects[i];
+                               if (!indirect)
+                                       continue;
                                if (indirect->address != instr)
                                        continue;
                                ready = could_sched(indirect, instr);
@@ -338,6 +340,9 @@ split_addr(struct ir3_sched_ctx *ctx)
        for (i = 0; i < ir->indirects_count; i++) {
                struct ir3_instruction *indirect = ir->indirects[i];
 
+               if (!indirect)
+                       continue;
+
                /* skip instructions already scheduled: */
                if (is_scheduled(indirect))
                        continue;