Mesa (10.2): nvc0/ir: avoid infinite recursion when finding first uses of tex

Emil Velikov evelikov at kemper.freedesktop.org
Tue Sep 2 19:53:33 UTC 2014


Module: Mesa
Branch: 10.2
Commit: 836b0ae8b618e857a0f12ed725a091cf81da3000
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=836b0ae8b618e857a0f12ed725a091cf81da3000

Author: Ilia Mirkin <imirkin at alum.mit.edu>
Date:   Thu Aug 28 23:05:49 2014 -0400

nvc0/ir: avoid infinite recursion when finding first uses of tex

In certain circumstances, findFirstUses could end up doubling back on
instructions it had already processed, resulting in an infinite
recursion. Avoid this by keeping track of already-visited instructions.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=83079
Tested-by: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de>
Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
Cc: "10.2 10.3" <mesa-stable at lists.freedesktop.org>
(cherry picked from commit c4bb436f7660c951cd27e52660cf825da68793e5)

Conflicts:
	src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h

---

 .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp      |   36 +++++++++++++++-----
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
index 767cc02..ea1a17a 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
@@ -26,6 +26,7 @@
 #include "codegen/nv50_ir_target_nvc0.h"
 
 #include <limits>
+#include <tr1/unordered_set>
 
 namespace nv50_ir {
 
@@ -148,7 +149,8 @@ private:
    bool insertTextureBarriers(Function *);
    inline bool insnDominatedBy(const Instruction *, const Instruction *) const;
    void findFirstUses(const Instruction *tex, const Instruction *def,
-                      std::list<TexUse>&);
+                      std::list<TexUse>&,
+                      std::tr1::unordered_set<const Instruction *>&);
    void findOverwritingDefs(const Instruction *tex, Instruction *insn,
                             const BasicBlock *term,
                             std::list<TexUse>&);
@@ -230,15 +232,31 @@ NVC0LegalizePostRA::findOverwritingDefs(const Instruction *texi,
 }
 
 void
-NVC0LegalizePostRA::findFirstUses(const Instruction *texi,
-                                  const Instruction *insn,
-                                  std::list<TexUse> &uses)
+NVC0LegalizePostRA::findFirstUses(
+      const Instruction *texi,
+      const Instruction *insn,
+      std::list<TexUse> &uses,
+      std::tr1::unordered_set<const Instruction *>& visited)
 {
    for (int d = 0; insn->defExists(d); ++d) {
       Value *v = insn->getDef(d);
       for (Value::UseIterator u = v->uses.begin(); u != v->uses.end(); ++u) {
          Instruction *usei = (*u)->getInsn();
 
+         /* XXX HACK ALERT XXX
+          *
+          * This shouldn't have to be here, we should always be making forward
+          * progress by looking at the uses. However this somehow does not
+          * appear to be the case. Probably because this is being done right
+          * after RA, when the defs/uses lists have been messed with by node
+          * merging. This should probably be moved to being done right before
+          * RA. But this will do for now.
+          */
+         if (visited.find(usei) != visited.end())
+            continue;
+
+         visited.insert(usei);
+
          if (usei->op == OP_PHI || usei->op == OP_UNION) {
             // need a barrier before WAW cases
             for (int s = 0; usei->srcExists(s); ++s) {
@@ -253,11 +271,11 @@ NVC0LegalizePostRA::findFirstUses(const Instruction *texi,
              usei->op == OP_PHI ||
              usei->op == OP_UNION) {
             // these uses don't manifest in the machine code
-            findFirstUses(texi, usei, uses);
+            findFirstUses(texi, usei, uses, visited);
          } else
          if (usei->op == OP_MOV && usei->getDef(0)->equals(usei->getSrc(0)) &&
              usei->subOp != NV50_IR_SUBOP_MOV_FINAL) {
-            findFirstUses(texi, usei, uses);
+            findFirstUses(texi, usei, uses, visited);
          } else {
             addTexUse(uses, usei, insn);
          }
@@ -313,8 +331,10 @@ NVC0LegalizePostRA::insertTextureBarriers(Function *fn)
    uses = new std::list<TexUse>[texes.size()];
    if (!uses)
       return false;
-   for (size_t i = 0; i < texes.size(); ++i)
-      findFirstUses(texes[i], texes[i], uses[i]);
+   for (size_t i = 0; i < texes.size(); ++i) {
+      std::tr1::unordered_set<const Instruction *> visited;
+      findFirstUses(texes[i], texes[i], uses[i], visited);
+   }
 
    // determine the barrier level at each use
    for (size_t i = 0; i < texes.size(); ++i) {




More information about the mesa-commit mailing list