summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2015-07-02 15:38:34 -0400
committerRob Clark <[email protected]>2015-07-03 08:56:09 -0400
commita84505c71920f2c70bc8d83cee3e223cd2d976ad (patch)
tree84bfe5d730962956d06c8bd738c605c5756b5984
parent2215ff2a5d5f1df5791399e1ff78b56bf06e9102 (diff)
freedreno/ir3: don't be confused by eliminated indirects
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 <[email protected]>
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_depth.c9
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_sched.c5
2 files changed, 14 insertions, 0 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_depth.c b/src/gallium/drivers/freedreno/ir3/ir3_depth.c
index 3a108243479..0f346b26f4a 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_depth.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_depth.c
@@ -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];
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_sched.c b/src/gallium/drivers/freedreno/ir3/ir3_sched.c
index 414d14e0f0d..0cb1589eb4d 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_sched.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_sched.c
@@ -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;