Mesa (10.3): nv50/ir: avoid deleting pseudo instructions too early

Emil Velikov evelikov at kemper.freedesktop.org
Sat Sep 27 18:07:40 UTC 2014


Module: Mesa
Branch: 10.3
Commit: fb4e23626f9f27c62aa1cbea05a1c8b088fcf49a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=fb4e23626f9f27c62aa1cbea05a1c8b088fcf49a

Author: Ilia Mirkin <imirkin at alum.mit.edu>
Date:   Wed Sep 24 21:45:07 2014 -0400

nv50/ir: avoid deleting pseudo instructions too early

What happens is that a SPLIT operation is part of the spill node, and as
a pseudo op, the instruction gets erased after processing its first def.
However the later defs still need to refer to it, so instead delay
deleting until after that whole RA node is done processing.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79462
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 0147c10c5f00b43696ba660aab604d674a75e83c)

---

 src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
index 4b105b4..d47fed2 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
@@ -25,6 +25,7 @@
 
 #include <stack>
 #include <limits>
+#include <tr1/unordered_set>
 
 namespace nv50_ir {
 
@@ -1547,6 +1548,11 @@ SpillCodeInserter::run(const std::list<ValuePair>& lst)
       LValue *lval = it->first->asLValue();
       Symbol *mem = it->second ? it->second->asSym() : NULL;
 
+      // Keep track of which instructions to delete later. Deleting them
+      // inside the loop is unsafe since a single instruction may have
+      // multiple destinations that all need to be spilled (like OP_SPLIT).
+      std::tr1::unordered_set<Instruction *> to_del;
+
       for (Value::DefIterator d = lval->defs.begin(); d != lval->defs.end();
            ++d) {
          Value *slot = mem ?
@@ -1579,7 +1585,7 @@ SpillCodeInserter::run(const std::list<ValuePair>& lst)
             d = lval->defs.erase(d);
             --d;
             if (slot->reg.file == FILE_MEMORY_LOCAL)
-               delete_Instruction(func->getProgram(), defi);
+               to_del.insert(defi);
             else
                defi->setDef(0, slot);
          } else {
@@ -1587,6 +1593,9 @@ SpillCodeInserter::run(const std::list<ValuePair>& lst)
          }
       }
 
+      for (std::tr1::unordered_set<Instruction *>::const_iterator it = to_del.begin();
+           it != to_del.end(); ++it)
+         delete_Instruction(func->getProgram(), *it);
    }
 
    // TODO: We're not trying to reuse old slots in a potential next iteration.




More information about the mesa-commit mailing list