summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Girlin <vadimgirlin@gmail.com>2013-02-14 03:15:21 +0400
committerVadim Girlin <vadimgirlin@gmail.com>2013-02-14 03:15:21 +0400
commite4521762b84fc5885c8a860ef5e3757fc16c88c4 (patch)
treecfef5af0b4cc19ab578407b9fa56e616333f4cf3
parent8ee522a63ea9c838192ebd97c78daf6c7195a642 (diff)
-rw-r--r--src/gallium/drivers/r600/sb/sb_if_conversion.cpp105
-rw-r--r--src/gallium/drivers/r600/sb/sb_if_conversion.h1
-rw-r--r--src/gallium/drivers/r600/sb/sb_ir.cpp2
3 files changed, 96 insertions, 12 deletions
diff --git a/src/gallium/drivers/r600/sb/sb_if_conversion.cpp b/src/gallium/drivers/r600/sb/sb_if_conversion.cpp
index 72639a09b7..e195d0c408 100644
--- a/src/gallium/drivers/r600/sb/sb_if_conversion.cpp
+++ b/src/gallium/drivers/r600/sb/sb_if_conversion.cpp
@@ -37,12 +37,14 @@
#include "sb_pass.h"
#include "sb_if_conversion.h"
+#include "sb_dump.h"
+
namespace r600_sb {
using std::cerr;
-int r600_sb::if_conversion::run() {
+int if_conversion::run() {
regions_vec &rv = sh.get_regions();
@@ -62,10 +64,86 @@ int r600_sb::if_conversion::run() {
return 0;
}
-bool r600_sb::if_conversion::run_on(region_node* r) {
+unsigned if_conversion::try_convert_kills(region_node* r) {
- if (!r->phi)
- return false;
+ // handling the simplest (and probably most frequent) case only -
+ // if - 4 kills - endif
+
+ // TODO handle more complex cases
+
+ depart_node *d1 = static_cast<depart_node*>(r->front());
+ if (!d1->is_depart())
+ return 0;
+
+ if_node *f = static_cast<if_node*>(d1->front());
+ if (!f->is_if())
+ return 0;
+
+ depart_node *d2 = static_cast<depart_node*>(f->front());
+ if (!d2->is_depart())
+ return 0;
+
+ unsigned cnt = 0;
+
+ for (node_iterator I = d2->begin(), E = d2->end(); I != E; ++I) {
+ alu_node *n = static_cast<alu_node*>(*I);
+ if (!n->is_alu_inst())
+ return 0;
+
+ if (!(n->bc.op_ptr->flags & AF_KILL))
+ return 0;
+
+ if (n->bc.op_ptr->src_count != 2 || n->src.size() != 2)
+ return 0;
+
+ value *s1 = n->src[0], *s2 = n->src[1];
+
+ // assuming that the KILL with constant operands is "always kill"
+
+ if (!s1 || !s2 || !s1->is_const() || !s2->is_const())
+ return 0;
+
+ ++cnt;
+ }
+
+ if (cnt != 4)
+ return 0;
+
+ value *cond = f->cond;
+ value *pred = get_select_value_for_em(sh, cond);
+
+ if (!pred)
+ return 0;
+
+ for (node_iterator N, I = d2->begin(), E = d2->end(); I != E; I = N) {
+ N = I; ++N;
+
+ alu_node *n = static_cast<alu_node*>(*I);
+
+ IFC_DUMP(
+ cerr << "converting ";
+ dump::dump_op(n);
+ cerr << " " << n << "\n";
+ );
+
+ n->remove();
+
+ n->bc.set_op(ALU_OP2_KILLE_INT);
+ n->src[0] = pred;
+ n->src[1] = sh.get_const_value(0);
+ // reset src modifiers
+ memset(&n->bc.src[0], 0, sizeof(bc_alu_src));
+ memset(&n->bc.src[1], 0, sizeof(bc_alu_src));
+
+ r->insert_before(n);
+ }
+
+ return cnt;
+}
+
+
+
+bool if_conversion::run_on(region_node* r) {
if (r->dep_count() != 2 || r->rep_count() != 1)
return false;
@@ -74,18 +152,23 @@ bool r600_sb::if_conversion::run_on(region_node* r) {
r->collect_stats(s);
- IFC_DUMP(
- cerr << "ifcvt: region " << r->region_id << " :\n";
- s.dump();
- );
-
- if (s.alu_kill_count || s.region_count || s.fetch_count ||
+ if (s.region_count || s.fetch_count ||
s.if_count != 1 || s.repeat_count)
return false;
- if (s.alu_count > 32)
+ if (s.alu_count > 64)
return false;
+ IFC_DUMP(
+ cerr << "ifcvt: region " << r->region_id << " :\n";
+ s.dump();
+ );
+
+ if (s.alu_kill_count) {
+ unsigned kcnt = try_convert_kills(r);
+ if (kcnt < s.alu_kill_count)
+ return false;
+ }
depart_node *nd1 = static_cast<depart_node*>(r->first);
if (!nd1->is_depart())
diff --git a/src/gallium/drivers/r600/sb/sb_if_conversion.h b/src/gallium/drivers/r600/sb/sb_if_conversion.h
index 822ca79058..a5588cbbb7 100644
--- a/src/gallium/drivers/r600/sb/sb_if_conversion.h
+++ b/src/gallium/drivers/r600/sb/sb_if_conversion.h
@@ -42,6 +42,7 @@ public:
alu_node* convert_phi(value *select, node *phi);
+ unsigned try_convert_kills(region_node* r);
};
diff --git a/src/gallium/drivers/r600/sb/sb_ir.cpp b/src/gallium/drivers/r600/sb/sb_ir.cpp
index 2474b4008e..98cca5e72b 100644
--- a/src/gallium/drivers/r600/sb/sb_ir.cpp
+++ b/src/gallium/drivers/r600/sb/sb_ir.cpp
@@ -476,7 +476,7 @@ void region_node::expand_repeat(repeat_node *r) {
void node_stats::dump() {
cerr << " alu_count : " << alu_count << "\n";
- cerr << " alu_side_effect_count : " << alu_kill_count << "\n";
+ cerr << " alu_kill_count : " << alu_kill_count << "\n";
cerr << " cf_count : " << cf_count << "\n";
cerr << " fetch_count : " << fetch_count << "\n";
cerr << " region_count : " << region_count << "\n";