From 6a59659b5ca039c6e5b56e7b9f5ca0a36e6440e6 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Thu, 28 Aug 2014 23:05:49 -0400 Subject: [PATCH] nvc0/ir: avoid infinite recursion when finding first uses of tex In certain circumstances, findFirstUses could end up doubling back down 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 Signed-off-by: Ilia Mirkin --- .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp | 23 +++++++++++++++------- .../nouveau/codegen/nv50_ir_lowering_nvc0.h | 5 ++++- 2 files changed, 20 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 7da9b0b..e081d59 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp @@ -174,15 +174,22 @@ NVC0LegalizePostRA::findOverwritingDefs(const Instruction *texi, } void -NVC0LegalizePostRA::findFirstUses(const Instruction *texi, - const Instruction *insn, - std::list &uses) +NVC0LegalizePostRA::findFirstUses( + const Instruction *texi, + const Instruction *insn, + std::list &uses, + std::tr1::unordered_set& 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(); + 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) { @@ -197,11 +204,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); } @@ -257,8 +264,10 @@ NVC0LegalizePostRA::insertTextureBarriers(Function *fn) uses = new std::list[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 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) { diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h index 7f39c28..d8ff5cd 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h @@ -20,6 +20,8 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include + #include "codegen/nv50_ir.h" #include "codegen/nv50_ir_build_util.h" @@ -69,7 +71,8 @@ private: bool insertTextureBarriers(Function *); inline bool insnDominatedBy(const Instruction *, const Instruction *) const; void findFirstUses(const Instruction *tex, const Instruction *def, - std::list&); + std::list&, + std::tr1::unordered_set&); void findOverwritingDefs(const Instruction *tex, Instruction *insn, const BasicBlock *term, std::list&); -- 1.8.5.5