[Mesa-dev] [PATCH 20/21] [RFC] r600/sb: make it work?

Dave Airlie airlied at gmail.com
Wed Jan 10 06:48:59 UTC 2018


From: Dave Airlie <airlied at redhat.com>

This has some hacks in it that in the end make heaven run
---
 src/gallium/drivers/r600/sb/sb_bc_builder.cpp  |  2 +-
 src/gallium/drivers/r600/sb/sb_bc_decoder.cpp  |  1 +
 src/gallium/drivers/r600/sb/sb_bc_finalize.cpp | 10 +++++++-
 src/gallium/drivers/r600/sb/sb_gcm.cpp         | 32 +++++++++++++++++---------
 src/gallium/drivers/r600/sb/sb_gvn.cpp         |  3 +++
 src/gallium/drivers/r600/sb/sb_liveness.cpp    |  4 ++++
 src/gallium/drivers/r600/sb/sb_pass.h          |  6 ++---
 src/gallium/drivers/r600/sb/sb_ra_checker.cpp  |  5 +++-
 src/gallium/drivers/r600/sb/sb_sched.cpp       |  4 ++--
 src/gallium/drivers/r600/sb/sb_ssa_builder.cpp |  4 +++-
 src/gallium/drivers/r600/sb/sb_valtable.cpp    |  2 +-
 11 files changed, 52 insertions(+), 21 deletions(-)

diff --git a/src/gallium/drivers/r600/sb/sb_bc_builder.cpp b/src/gallium/drivers/r600/sb/sb_bc_builder.cpp
index ea91e197c0..40d950e857 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_builder.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_builder.cpp
@@ -398,7 +398,7 @@ int bc_builder::build_alu(alu_node* n) {
 			.LDS_OP((bc.op_ptr->opcode[1] >> 8) & 0xff)
 			.IDX_OFFSET_0((bc.lds_idx_offset >> 0) & 1)
 			.IDX_OFFSET_2((bc.lds_idx_offset >> 2) & 1)
-			.DST_CHAN(bc.dst_chan)
+			.DST_CHAN(0)
 			.IDX_OFFSET_3((bc.lds_idx_offset >> 3) & 1);
 
 		return 0;
diff --git a/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp b/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp
index 1fa580e66d..823b927881 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp
@@ -329,6 +329,7 @@ int bc_decoder::decode_alu(unsigned & i, bc_alu& bc) {
 			bc.src[2].sel = iw1.get_SRC2_SEL();
 			bc.src[2].rel = iw1.get_SRC2_REL();
 			bc.dst_chan = iw1.get_DST_CHAN();
+			bc.dst_gpr = 0;
 			// TODO: clean up
 			for (size_t k = 0, e = r600_alu_op_table_size(); k != e; k++) {
 				if (((r600_alu_op_table[k].opcode[1] >> 8) & 0xff) == iw1.get_LDS_OP()) {
diff --git a/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp b/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp
index 099b295f18..5b202c3737 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp
@@ -293,6 +293,10 @@ void bc_finalizer::finalize_alu_group(alu_group_node* g, node *prev_node) {
 		unsigned slot = n->bc.slot;
 		value *d = n->dst.empty() ? NULL : n->dst[0];
 
+		if (n->bc.op == LDS_OP1_LDS_READ_RET && !d) {
+			n->remove();
+			continue;
+		}
 		if (d && d->is_special_reg()) {
 			assert((n->bc.op_ptr->flags & AF_MOVA) || d->is_geometry_emit() || d->is_lds_oq() || d->is_lds_access());
 			d = NULL;
@@ -339,7 +343,8 @@ void bc_finalizer::finalize_alu_group(alu_group_node* g, node *prev_node) {
 			insert_rv6xx_load_ar_workaround(g);
 		}
 	}
-	last->bc.last = 1;
+	if (last)
+		last->bc.last = 1;
 }
 
 bool bc_finalizer::finalize_alu_src(alu_group_node* g, alu_node* a, alu_group_node *prev) {
@@ -358,6 +363,9 @@ bool bc_finalizer::finalize_alu_src(alu_group_node* g, alu_node* a, alu_group_no
 		assert(v);
 
 		bc_alu_src &src = a->bc.src[si];
+
+		if (si >= 3)
+			continue;
 		sel_chan sc;
 		src.rel = 0;
 
diff --git a/src/gallium/drivers/r600/sb/sb_gcm.cpp b/src/gallium/drivers/r600/sb/sb_gcm.cpp
index 7776a10fc8..c08648ba4a 100644
--- a/src/gallium/drivers/r600/sb/sb_gcm.cpp
+++ b/src/gallium/drivers/r600/sb/sb_gcm.cpp
@@ -158,18 +158,19 @@ void gcm::sched_early(container_node *n) {
 	}
 }
 
-void gcm::td_schedule(bb_node *bb, node *n) {
+bool gcm::td_schedule(bb_node *bb, node *n) {
+	bool pushed_front = false;
 	GCM_DUMP(
 		sblog << "scheduling : ";
 		dump::dump_op(n);
 		sblog << "\n";
 	);
-	td_release_uses(n->dst);
+	pushed_front = td_release_uses(n->dst);
 
 	bb->push_back(n);
 
 	op_map[n].top_bb = bb;
-
+	return pushed_front;
 }
 
 void gcm::td_sched_bb(bb_node* bb) {
@@ -181,8 +182,10 @@ void gcm::td_sched_bb(bb_node* bb) {
 		for (sq_iterator N, I = ready.begin(), E = ready.end(); I != E;
 				I = N) {
 			N = I; ++N;
-			td_schedule(bb, *I);
+			bool pushed_front = td_schedule(bb, *I);
 			ready.erase(I);
+			if (pushed_front)
+				break;
 		}
 	}
 }
@@ -191,7 +194,7 @@ bool gcm::td_is_ready(node* n) {
 	return uses[n] == 0;
 }
 
-void gcm::td_release_val(value *v) {
+bool gcm::td_release_val(value *v) {
 
 	GCM_DUMP(
 		sblog << "td checking uses: ";
@@ -199,6 +202,7 @@ void gcm::td_release_val(value *v) {
 		sblog << "\n";
 	);
 
+	bool pushed_front = false;
 	for (uselist::iterator I = v->uses.begin(), E = v->uses.end(); I != E; ++I) {
 		node *op = *I;
 		if (op->parent != &pending) {
@@ -220,23 +224,29 @@ void gcm::td_release_val(value *v) {
 			);
 
 			pending.remove_node(op);
-			ready.push_back(op);
+			if (op->produces_lds_oq() || op->consumes_lds_oq()) {
+				ready.push_front(op);
+				pushed_front = true;
+			} else
+				ready.push_back(op);
 		}
 	}
-
+	return pushed_front;
 }
 
-void gcm::td_release_uses(vvec& v) {
+bool gcm::td_release_uses(vvec& v) {
+	bool pushed_front = false;
 	for (vvec::iterator I = v.begin(), E = v.end(); I != E; ++I) {
 		value *v = *I;
 		if (!v)
 			continue;
 
 		if (v->is_rel())
-			td_release_uses(v->mdef);
+			pushed_front |= td_release_uses(v->mdef);
 		else
-			td_release_val(v);
+			pushed_front |= td_release_val(v);
 	}
+	return pushed_front;
 }
 
 void gcm::sched_late(container_node *n) {
@@ -637,7 +647,7 @@ void gcm::add_ready(node *n) {
 	sched_queue_id sq = sh.get_queue_id(n);
 	if (n->flags & NF_SCHEDULE_EARLY)
 		bu_ready_early[sq].push_back(n);
-	else if (sq == SQ_ALU && n->is_copy_mov())
+	else if (sq == SQ_ALU && (n->is_copy_mov() || n->consumes_lds_oq() || n->produces_lds_oq()))
 		bu_ready[sq].push_front(n);
 	else if (n->is_alu_inst()) {
 		alu_node *a = static_cast<alu_node*>(n);
diff --git a/src/gallium/drivers/r600/sb/sb_gvn.cpp b/src/gallium/drivers/r600/sb/sb_gvn.cpp
index caea4ec666..bf7b915e7a 100644
--- a/src/gallium/drivers/r600/sb/sb_gvn.cpp
+++ b/src/gallium/drivers/r600/sb/sb_gvn.cpp
@@ -133,6 +133,9 @@ bool gvn::visit(region_node& n, bool enter) {
 }
 
 bool gvn::process_src(value* &v, bool rewrite) {
+
+	if (v->is_lds_oq() || v->is_lds_access())
+		return false;
 	if (!v->gvn_source)
 		sh.vt.add_value(v);
 
diff --git a/src/gallium/drivers/r600/sb/sb_liveness.cpp b/src/gallium/drivers/r600/sb/sb_liveness.cpp
index 8ecc9a5987..2c52581054 100644
--- a/src/gallium/drivers/r600/sb/sb_liveness.cpp
+++ b/src/gallium/drivers/r600/sb/sb_liveness.cpp
@@ -217,6 +217,10 @@ void liveness::update_interferences() {
 }
 
 bool liveness::remove_val(value *v) {
+  if (v->is_lds_access()) {
+    v->flags &= ~VLF_DEAD;
+    return true;
+  }
 	if (live.remove_val(v)) {
 		v->flags &= ~VLF_DEAD;
 		return true;
diff --git a/src/gallium/drivers/r600/sb/sb_pass.h b/src/gallium/drivers/r600/sb/sb_pass.h
index a21b0bf997..b62fbaedf9 100644
--- a/src/gallium/drivers/r600/sb/sb_pass.h
+++ b/src/gallium/drivers/r600/sb/sb_pass.h
@@ -278,9 +278,9 @@ private:
 	void sched_early(container_node *n);
 	void td_sched_bb(bb_node *bb);
 	bool td_is_ready(node *n);
-	void td_release_uses(vvec &v);
-	void td_release_val(value *v);
-	void td_schedule(bb_node *bb, node *n);
+	bool td_release_uses(vvec &v);
+	bool td_release_val(value *v);
+	bool td_schedule(bb_node *bb, node *n);
 
 	void sched_late(container_node *n);
 	void bu_sched_bb(bb_node *bb);
diff --git a/src/gallium/drivers/r600/sb/sb_ra_checker.cpp b/src/gallium/drivers/r600/sb/sb_ra_checker.cpp
index 9681e69f6c..563b92a580 100644
--- a/src/gallium/drivers/r600/sb/sb_ra_checker.cpp
+++ b/src/gallium/drivers/r600/sb/sb_ra_checker.cpp
@@ -214,7 +214,10 @@ void ra_checker::check_alu_group(alu_group_node *g) {
 		process_op_dst(a);
 
 		unsigned slot = a->bc.slot;
-		prev_dst[slot] = a->dst[0];
+		if (a->dst.size())
+			prev_dst[slot] = a->dst[0];
+		else
+			prev_dst[slot] = NULL;
 	}
 }
 
diff --git a/src/gallium/drivers/r600/sb/sb_sched.cpp b/src/gallium/drivers/r600/sb/sb_sched.cpp
index f5fd84d54a..bf8f1308ee 100644
--- a/src/gallium/drivers/r600/sb/sb_sched.cpp
+++ b/src/gallium/drivers/r600/sb/sb_sched.cpp
@@ -1556,7 +1556,7 @@ void post_scheduler::recolor_locals() {
 
 	for (unsigned s = 0; s < ctx.num_slots; ++s) {
 		alu_node *n = rt.slot(s);
-		if (n) {
+		if (n && n->dst.size()) {
 			value *d = n->dst[0];
 			if (d && d->is_sgpr() && !d->is_prealloc()) {
 				recolor_local(d);
@@ -1910,7 +1910,7 @@ void post_scheduler::release_op(node *n) {
 
 	if (n->is_copy_mov()) {
 		ready_copies.push_back(n);
-	} else if (n->is_mova() || n->is_pred_set()) {
+	} else if (n->is_mova() || n->is_pred_set() || n->consumes_lds_oq() || n->produces_lds_oq()) {
 		ready.push_front(n);
 	} else {
 		ready.push_back(n);
diff --git a/src/gallium/drivers/r600/sb/sb_ssa_builder.cpp b/src/gallium/drivers/r600/sb/sb_ssa_builder.cpp
index 5cd41c2aab..239fad9d84 100644
--- a/src/gallium/drivers/r600/sb/sb_ssa_builder.cpp
+++ b/src/gallium/drivers/r600/sb/sb_ssa_builder.cpp
@@ -53,6 +53,8 @@ void ssa_prepare::add_defs(node &n) {
 		if (!v)
 			continue;
 
+		if (v->is_lds_access() || v->is_lds_oq())
+			continue;
 		if (v->is_rel()) {
 			s.add_vec(v->mdef);
 		} else
@@ -167,7 +169,7 @@ bool ssa_rename::visit(alu_node& n, bool enter) {
 
 		node *psi = NULL;
 
-		if (n.pred && n.dst[0]) {
+		if (n.pred && n.dst[0] && !n.dst[0]->is_lds_access() && !n.dst[0]->is_lds_oq()) {
 
 			value *d = n.dst[0];
 			unsigned index = get_index(rename_stack.top(), d);
diff --git a/src/gallium/drivers/r600/sb/sb_valtable.cpp b/src/gallium/drivers/r600/sb/sb_valtable.cpp
index 41cfbf0946..22ef1164c0 100644
--- a/src/gallium/drivers/r600/sb/sb_valtable.cpp
+++ b/src/gallium/drivers/r600/sb/sb_valtable.cpp
@@ -185,7 +185,7 @@ value_hash value::hash() {
 		return ghash;
 	if (is_rel())
 		ghash = rel_hash();
-	else if (def)
+	else if (def && !is_dead())
 		ghash = def->hash();
 	else
 		ghash = ((uintptr_t)this) | 1;
-- 
2.14.3



More information about the mesa-dev mailing list