From de0fd375f6de8f3357d05decc4a7dc231c679645 Mon Sep 17 00:00:00 2001 From: Vadim Girlin Date: Wed, 10 Dec 2014 14:41:10 +0300 Subject: [PATCH] r600g/sb: fix issues with loops created for switch Signed-off-by: Dave Airlie --- 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 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(r->first); - if (!nd1->is_depart()) + if (!nd1->is_depart() || nd1->target != r) return false; if_node *nif = static_cast(nd1->first); if (!nif->is_if()) return false; depart_node *nd2 = static_cast(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_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) { -- 2.30.2