[Mesa-dev] [PATCH 1/5] i965: Keep pointers to IF/ELSE/ENDIF instructions in the cfg.

Matt Turner mattst88 at gmail.com
Fri Nov 1 02:57:22 CET 2013


Useful for finding the associated control flow instructions, given a
block ending in one.
---
 src/mesa/drivers/dri/i965/brw_cfg.cpp | 34 ++++++++++++++++++++++++++++++----
 src/mesa/drivers/dri/i965/brw_cfg.h   | 10 ++++++++++
 2 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_cfg.cpp b/src/mesa/drivers/dri/i965/brw_cfg.cpp
index e9d2bb8..7e0e9a9 100644
--- a/src/mesa/drivers/dri/i965/brw_cfg.cpp
+++ b/src/mesa/drivers/dri/i965/brw_cfg.cpp
@@ -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
@@ -90,6 +94,7 @@ cfg_t::create(void *parent_mem_ctx, exec_list *instructions)
    bblock_t *entry = new_block();
    bblock_t *cur_if = NULL, *cur_else = NULL, *cur_endif = NULL;
    bblock_t *cur_do = NULL, *cur_while = NULL;
+   backend_instruction *if_inst = NULL, *else_inst = NULL, *endif_inst = NULL;
    exec_list if_stack, else_stack, endif_stack, do_stack, while_stack;
    bblock_t *next;
 
@@ -121,6 +126,10 @@ cfg_t::create(void *parent_mem_ctx, exec_list *instructions)
 	  */
 	 cur_endif = new_block();
 
+         if_inst = cur->end;
+         else_inst = NULL;
+         endif_inst = NULL;
+
 	 /* Set up our immediately following block, full of "then"
 	  * instructions.
 	  */
@@ -134,6 +143,8 @@ cfg_t::create(void *parent_mem_ctx, exec_list *instructions)
       case BRW_OPCODE_ELSE:
 	 cur->add_successor(mem_ctx, cur_endif);
 
+         else_inst = cur->end;
+
 	 next = new_block();
 	 next->start = (backend_instruction *)inst->next;
 	 cur_if->add_successor(mem_ctx, next);
@@ -142,20 +153,35 @@ 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);
+
+         endif_inst = cur->end;
 	 set_next_block(cur_endif);
 
-	 if (!cur_else)
+         cur_if->if_inst = if_inst;
+         cur_if->else_inst = else_inst;
+         cur_if->endif_inst = endif_inst;
+
+	 if (!cur_else) {
 	    cur_if->add_successor(mem_ctx, cur_endif);
+         } else {
+            cur_else->if_inst = if_inst ;
+            cur_else->else_inst = else_inst;
+            cur_else->endif_inst = endif_inst;
+         }
+
+         cur->if_inst = if_inst;
+         cur->else_inst = else_inst;
+         cur->endif_inst = endif_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.
diff --git a/src/mesa/drivers/dri/i965/brw_cfg.h b/src/mesa/drivers/dri/i965/brw_cfg.h
index ec5a3a0..2ea492e 100644
--- a/src/mesa/drivers/dri/i965/brw_cfg.h
+++ b/src/mesa/drivers/dri/i965/brw_cfg.h
@@ -56,6 +56,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 basic blocks ending in 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 {
-- 
1.8.3.2



More information about the mesa-dev mailing list