Ilia Mirkin
2014-Sep-25 01:47 UTC
[Nouveau] [PATCH] 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 spilling 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> --- 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. -- 1.8.5.5
Apparently Analagous Threads
- [PATCH] nv50/ra: Only increment DefValue counter if we are going to spill
- [PATCH RESEND] nv50/ir: use unordered_set instead of list to keep track of var defs
- [PATCH] nv50/ir: use unordered_set instead of list to keep track of var defs
- [PATCH] nv50/ir: use unordered_set instead of list to keep our instructions in uses
- Regression caused by 2e9ee44797 ("nv50/ir/ra: some register spilling fixes")