i965/cfg: Keep pointers to IF/ELSE/ENDIF instructions in the cfg.
authorMatt Turner <mattst88@gmail.com>
Wed, 30 Oct 2013 23:51:32 +0000 (16:51 -0700)
committerMatt Turner <mattst88@gmail.com>
Thu, 5 Dec 2013 04:05:41 +0000 (20:05 -0800)
Useful for finding the associated control flow instructions, given a
block ending in one.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_cfg.cpp
src/mesa/drivers/dri/i965/brw_cfg.h

index cfe43d20139072716615eb9341ac6a1c82f32001..548b45899b20db2f05320d284f8ad1ffd2cc2f43 100644 (file)
@@ -28,7 +28,7 @@
 #include "brw_fs.h"
 #include "brw_cfg.h"
 
-/** @file brw_cfg_t.cpp
+/** @file brw_cfg.cpp
  *
  * Walks the shader instructions generated and creates a set of basic
  * blocks with successor/predecessor edges connecting them.
@@ -52,6 +52,10 @@ bblock_t::bblock_t() :
 
    parents.make_empty();
    children.make_empty();
+
+   if_inst = NULL;
+   else_inst = NULL;
+   endif_inst = NULL;
 }
 
 void
@@ -155,7 +159,7 @@ cfg_t::create(void *parent_mem_ctx, exec_list *instructions)
         set_next_block(next);
         break;
 
-      case BRW_OPCODE_ENDIF:
+      case BRW_OPCODE_ENDIF: {
         cur_endif->start = (backend_instruction *)inst->next;
         cur->add_successor(mem_ctx, cur_endif);
         set_next_block(cur_endif);
@@ -163,12 +167,33 @@ cfg_t::create(void *parent_mem_ctx, exec_list *instructions)
         if (!cur_else)
            cur_if->add_successor(mem_ctx, cur_endif);
 
+         backend_instruction *else_inst = cur_else ?
+            (backend_instruction *) cur_else->start->prev : NULL;
+
+         assert(cur_if->end->opcode == BRW_OPCODE_IF);
+         assert(!else_inst || else_inst->opcode == BRW_OPCODE_ELSE);
+         assert(inst->opcode == BRW_OPCODE_ENDIF);
+
+         cur_if->if_inst = cur_if->end;
+         cur_if->else_inst = else_inst;
+         cur_if->endif_inst = inst;
+
+        if (cur_else) {
+            cur_else->if_inst = cur_if->end;
+            cur_else->else_inst = else_inst;
+            cur_else->endif_inst = inst;
+         }
+
+         cur->if_inst = cur_if->end;
+         cur->else_inst = else_inst;
+         cur->endif_inst = inst;
+
         /* Pop the stack so we're in the previous if/else/endif */
         cur_if = pop_stack(&if_stack);
         cur_else = pop_stack(&else_stack);
         cur_endif = pop_stack(&endif_stack);
         break;
-
+      }
       case BRW_OPCODE_DO:
         /* Push our information onto a stack so we can recover from
          * nested loops.
index e667d2271b6ac773e43b4c5be1ca186ff5f82672..ad54f869883140102c09c85a0d2e75d61a988395 100644 (file)
@@ -57,6 +57,16 @@ public:
    exec_list parents;
    exec_list children;
    int block_num;
+
+   /* If the current basic block ends in an IF, ELSE, or ENDIF instruction,
+    * these pointers will hold the locations of the other associated control
+    * flow instructions.
+    *
+    * Otherwise they are NULL.
+    */
+   backend_instruction *if_inst;
+   backend_instruction *else_inst;
+   backend_instruction *endif_inst;
 };
 
 class cfg_t {