Mesa (master): pan/mdg: Optimize pipelining logic
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed May 20 17:29:32 UTC 2020
Module: Mesa
Branch: master
Commit: 4cf02b5d4a649b9fe621e3ef855021389663222d
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=4cf02b5d4a649b9fe621e3ef855021389663222d
Author: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Date: Wed May 6 15:36:38 2020 -0400
pan/mdg: Optimize pipelining logic
The test and rewrite were both accidentally O(N) to the shader size when
they should be O(1), so overall this takes the pass from O(N^2) to O(N).
Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5123>
---
src/panfrost/midgard/compiler.h | 1 -
src/panfrost/midgard/midgard_ra_pipeline.c | 42 +++++++++++++++++++++---------
src/panfrost/midgard/mir.c | 19 --------------
3 files changed, 30 insertions(+), 32 deletions(-)
diff --git a/src/panfrost/midgard/compiler.h b/src/panfrost/midgard/compiler.h
index 67d56035a8b..618c0d79265 100644
--- a/src/panfrost/midgard/compiler.h
+++ b/src/panfrost/midgard/compiler.h
@@ -483,7 +483,6 @@ void mir_rewrite_index_src_swizzle(compiler_context *ctx, unsigned old, unsigned
bool mir_single_use(compiler_context *ctx, unsigned value);
bool mir_special_index(compiler_context *ctx, unsigned idx);
unsigned mir_use_count(compiler_context *ctx, unsigned value);
-bool mir_is_written_before(compiler_context *ctx, midgard_instruction *ins, unsigned node);
uint16_t mir_bytemask_of_read_components(midgard_instruction *ins, unsigned node);
uint16_t mir_bytemask_of_read_components_index(midgard_instruction *ins, unsigned i);
midgard_reg_mode mir_typesize(midgard_instruction *ins);
diff --git a/src/panfrost/midgard/midgard_ra_pipeline.c b/src/panfrost/midgard/midgard_ra_pipeline.c
index 48f45cb9adb..1037d0645d9 100644
--- a/src/panfrost/midgard/midgard_ra_pipeline.c
+++ b/src/panfrost/midgard/midgard_ra_pipeline.c
@@ -47,18 +47,30 @@ mir_pipeline_ins(
{
midgard_instruction *ins = bundle->instructions[i];
- /* We could be pipelining a register, so we need to make sure that all
- * of the components read in this bundle are written in this bundle,
- * and that no components are written before this bundle */
+ /* Our goal is to create a pipeline register. Pipeline registers are
+ * created at the start of the bundle and are destroyed at the end. So
+ * we conservatively require:
+ *
+ * 1. Each component read in the second stage is written in the first stage.
+ * 2. The index is not live after the bundle.
+ * 3. We're not a special index (writeout, conditionals, ..)
+ *
+ * Rationale: #1 ensures that there is no need to go before the
+ * creation of the bundle, so the pipeline register can exist. #2 is
+ * since the pipeline register will be destroyed at the end. This
+ * ensures that nothing will try to read/write the pipeline register
+ * once it is not live, and that there's no need to go earlier. */
unsigned node = ins->dest;
unsigned read_mask = 0;
+ if (node >= SSA_FIXED_MINIMUM)
+ return false;
+
/* Analyze the bundle for a per-byte read mask */
for (unsigned j = 0; j < bundle->instruction_count; ++j) {
midgard_instruction *q = bundle->instructions[j];
- read_mask |= mir_bytemask_of_read_components(q, node);
/* The fragment colour can't be pipelined (well, it is
* pipelined in r0, but this is a delicate dance with
@@ -66,11 +78,15 @@ mir_pipeline_ins(
if (q->compact_branch && q->writeout && mir_has_arg(q, node))
return false;
+
+ if (q->unit < UNIT_VADD) continue;
+ read_mask |= mir_bytemask_of_read_components(q, node);
}
- /* Now analyze for a write mask */
+ /* Now check what's written in the beginning stage */
for (unsigned j = 0; j < bundle->instruction_count; ++j) {
midgard_instruction *q = bundle->instructions[j];
+ if (q->unit >= UNIT_VADD) break;
if (q->dest != node) continue;
/* Remove the written mask from the read requirements */
@@ -81,12 +97,6 @@ mir_pipeline_ins(
if (read_mask)
return false;
- /* Now, check outside the bundle */
- midgard_instruction *start = bundle->instructions[0];
-
- if (mir_is_written_before(ctx, start, node))
- return false;
-
/* We want to know if we live after this bundle, so check if
* we're live after the last instruction of the bundle */
@@ -97,8 +107,16 @@ mir_pipeline_ins(
return false;
/* We're only live in this bundle -- pipeline! */
+ unsigned preg = SSA_FIXED_REGISTER(24 + pipeline_count);
+
+ for (unsigned j = 0; j < bundle->instruction_count; ++j) {
+ midgard_instruction *q = bundle->instructions[j];
- mir_rewrite_index(ctx, node, SSA_FIXED_REGISTER(24 + pipeline_count));
+ if (q->unit >= UNIT_VADD)
+ mir_rewrite_index_src_single(q, node, preg);
+ else
+ mir_rewrite_index_dst_single(q, node, preg);
+ }
return true;
}
diff --git a/src/panfrost/midgard/mir.c b/src/panfrost/midgard/mir.c
index 7dc357e62ac..68f6286c590 100644
--- a/src/panfrost/midgard/mir.c
+++ b/src/panfrost/midgard/mir.c
@@ -197,25 +197,6 @@ mir_special_index(compiler_context *ctx, unsigned idx)
return false;
}
-/* Is a node written before a given instruction? */
-
-bool
-mir_is_written_before(compiler_context *ctx, midgard_instruction *ins, unsigned node)
-{
- if (node >= SSA_FIXED_MINIMUM)
- return true;
-
- mir_foreach_instr_global(ctx, q) {
- if (q == ins)
- break;
-
- if (q->dest == node)
- return true;
- }
-
- return false;
-}
-
/* Grabs the type size. */
midgard_reg_mode
More information about the mesa-commit
mailing list