Mesa (master): r600g/sb: fix issues with loops created for switch

Dave Airlie airlied at kemper.freedesktop.org
Tue Dec 16 02:45:15 UTC 2014


Module: Mesa
Branch: master
Commit: de0fd375f6de8f3357d05decc4a7dc231c679645
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=de0fd375f6de8f3357d05decc4a7dc231c679645

Author: Vadim Girlin <vadimgirlin at gmail.com>
Date:   Wed Dec 10 14:41:10 2014 +0300

r600g/sb: fix issues with loops created for switch

Signed-off-by: Dave Airlie <airlied at redhat.com>

---

 src/gallium/drivers/r600/sb/sb_bc_finalize.cpp   |    2 ++
 src/gallium/drivers/r600/sb/sb_bc_parser.cpp     |    2 ++
 src/gallium/drivers/r600/sb/sb_if_conversion.cpp |    4 ++--
 src/gallium/drivers/r600/sb/sb_ir.h              |    9 +++++++--
 src/gallium/drivers/r600/sb/sb_sched.cpp         |    3 +++
 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 f0849ca..3f362c4 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 d787e5b..403f938 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 93edace..3f2b1b1 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 85c3d06..711c2eb 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 1413916..4fbdc4f 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) {




More information about the mesa-commit mailing list