summaryrefslogtreecommitdiffstats
path: root/src/freedreno/ir3/ir3_sched.c
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2019-05-24 09:19:55 -0700
committerRob Clark <[email protected]>2019-06-03 12:44:03 -0700
commitbb3aa44ade078278c3ad021736c1cd2e8d6ff5da (patch)
tree358cc55a15e572b8447b0e7baef3b74fb40abae8 /src/freedreno/ir3/ir3_sched.c
parentd2906293c432b1b0519612caed0c50f43044966a (diff)
freedreno/ir3: sched should mark outputs used
Account for shader outputs and values live in any direct/indirect successor block. Signed-off-by: Rob Clark <[email protected]> Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/freedreno/ir3/ir3_sched.c')
-rw-r--r--src/freedreno/ir3/ir3_sched.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/src/freedreno/ir3/ir3_sched.c b/src/freedreno/ir3/ir3_sched.c
index dd9567764f7..16199ca3fb9 100644
--- a/src/freedreno/ir3/ir3_sched.c
+++ b/src/freedreno/ir3/ir3_sched.c
@@ -87,6 +87,8 @@ unuse_each_src(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr)
}
}
+static void use_instr(struct ir3_instruction *instr);
+
static void
use_each_src(struct ir3_instruction *instr)
{
@@ -95,13 +97,17 @@ use_each_src(struct ir3_instruction *instr)
foreach_ssa_src_n(src, n, instr) {
if (__is_false_dep(instr, n))
continue;
- if (instr->block != src->block)
- continue;
- if ((src->opc == OPC_META_FI) || (src->opc == OPC_META_FO)) {
- use_each_src(src);
- } else {
- src->use_count++;
- }
+ use_instr(src);
+ }
+}
+
+static void
+use_instr(struct ir3_instruction *instr)
+{
+ if ((instr->opc == OPC_META_FI) || (instr->opc == OPC_META_FO)) {
+ use_each_src(instr);
+ } else {
+ instr->use_count++;
}
}
@@ -115,23 +121,33 @@ update_live_values(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr)
unuse_each_src(ctx, instr);
}
-/* This is *slightly* different than how ir3_cp uses use_count, in that
- * we just track it per block (because we schedule a block at a time) and
- * because we don't track meta instructions and false dependencies (since
- * they don't contribute real register pressure).
- */
static void
-update_use_count(struct ir3_block *block)
+update_use_count(struct ir3 *ir)
{
- list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
- instr->use_count = 0;
+ list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+ list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
+ instr->use_count = 0;
+ }
}
- list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
- if ((instr->opc == OPC_META_FI) || (instr->opc == OPC_META_FO))
+ list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+ list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
+ if ((instr->opc == OPC_META_FI) || (instr->opc == OPC_META_FO))
+ continue;
+
+ use_each_src(instr);
+ }
+ }
+
+ /* Shader outputs are also used:
+ */
+ for (unsigned i = 0; i < ir->noutputs; i++) {
+ struct ir3_instruction *out = ir->outputs[i];
+
+ if (!out)
continue;
- use_each_src(instr);
+ use_instr(out);
}
}
@@ -790,10 +806,10 @@ int ir3_sched(struct ir3 *ir)
struct ir3_sched_ctx ctx = {0};
ir3_clear_mark(ir);
+ update_use_count(ir);
list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
ctx.live_values = 0;
- update_use_count(block);
sched_block(&ctx, block);
}