summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlia Mirkin <imirkin@alum.mit.edu>2014-09-24 21:45:07 -0400
committerEmil Velikov <emil.l.velikov@gmail.com>2014-09-27 16:25:59 +0100
commit18336b99b2c8d71569bdb89a6c3cb93880cd3fc3 (patch)
tree80e26cade7c356444ca48c2703984c9dc1e0f947
parent38c5650656f6829b4a47d6ebb384e2c4c208489f (diff)
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@alum.mit.edu> Cc: "10.2 10.3" <mesa-stable@lists.freedesktop.org> (cherry picked from commit 0147c10c5f00b43696ba660aab604d674a75e83c)
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
index f2a8b551407..814e353e5d7 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 {
@@ -1544,6 +1545,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 ?
@@ -1576,7 +1582,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 {
@@ -1584,6 +1590,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.