diff options
author | Vadim Girlin <vadimgirlin@gmail.com> | 2013-02-14 03:15:21 +0400 |
---|---|---|
committer | Vadim Girlin <vadimgirlin@gmail.com> | 2013-02-14 03:15:21 +0400 |
commit | e4521762b84fc5885c8a860ef5e3757fc16c88c4 (patch) | |
tree | cfef5af0b4cc19ab578407b9fa56e616333f4cf3 | |
parent | 8ee522a63ea9c838192ebd97c78daf6c7195a642 (diff) |
wipr600-sb-wip
-rw-r--r-- | src/gallium/drivers/r600/sb/sb_if_conversion.cpp | 105 | ||||
-rw-r--r-- | src/gallium/drivers/r600/sb/sb_if_conversion.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/r600/sb/sb_ir.cpp | 2 |
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"; |