[Mesa-dev] [PATCH] fix WaW errors in GM107 instruction scheduling

Rhys Perry pendingchaos02 at gmail.com
Sat May 19 21:03:39 UTC 2018


Previously, findFirstUse() only considered reads "uses". This fixes that by
making it check both an instruction's sources and definitions. It also shortens
both findFistUse() and findFirstDef() along the way.

---
 .../drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp | 103 ++++++++++-----------
 1 file changed, 50 insertions(+), 53 deletions(-)


diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
index 1f6189890c..c942db3ec9 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
@@ -3618,6 +3618,7 @@ private:
 
    bool insertBarriers(BasicBlock *);
 
+   bool doesInsnWriteTo(const Instruction *insn, const Value *val) const;
    Instruction *findFirstUse(const Instruction *) const;
    Instruction *findFirstDef(const Instruction *) const;
 
@@ -3948,8 +3949,43 @@ SchedDataCalculatorGM107::needWrDepBar(const Instruction *insn) const
    return false;
 }
 
-// Find the next instruction inside the same basic block which uses the output
-// of the given instruction in order to avoid RaW hazards.
+// Helper function for findFirstUse() and findFirstDef()
+bool
+SchedDataCalculatorGM107::doesInsnWriteTo(const Instruction *insn,
+                                          const Value *val) const
+{
+   for (int d = 0; insn->defExists(d); ++d) {
+      const Value* def = insn->getDef(d);
+      int minGPR = def->reg.data.id;
+      int maxGPR = minGPR + def->reg.size / 4 - 1;
+
+      if (def->reg.file == FILE_GPR) {
+         if (val->reg.file != FILE_GPR ||
+             val->reg.data.id + val->reg.size / 4 - 1 < minGPR ||
+             val->reg.data.id > maxGPR)
+            continue;
+         return true;
+      } else
+      if (def->reg.file == FILE_PREDICATE) {
+         if (val->reg.file != FILE_PREDICATE ||
+             val->reg.data.id != minGPR)
+            continue;
+         return true;
+      } else
+      if (def->reg.file == FILE_FLAGS) {
+         if (val->reg.file != FILE_FLAGS ||
+             val->reg.data.id != minGPR)
+            continue;
+         return true;
+      }
+   }
+
+   return false;
+}
+
+// Find the next instruction inside the same basic block which uses (reads or
+// writes from) the output of the given instruction in order to avoid RaW and
+// WaW hazards.
 Instruction *
 SchedDataCalculatorGM107::findFirstUse(const Instruction *bari) const
 {
@@ -3961,34 +3997,13 @@ SchedDataCalculatorGM107::findFirstUse(const Instruction *bari) const
    for (insn = bari->next; insn != NULL; insn = next) {
       next = insn->next;
 
-      for (int s = 0; insn->srcExists(s); ++s) {
-         const Value *src = insn->src(s).rep();
-         for (int d = 0; bari->defExists(d); ++d) {
-            const ValueDef &def = bari->def(d);
-            int minGPR = def.rep()->reg.data.id;
-            int maxGPR = minGPR + def.rep()->reg.size / 4 - 1;
-
-            if (def.getFile() == FILE_GPR) {
-               if (insn->src(s).getFile() != FILE_GPR ||
-                   src->reg.data.id + src->reg.size / 4 - 1 < minGPR ||
-                   src->reg.data.id > maxGPR)
-                  continue;
-               return insn;
-            } else
-            if (def.getFile() == FILE_PREDICATE) {
-               if (insn->src(s).getFile() != FILE_PREDICATE ||
-                   src->reg.data.id != minGPR)
-                  continue;
-               return insn;
-            }
-            if (def.getFile() == FILE_FLAGS) {
-               if (insn->src(s).getFile() != FILE_FLAGS ||
-                   src->reg.data.id != minGPR)
-                  continue;
-               return insn;
-            }
-         }
-      }
+      for (int s = 0; insn->srcExists(s); ++s)
+         if (doesInsnWriteTo(bari, insn->getSrc(s)))
+            return insn;
+
+      for (int d = 0; insn->defExists(d); ++d)
+         if (doesInsnWriteTo(bari, insn->getDef(d)))
+            return insn;
    }
    return NULL;
 }
@@ -3999,34 +4014,16 @@ Instruction *
 SchedDataCalculatorGM107::findFirstDef(const Instruction *bari) const
 {
    Instruction *insn, *next;
-   int minGPR, maxGPR;
+
+   if (!bari->srcExists(0))
+      return NULL;
 
    for (insn = bari->next; insn != NULL; insn = next) {
       next = insn->next;
 
-      for (int d = 0; insn->defExists(d); ++d) {
-         const Value *def = insn->def(d).rep();
-         if (insn->def(d).getFile() != FILE_GPR &&
-             insn->def(d).getFile() != FILE_FLAGS)
-            continue;
-
-         minGPR = def->reg.data.id;
-         maxGPR = minGPR + def->reg.size / 4 - 1;
-
-         for (int s = 0; bari->srcExists(s); ++s) {
-            const Value *src = bari->src(s).rep();
-            if (bari->src(s).getFile() == FILE_FLAGS &&
-                insn->def(d).getFile() == FILE_FLAGS &&
-                src->reg.data.id == minGPR)
-               return insn;
-            if (bari->src(s).getFile() != FILE_GPR ||
-                insn->def(d).getFile() != FILE_GPR ||
-                src->reg.data.id + src->reg.size / 4 - 1 < minGPR ||
-                src->reg.data.id > maxGPR)
-               continue;
+      for (int s = 0; bari->srcExists(s); ++s)
+         if (doesInsnWriteTo(insn, bari->getSrc(s)))
             return insn;
-         }
-      }
    }
    return NULL;
 }
-- 
2.14.3



More information about the mesa-dev mailing list