summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2015-12-08 18:21:26 -0500
committerIlia Mirkin <[email protected]>2015-12-08 23:15:29 -0500
commitc1c1248b94e17a1a4fa0e6f353377efa99efe602 (patch)
treed657e41fbc6988aeb88631bbbf63f066662d4d3c
parent99581ca393037e10d17aab1f4c90ff2bdb1ec557 (diff)
nv50/ir: reduce degree limit on ops that can't encode large reg dests
Operations that take immediates can only encode registers up to 64. This fixes a shader in a "Powered by Unity" intro. Signed-off-by: Ilia Mirkin <[email protected]>
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp37
1 files changed, 34 insertions, 3 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
index f5143bf3137..a7d81774a83 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
@@ -103,6 +103,8 @@ public:
void print() const;
+ const bool restrictedGPR16Range;
+
private:
BitSet bits[LAST_REGISTER_FILE + 1];
@@ -110,8 +112,6 @@ private:
int last[LAST_REGISTER_FILE + 1];
int fill[LAST_REGISTER_FILE + 1];
-
- const bool restrictedGPR16Range;
};
void
@@ -840,6 +840,32 @@ GCRA::printNodeInfo() const
}
}
+static bool
+isShortRegOp(Instruction *insn)
+{
+ // Immediates are always in src1. Every other situation can be resolved by
+ // using a long encoding.
+ return insn->srcExists(1) && insn->src(1).getFile() == FILE_IMMEDIATE;
+}
+
+// Check if this LValue is ever used in an instruction that can't be encoded
+// with long registers (i.e. > r63)
+static bool
+isShortRegVal(LValue *lval)
+{
+ if (lval->defs.size() == 0)
+ return false;
+ for (Value::DefCIterator def = lval->defs.begin();
+ def != lval->defs.end(); ++def)
+ if (isShortRegOp((*def)->getInsn()))
+ return true;
+ for (Value::UseCIterator use = lval->uses.begin();
+ use != lval->uses.end(); ++use)
+ if (isShortRegOp((*use)->getInsn()))
+ return true;
+ return false;
+}
+
void
GCRA::RIG_Node::init(const RegisterSet& regs, LValue *lval)
{
@@ -855,7 +881,12 @@ GCRA::RIG_Node::init(const RegisterSet& regs, LValue *lval)
weight = std::numeric_limits<float>::infinity();
degree = 0;
- degreeLimit = regs.getFileSize(f, lval->reg.size);
+ int size = regs.getFileSize(f, lval->reg.size);
+ // On nv50, we lose a bit of gpr encoding when there's an embedded
+ // immediate.
+ if (regs.restrictedGPR16Range && f == FILE_GPR && isShortRegVal(lval))
+ size /= 2;
+ degreeLimit = size;
degreeLimit -= relDegree[1][colors] - 1;
livei.insert(lval->livei);