From 96d4db683f90f02e72d34ece544de7eedfa873ee Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 25 Jul 2015 13:51:16 -0400 Subject: [PATCH] freedreno/ir3: track "keeps" in ir 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 --- src/gallium/drivers/freedreno/ir3/ir3.h | 6 +++++ .../drivers/freedreno/ir3/ir3_compiler_nir.c | 27 +++---------------- src/gallium/drivers/freedreno/ir3/ir3_cp.c | 4 +++ src/gallium/drivers/freedreno/ir3/ir3_depth.c | 3 +++ 4 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h index e68170dec58..12f2ebe18db 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.h +++ b/src/gallium/drivers/freedreno/ir3/ir3.h @@ -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; diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c index e013abedce6..a4b27854433 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c @@ -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); diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cp.c b/src/gallium/drivers/freedreno/ir3/ir3_cp.c index f4c825b2ab6..be4e4e81109 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_cp.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_cp.c @@ -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); diff --git a/src/gallium/drivers/freedreno/ir3/ir3_depth.c b/src/gallium/drivers/freedreno/ir3/ir3_depth.c index 0f346b26f4a..97df0c2ac99 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_depth.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_depth.c @@ -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) -- 2.30.2