diff options
author | Christoph Bumiller <[email protected]> | 2012-04-29 17:56:57 +0200 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2012-04-29 17:56:57 +0200 |
commit | 00fe442253744c4c4e7e68da44d6983da053968b (patch) | |
tree | a2220fceb8ffa22edd97b4d725b4e3ee231a19d0 /src/gallium/drivers/nv50/codegen | |
parent | 163b290f886c69a233c71799613eb74fb2668085 (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')
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; |