summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv50/codegen
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2012-04-29 17:56:57 +0200
committerChristoph Bumiller <[email protected]>2012-04-29 17:56:57 +0200
commit00fe442253744c4c4e7e68da44d6983da053968b (patch)
treea2220fceb8ffa22edd97b4d725b4e3ee231a19d0 /src/gallium/drivers/nv50/codegen
parent163b290f886c69a233c71799613eb74fb2668085 (diff)
nvc0/ir: implement better placement of texture barriers
Put them before first uses instead of right after the texturing instruction and cull unnecessary barriers.
Diffstat (limited to 'src/gallium/drivers/nv50/codegen')
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir.h3
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_graph.cpp46
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_graph.h4
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp1
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_peephole.cpp7
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_ra.cpp2
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_util.h1
7 files changed, 58 insertions, 6 deletions
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir.h b/src/gallium/drivers/nv50/codegen/nv50_ir.h
index c299cab3f52..da9042066ad 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir.h
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir.h
@@ -135,6 +135,8 @@ enum operation
OP_LAST
};
+// various instruction-specific modifier definitions Instruction::subOp
+// MOV_FINAL marks a MOV originating from an EXPORT (used for placing TEXBARs)
#define NV50_IR_SUBOP_MUL_HIGH 1
#define NV50_IR_SUBOP_EMIT_RESTART 1
#define NV50_IR_SUBOP_LDC_IL 1
@@ -143,6 +145,7 @@ enum operation
#define NV50_IR_SUBOP_SHIFT_WRAP 1
#define NV50_IR_SUBOP_EMU_PRERET 1
#define NV50_IR_SUBOP_TEXBAR(n) n
+#define NV50_IR_SUBOP_MOV_FINAL 1
enum DataType
{
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_graph.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_graph.cpp
index 90147b6bfb8..f1bff973636 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_graph.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_graph.cpp
@@ -21,6 +21,9 @@
*/
#include "nv50_ir_graph.h"
+#include <limits>
+#include <list>
+#include "nv50_ir.h"
namespace nv50_ir {
@@ -228,8 +231,7 @@ public:
virtual bool end() const { return pos >= count; }
virtual void next() { if (pos < count) ++pos; }
virtual void *get() const { return nodes[pos]; }
-
- void reset() { pos = 0; }
+ virtual void reset() { pos = 0; }
protected:
Graph::Node **nodes;
@@ -274,6 +276,7 @@ public:
virtual void *get() const { return nodes[pos]; }
virtual bool end() const { return pos >= count; }
virtual void next() { if (pos < count) ++pos; }
+ virtual void reset() { pos = 0; }
private:
void search(Graph::Node *node, const int sequence)
@@ -389,4 +392,43 @@ void Graph::classifyDFS(Node *curr, int& seq)
curr->tag = 0;
}
+// @dist is indexed by Node::tag, returns -1 if no path found
+int
+Graph::findLightestPathWeight(Node *a, Node *b, const std::vector<int> &weight)
+{
+ std::vector<int> path(weight.size(), std::numeric_limits<int>::max());
+ std::list<Node *> nodeList;
+ const int seq = nextSequence();
+
+ path[a->tag] = 0;
+ for (Node *c = a; c && c != b;) {
+ const int p = path[c->tag] + weight[c->tag];
+ for (EdgeIterator ei = c->outgoing(); !ei.end(); ei.next()) {
+ Node *t = ei.getNode();
+ if (t->getSequence() < seq) {
+ if (path[t->tag] == std::numeric_limits<int>::max())
+ nodeList.push_front(t);
+ if (p < path[t->tag])
+ path[t->tag] = p;
+ }
+ }
+ c->visit(seq);
+ Node *next = NULL;
+ for (std::list<Node *>::iterator n = nodeList.begin();
+ n != nodeList.end(); ++n) {
+ if (!next || path[(*n)->tag] < path[next->tag])
+ next = *n;
+ if ((*n) == c) {
+ // erase visited
+ n = nodeList.erase(n);
+ --n;
+ }
+ }
+ c = next;
+ }
+ if (path[b->tag] == std::numeric_limits<int>::max())
+ return -1;
+ return path[b->tag];
+}
+
} // namespace nv50_ir
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_graph.h b/src/gallium/drivers/nv50/codegen/nv50_ir_graph.h
index cfa73c3dd1a..9ef317f943c 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_graph.h
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_graph.h
@@ -24,6 +24,7 @@
#define __NV50_IR_GRAPH_H__
#include "nv50_ir_util.h"
+#include <vector>
namespace nv50_ir {
@@ -165,6 +166,9 @@ public:
void classifyEdges();
+ // @weights: indexed by Node::tag
+ int findLightestPathWeight(Node *, Node *, const std::vector<int>& weights);
+
private:
void classifyDFS(Node *, int&);
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp
index 30d8acee3bc..27373b4cc47 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp
@@ -998,6 +998,7 @@ NV50LoweringPreSSA::handleEXPORT(Instruction *i)
int id = i->getSrc(0)->reg.data.offset / 4; // in 32 bit reg units
i->op = OP_MOV;
+ i->subOp = NV50_IR_SUBOP_MOV_FINAL;
i->src(0).set(i->src(1));
i->setSrc(1, NULL);
i->setDef(0, new_LValue(func, FILE_GPR));
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_peephole.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_peephole.cpp
index 7d0ebc69710..5bc3a450779 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_peephole.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_peephole.cpp
@@ -33,7 +33,7 @@ namespace nv50_ir {
bool
Instruction::isNop() const
{
- if (op == OP_CONSTRAINT || op == OP_PHI)
+ if (op == OP_PHI || op == OP_SPLIT || op == OP_MERGE || op == OP_CONSTRAINT)
return true;
if (terminator || join) // XXX: should terminator imply flow ?
return false;
@@ -1855,7 +1855,10 @@ FlatteningPass::visit(BasicBlock *bb)
Instruction *insn = bb->getExit();
if (insn && insn->op == OP_JOIN && !insn->getPredicate()) {
insn = insn->prev;
- if (insn && !insn->getPredicate() && !insn->asFlow() && !insn->isNop()) {
+ if (insn && !insn->getPredicate() &&
+ !insn->asFlow() &&
+ insn->op != OP_TEXBAR &&
+ !insn->isNop()) {
insn->join = 1;
bb->remove(bb->getExit());
return true;
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_ra.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_ra.cpp
index 5d2aa587a31..77edaa6067a 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_ra.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_ra.cpp
@@ -1615,7 +1615,6 @@ GCRA::resolveSplitsAndMerges()
v->join = v;
reg += v->reg.size;
}
- delete_Instruction(prog, split);
}
splits.clear();
@@ -1630,7 +1629,6 @@ GCRA::resolveSplitsAndMerges()
v->join = v;
reg += v->reg.size;
}
- delete_Instruction(prog, merge);
}
merges.clear();
}
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_util.h b/src/gallium/drivers/nv50/codegen/nv50_ir_util.h
index f348f1811b8..a0020789c11 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_util.h
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_util.h
@@ -91,6 +91,7 @@ public:
virtual void next() = 0;
virtual void *get() const = 0;
virtual bool end() const = 0; // if true, get will return 0
+ virtual void reset() { assert(0); } // only for graph iterators
};
typedef std::auto_ptr<Iterator> IteratorRef;