summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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.