summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/sb
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r600/sb')
-rw-r--r--src/gallium/drivers/r600/sb/sb_dce_cleanup.cpp25
-rw-r--r--src/gallium/drivers/r600/sb/sb_gcm.cpp7
-rw-r--r--src/gallium/drivers/r600/sb/sb_ir.cpp4
-rw-r--r--src/gallium/drivers/r600/sb/sb_ir.h14
-rw-r--r--src/gallium/drivers/r600/sb/sb_pass.h6
-rw-r--r--src/gallium/drivers/r600/sb/sb_valtable.cpp42
6 files changed, 68 insertions, 30 deletions
diff --git a/src/gallium/drivers/r600/sb/sb_dce_cleanup.cpp b/src/gallium/drivers/r600/sb/sb_dce_cleanup.cpp
index 79aef9106a4..abae2bf69d7 100644
--- a/src/gallium/drivers/r600/sb/sb_dce_cleanup.cpp
+++ b/src/gallium/drivers/r600/sb/sb_dce_cleanup.cpp
@@ -30,6 +30,18 @@
namespace r600_sb {
+int dce_cleanup::run() {
+ int r;
+
+ // Run cleanup for as long as there are unused nodes.
+ do {
+ nodes_changed = false;
+ r = vpass::run();
+ } while (r == 0 && nodes_changed);
+
+ return r;
+}
+
bool dce_cleanup::visit(node& n, bool enter) {
if (enter) {
} else {
@@ -110,7 +122,18 @@ bool dce_cleanup::visit(region_node& n, bool enter) {
void dce_cleanup::cleanup_dst(node& n) {
if (!cleanup_dst_vec(n.dst) && remove_unused &&
!n.dst.empty() && !(n.flags & NF_DONT_KILL) && n.parent)
+ {
+ // Delete use references to the removed node from the src values.
+ for (vvec::iterator I = n.src.begin(), E = n.src.end(); I != E; ++I) {
+ value* v = *I;
+ if (v && v->def && v->uses.size())
+ {
+ v->remove_use(&n);
+ }
+ }
n.remove();
+ nodes_changed = true;
+ }
}
bool dce_cleanup::visit(container_node& n, bool enter) {
@@ -130,7 +153,7 @@ bool dce_cleanup::cleanup_dst_vec(vvec& vv) {
if (v->gvn_source && v->gvn_source->is_dead())
v->gvn_source = NULL;
- if (v->is_dead() || (remove_unused && !v->is_rel() && !v->uses))
+ if (v->is_dead() || (remove_unused && !v->is_rel() && !v->uses.size()))
v = NULL;
else
alive = true;
diff --git a/src/gallium/drivers/r600/sb/sb_gcm.cpp b/src/gallium/drivers/r600/sb/sb_gcm.cpp
index 236b2ea0031..9c75389ada0 100644
--- a/src/gallium/drivers/r600/sb/sb_gcm.cpp
+++ b/src/gallium/drivers/r600/sb/sb_gcm.cpp
@@ -199,10 +199,9 @@ void gcm::td_release_val(value *v) {
sblog << "\n";
);
- use_info *u = v->uses;
- while (u) {
+ for (uselist::iterator I = v->uses.begin(), E = v->uses.end(); I != E; ++I) {
+ use_info *u = *I;
if (u->op->parent != &pending) {
- u = u->next;
continue;
}
@@ -212,6 +211,7 @@ void gcm::td_release_val(value *v) {
sblog << "\n";
);
+ assert(uses[u->op] > 0);
if (--uses[u->op] == 0) {
GCM_DUMP(
sblog << "td released : ";
@@ -222,7 +222,6 @@ void gcm::td_release_val(value *v) {
pending.remove_node(u->op);
ready.push_back(u->op);
}
- u = u->next;
}
}
diff --git a/src/gallium/drivers/r600/sb/sb_ir.cpp b/src/gallium/drivers/r600/sb/sb_ir.cpp
index 5226893de75..d989dce62c9 100644
--- a/src/gallium/drivers/r600/sb/sb_ir.cpp
+++ b/src/gallium/drivers/r600/sb/sb_ir.cpp
@@ -255,7 +255,7 @@ void container_node::expand() {
void node::remove() {parent->remove_node(this);
}
-value_hash node::hash_src() {
+value_hash node::hash_src() const {
value_hash h = 12345;
@@ -269,7 +269,7 @@ value_hash node::hash_src() {
}
-value_hash node::hash() {
+value_hash node::hash() const {
if (parent && parent->subtype == NST_LOOP_PHI_CONTAINER)
return 47451;
diff --git a/src/gallium/drivers/r600/sb/sb_ir.h b/src/gallium/drivers/r600/sb/sb_ir.h
index 4fc4da2fb21..74c0549a813 100644
--- a/src/gallium/drivers/r600/sb/sb_ir.h
+++ b/src/gallium/drivers/r600/sb/sb_ir.h
@@ -446,15 +446,16 @@ enum use_kind {
};
struct use_info {
- use_info *next;
node *op;
use_kind kind;
int arg;
- use_info(node *n, use_kind kind, int arg, use_info* next)
- : next(next), op(n), kind(kind), arg(arg) {}
+ use_info(node *n, use_kind kind, int arg)
+ : op(n), kind(kind), arg(arg) {}
};
+typedef std::list< use_info * > uselist;
+
enum constraint_kind {
CK_SAME_REG,
CK_PACKED_BS,
@@ -498,7 +499,7 @@ public:
value_hash ghash;
node *def, *adef;
- use_info *uses;
+ uselist uses;
ra_constraint *constraint;
ra_chunk *chunk;
@@ -585,6 +586,7 @@ public:
}
void add_use(node *n, use_kind kind, int arg);
+ void remove_use(const node *n);
value_hash hash();
value_hash rel_hash();
@@ -790,8 +792,8 @@ public:
void replace_with(node *n);
void remove();
- virtual value_hash hash();
- value_hash hash_src();
+ virtual value_hash hash() const;
+ value_hash hash_src() const;
virtual bool fold_dispatch(expr_handler *ex);
diff --git a/src/gallium/drivers/r600/sb/sb_pass.h b/src/gallium/drivers/r600/sb/sb_pass.h
index 0346df1b167..e878f8c70ca 100644
--- a/src/gallium/drivers/r600/sb/sb_pass.h
+++ b/src/gallium/drivers/r600/sb/sb_pass.h
@@ -124,7 +124,9 @@ class dce_cleanup : public vpass {
public:
dce_cleanup(shader &s) : vpass(s),
- remove_unused(s.dce_flags & DF_REMOVE_UNUSED) {}
+ remove_unused(s.dce_flags & DF_REMOVE_UNUSED), nodes_changed(false) {}
+
+ virtual int run();
virtual bool visit(node &n, bool enter);
virtual bool visit(alu_group_node &n, bool enter);
@@ -140,6 +142,8 @@ private:
void cleanup_dst(node &n);
bool cleanup_dst_vec(vvec &vv);
+ // Did we alter/remove nodes during a single pass?
+ bool nodes_changed;
};
diff --git a/src/gallium/drivers/r600/sb/sb_valtable.cpp b/src/gallium/drivers/r600/sb/sb_valtable.cpp
index eb242b1c26f..a8b7b49cd41 100644
--- a/src/gallium/drivers/r600/sb/sb_valtable.cpp
+++ b/src/gallium/drivers/r600/sb/sb_valtable.cpp
@@ -220,17 +220,33 @@ void value::add_use(node* n, use_kind kind, int arg) {
dump::dump_op(n);
sblog << " kind " << kind << " arg " << arg << "\n";
}
- uses = new use_info(n, kind, arg, uses);
+ uses.push_back(new use_info(n, kind, arg));
}
-unsigned value::use_count() {
- use_info *u = uses;
- unsigned c = 0;
- while (u) {
- ++c;
- u = u->next;
+struct use_node_comp {
+ explicit use_node_comp(const node *n) : n(n) {}
+ bool operator() (const use_info *u) {
+ return u->op->hash() == n->hash();
+ }
+
+ private:
+ const node *n;
+};
+
+void value::remove_use(const node *n) {
+ uselist::iterator it =
+ std::find_if(uses.begin(), uses.end(), use_node_comp(n));
+
+ if (it != uses.end())
+ {
+ // TODO assert((*it)->kind == kind) ?
+ // TODO assert((*it)->arg == arg) ?
+ uses.erase(it);
}
- return c;
+}
+
+unsigned value::use_count() {
+ return uses.size();
}
bool value::is_global() {
@@ -274,13 +290,7 @@ bool value::is_prealloc() {
}
void value::delete_uses() {
- use_info *u, *c = uses;
- while (c) {
- u = c->next;
- delete c;
- c = u;
- }
- uses = NULL;
+ uses.erase(uses.begin(), uses.end());
}
void ra_constraint::update_values() {
@@ -468,7 +478,7 @@ bool r600_sb::sb_value_set::add_vec(vvec& vv) {
bool r600_sb::sb_value_set::contains(value* v) {
unsigned b = v->uid - 1;
if (b < bs.size())
- return bs.get(v->uid - 1);
+ return bs.get(b);
else
return false;
}