[Mesa-dev] [PATCH 4/4] nv50: add PostRADualIssue Pass

Karol Herbst karolherbst at gmail.com
Sat Aug 13 10:02:38 UTC 2016


this paths reorders instructions in a way, so that the hardware is able to
dual issue more instructions leading to higher performance.

with all previos commits put together
changes for ./GpuTest /test=pixmark_piano /benchmark /no_scorebox /msaa=0
/benchmark_duration_ms=60000 /width=1024 /height=640:

inst_executed: 1.03G
inst_issued1: 614M -> 500M
inst_issued2: 213M -> 271M

score: 1021 -> 1056

Signed-off-by: Karol Herbst <karolherbst at gmail.com>
---
 .../drivers/nouveau/codegen/nv50_ir_peephole.cpp   | 59 ++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
index a9172f8..88354c9 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
@@ -3385,6 +3385,62 @@ DeadCodeElim::checkSplitLoad(Instruction *ld1)
 
 // =============================================================================
 
+// Tries to improve dual issueing trivially
+//
+// the PASS checks for every instruction A,B with A->next == B and
+// !canDualIssue(A,B), if there is a Instruction C in the same BB which can be
+// moved between A and B and canDualIssue(A,C) is true
+class PostRADualIssue : public Pass
+{
+private:
+   virtual bool visit(BasicBlock *);
+};
+
+static bool
+isChainedCommutationLegal(Instruction *a, Instruction *b)
+{
+   Instruction *check = a;
+   do {
+      if (!check->isCommutationLegal(b) || (check->op == OP_TEX && check->op == OP_TEX))
+         return false;
+      check = check->next;
+   } while (check != b);
+   return true;
+}
+
+bool
+PostRADualIssue::visit(BasicBlock *bb)
+{
+   const Target *target = prog->getTarget();
+   Instruction *i, *next, *check;
+
+   for (i = bb->getEntry(); i; i = next) {
+      next = i->next;
+
+      // check next
+      if (!next || next->fixed || next->join || next->asFlow() || target->canDualIssue(i, next))
+         continue;
+
+      check = next->next;
+      // we can't move fixed, flow instructions and instruction marked as join
+      while (check && !check->fixed && !check->join && !check->asFlow() && check->prev->bb == check->bb && isChainedCommutationLegal(next, check)) {
+         if (target->canDualIssue(i, check)) {
+            // move the instruction after i step by step
+            while (check->prev != i)
+               bb->permuteAdjacent(check->prev, check);
+
+            // we have to always continue with the currently next instruction
+            next = i->next;
+            break;
+         }
+         check = check->next;
+      }
+   }
+   return true;
+}
+
+// =============================================================================
+
 #define RUN_PASS(l, n, f)                       \
    if (level >= (l)) {                          \
       if (dbgFlags & NV50_IR_DEBUG_VERBOSE)     \
@@ -3420,6 +3476,9 @@ Program::optimizePostRA(int level)
    RUN_PASS(2, FlatteningPass, run);
    if (getTarget()->getChipset() < 0xc0)
       RUN_PASS(2, NV50PostRaConstantFolding, run);
+   // should be last
+   if (getTarget()->hasDualIssueing())
+      RUN_PASS(2, PostRADualIssue, run);
 
    return true;
 }
-- 
2.9.2



More information about the mesa-dev mailing list