r600g/sb: fix issues with loops created for switch
authorVadim Girlin <vadimgirlin@gmail.com>
Wed, 10 Dec 2014 11:41:10 +0000 (14:41 +0300)
committerDave Airlie <airlied@redhat.com>
Tue, 16 Dec 2014 02:43:31 +0000 (12:43 +1000)
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/r600/sb/sb_bc_finalize.cpp
src/gallium/drivers/r600/sb/sb_bc_parser.cpp
src/gallium/drivers/r600/sb/sb_if_conversion.cpp
src/gallium/drivers/r600/sb/sb_ir.h
src/gallium/drivers/r600/sb/sb_sched.cpp

index f0849ca6b6b9a882ea4da80c4320ca0d39921cb1..3f362c4d787949c4d899cc0e2837cf94e2a74d83 100644 (file)
@@ -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);
 
index d787e5b1238d1504f1db7acd022ffd24687aa131..403f938092e745be484b7416557d1831be3fe48c 100644 (file)
@@ -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;
 }
index 93edacec7af8251fcc98aed6a04e6d1d55168c0d..3f2b1b1b925a37085cf13628c4313ddfed5d7a9e 100644 (file)
@@ -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;
index 85c3d06ea7f4f52d172ca69704a832736cacc3d9..711c2eb9e35aef0a06d4353c2766b87dff548d01 100644 (file)
@@ -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;
index 1413916175594087e6f91efdf3324668aa92ac90..4fbdc4fd971d84bd95eb0feabeca0a079c2c04e3 100644 (file)
@@ -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) {