aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Girlin <[email protected]>2014-12-10 14:41:10 +0300
committerDave Airlie <[email protected]>2014-12-16 12:43:31 +1000
commitde0fd375f6de8f3357d05decc4a7dc231c679645 (patch)
tree8e48ceeede5a60a09d2f2684243be1b76b62531d
parent34e512d9ead1a4b67cea761a05f008ff92bb368d (diff)
r600g/sb: fix issues with loops created for switch
Signed-off-by: Dave Airlie <[email protected]>
-rw-r--r--src/gallium/drivers/r600/sb/sb_bc_finalize.cpp2
-rw-r--r--src/gallium/drivers/r600/sb/sb_bc_parser.cpp2
-rw-r--r--src/gallium/drivers/r600/sb/sb_if_conversion.cpp4
-rw-r--r--src/gallium/drivers/r600/sb/sb_ir.h9
-rw-r--r--src/gallium/drivers/r600/sb/sb_sched.cpp3
5 files changed, 16 insertions, 4 deletions
diff --git a/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp b/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp
index f0849ca6b6b..3f362c4d787 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp
@@ -110,6 +110,8 @@ int bc_finalizer::run() {
void bc_finalizer::finalize_loop(region_node* r) {
+ update_nstack(r);
+
cf_node *loop_start = sh.create_cf(CF_OP_LOOP_START_DX10);
cf_node *loop_end = sh.create_cf(CF_OP_LOOP_END);
diff --git a/src/gallium/drivers/r600/sb/sb_bc_parser.cpp b/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
index d787e5b1238..403f938092e 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
@@ -758,6 +758,8 @@ int bc_parser::prepare_loop(cf_node* c) {
c->insert_before(reg);
rep->move(c, end->next);
+ reg->src_loop = true;
+
loop_stack.push(reg);
return 0;
}
diff --git a/src/gallium/drivers/r600/sb/sb_if_conversion.cpp b/src/gallium/drivers/r600/sb/sb_if_conversion.cpp
index 93edacec7af..3f2b1b1b925 100644
--- a/src/gallium/drivers/r600/sb/sb_if_conversion.cpp
+++ b/src/gallium/drivers/r600/sb/sb_if_conversion.cpp
@@ -115,13 +115,13 @@ void if_conversion::convert_kill_instructions(region_node *r,
bool if_conversion::check_and_convert(region_node *r) {
depart_node *nd1 = static_cast<depart_node*>(r->first);
- if (!nd1->is_depart())
+ if (!nd1->is_depart() || nd1->target != r)
return false;
if_node *nif = static_cast<if_node*>(nd1->first);
if (!nif->is_if())
return false;
depart_node *nd2 = static_cast<depart_node*>(nif->first);
- if (!nd2->is_depart())
+ if (!nd2->is_depart() || nd2->target != r)
return false;
value* &em = nif->cond;
diff --git a/src/gallium/drivers/r600/sb/sb_ir.h b/src/gallium/drivers/r600/sb/sb_ir.h
index 85c3d06ea7f..711c2eb9e35 100644
--- a/src/gallium/drivers/r600/sb/sb_ir.h
+++ b/src/gallium/drivers/r600/sb/sb_ir.h
@@ -1089,7 +1089,8 @@ typedef std::vector<repeat_node*> repeat_vec;
class region_node : public container_node {
protected:
region_node(unsigned id) : container_node(NT_REGION, NST_LIST), region_id(id),
- loop_phi(), phi(), vars_defined(), departs(), repeats() {}
+ loop_phi(), phi(), vars_defined(), departs(), repeats(), src_loop()
+ {}
public:
unsigned region_id;
@@ -1101,12 +1102,16 @@ public:
depart_vec departs;
repeat_vec repeats;
+ // true if region was created for loop in the parser, sometimes repeat_node
+ // may be optimized away so we need to remember this information
+ bool src_loop;
+
virtual bool accept(vpass &p, bool enter);
unsigned dep_count() { return departs.size(); }
unsigned rep_count() { return repeats.size() + 1; }
- bool is_loop() { return !repeats.empty(); }
+ bool is_loop() { return src_loop || !repeats.empty(); }
container_node* get_entry_code_location() {
node *p = first;
diff --git a/src/gallium/drivers/r600/sb/sb_sched.cpp b/src/gallium/drivers/r600/sb/sb_sched.cpp
index 14139161755..4fbdc4fd971 100644
--- a/src/gallium/drivers/r600/sb/sb_sched.cpp
+++ b/src/gallium/drivers/r600/sb/sb_sched.cpp
@@ -1527,6 +1527,9 @@ bool post_scheduler::check_copy(node *n) {
if (!s->is_prealloc()) {
recolor_local(s);
+
+ if (!s->chunk || s->chunk != d->chunk)
+ return false;
}
if (s->gpr == d->gpr) {