summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp32
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h5
2 files changed, 29 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 7da9b0be7e8..92f9a156f7c 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,31 @@ NVC0LegalizePostRA::findOverwritingDefs(const Instruction *texi,
}
void
-NVC0LegalizePostRA::findFirstUses(const Instruction *texi,
- const Instruction *insn,
- std::list<TexUse> &uses)
+NVC0LegalizePostRA::findFirstUses(
+ const Instruction *texi,
+ const Instruction *insn,
+ std::list<TexUse> &uses,
+ std::tr1::unordered_set<const Instruction *>& 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();
+ /* XXX HACK ALERT XXX
+ *
+ * This shouldn't have to be here, we should always be making forward
+ * progress by looking at the uses. However this somehow does not
+ * appear to be the case. Probably because this is being done right
+ * after RA, when the defs/uses lists have been messed with by node
+ * merging. This should probably be moved to being done right before
+ * RA. But this will do for now.
+ */
+ 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 +213,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 +273,10 @@ NVC0LegalizePostRA::insertTextureBarriers(Function *fn)
uses = new std::list<TexUse>[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<const Instruction *> 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 7f39c289554..d8ff5cd3d96 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 <tr1/unordered_set>
+
#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<TexUse>&);
+ std::list<TexUse>&,
+ std::tr1::unordered_set<const Instruction *>&);
void findOverwritingDefs(const Instruction *tex, Instruction *insn,
const BasicBlock *term,
std::list<TexUse>&);