freedreno/ir3: track "keeps" in ir
authorRob Clark <robclark@freedesktop.org>
Sat, 25 Jul 2015 17:51:16 +0000 (13:51 -0400)
committerRob Clark <robclark@freedesktop.org>
Mon, 27 Jul 2015 17:51:06 +0000 (13:51 -0400)
Previously we had a fixed array to track kills, since they don't
generate an SSA value, and then cheated by stuffing them in the
outputs array before sending things through depth/sched/etc.  But
store instructions will need similar treatment.  So convert this
over to a more general array of instructions that must be kept
and fix up the places that were previously relying on kills being
in the output array.

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

index e68170dec580f82c3bdbdc04462185a6084e2c5e..12f2ebe18db175cee0975369008fbcd7af57ee9d 100644 (file)
@@ -369,6 +369,12 @@ struct ir3 {
        unsigned predicates_count, predicates_sz;
        struct ir3_instruction **predicates;
 
+       /* Track instructions which do not write a register but other-
+        * wise must not be discarded (such as kill, stg, etc)
+        */
+       unsigned keeps_count, keeps_sz;
+       struct ir3_instruction **keeps;
+
        /* List of blocks: */
        struct list_head block_list;
 
index e013abedce6a8fad18a6d2fc965f39d26a8fd890..a4b27854433636bc2d48a3c47fe397e66dd71dbf 100644 (file)
@@ -117,10 +117,6 @@ struct ir3_compile {
        /* for looking up which system value is which */
        unsigned sysval_semantics[8];
 
-       /* list of kill instructions: */
-       struct ir3_instruction *kill[16];
-       unsigned int kill_count;
-
        /* set if we encounter something we can't handle yet, so we
         * can bail cleanly and fallback to TGSI compiler f/e
         */
@@ -1481,7 +1477,7 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
                kill = ir3_KILL(b, cond, 0);
                array_insert(ctx->ir->predicates, kill);
 
-               ctx->kill[ctx->kill_count++] = kill;
+               array_insert(ctx->ir->keeps, kill);
                ctx->so->has_kill = true;
 
                break;
@@ -2165,13 +2161,9 @@ emit_instructions(struct ir3_compile *ctx)
        ninputs  = exec_list_length(&ctx->s->inputs) * 4;
        noutputs = exec_list_length(&ctx->s->outputs) * 4;
 
-       /* we need to allocate big enough outputs array so that
-        * we can stuff the kill's at the end.  Likewise for vtx
-        * shaders, we need to leave room for sysvals:
+       /* or vtx shaders, we need to leave room for sysvals:
         */
-       if (ctx->so->type == SHADER_FRAGMENT) {
-               noutputs += ARRAY_SIZE(ctx->kill);
-       } else if (ctx->so->type == SHADER_VERTEX) {
+       if (ctx->so->type == SHADER_VERTEX) {
                ninputs += 8;
        }
 
@@ -2182,9 +2174,7 @@ emit_instructions(struct ir3_compile *ctx)
        ctx->in_block = ctx->block;
        list_addtail(&ctx->block->node, &ctx->ir->block_list);
 
-       if (ctx->so->type == SHADER_FRAGMENT) {
-               ctx->ir->noutputs -= ARRAY_SIZE(ctx->kill);
-       } else if (ctx->so->type == SHADER_VERTEX) {
+       if (ctx->so->type == SHADER_VERTEX) {
                ctx->ir->ninputs -= 8;
        }
 
@@ -2380,15 +2370,6 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
                }
        }
 
-       /* at this point, we want the kill's in the outputs array too,
-        * so that they get scheduled (since they have no dst).. we've
-        * already ensured that the array is big enough in push_block():
-        */
-       if (so->type == SHADER_FRAGMENT) {
-               for (i = 0; i < ctx->kill_count; i++)
-                       ir->outputs[ir->noutputs++] = ctx->kill[i];
-       }
-
        if (fd_mesa_debug & FD_DBG_OPTMSGS) {
                printf("BEFORE CP:\n");
                ir3_print(ir);
index f4c825b2ab602b6a3fe93ac4e5da5fea200c6bf7..be4e4e81109787b14203c73f3976471b02d08a94 100644 (file)
@@ -408,6 +408,10 @@ ir3_cp(struct ir3 *ir)
                }
        }
 
+       for (unsigned i = 0; i < ir->keeps_count; i++) {
+               ir->keeps[i] = instr_cp(ir->keeps[i], NULL);
+       }
+
        list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
                if (block->condition)
                        block->condition = instr_cp(block->condition, NULL);
index 0f346b26f4aa1b600c2ead722548d12da9502f0d..97df0c2ac99fbf61d652c5ad789b8d36c52a83de 100644 (file)
@@ -156,6 +156,9 @@ ir3_depth(struct ir3 *ir)
                if (ir->outputs[i])
                        ir3_instr_depth(ir->outputs[i]);
 
+       for (i = 0; i < ir->keeps_count; i++)
+               ir3_instr_depth(ir->keeps[i]);
+
        /* We also need to account for if-condition: */
        list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
                if (block->condition)