summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Turner <[email protected]>2013-10-30 16:51:32 -0700
committerMatt Turner <[email protected]>2013-12-04 20:05:41 -0800
commited85c0f409116b42f032d0e7939d4ea55d3ca2f3 (patch)
tree390adb4207bc17455cc42ec27122c733e9eead15
parent51194932d3b866e56b0001874c28f862d382dbd3 (diff)
i965/cfg: Keep pointers to IF/ELSE/ENDIF instructions in the cfg.
Useful for finding the associated control flow instructions, given a block ending in one. Reviewed-by: Eric Anholt <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_cfg.cpp31
-rw-r--r--src/mesa/drivers/dri/i965/brw_cfg.h10
2 files changed, 38 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_cfg.cpp b/src/mesa/drivers/dri/i965/brw_cfg.cpp
index cfe43d20139..548b45899b2 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
@@ -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.
diff --git a/src/mesa/drivers/dri/i965/brw_cfg.h b/src/mesa/drivers/dri/i965/brw_cfg.h
index e667d2271b6..ad54f869883 100644
--- a/src/mesa/drivers/dri/i965/brw_cfg.h
+++ b/src/mesa/drivers/dri/i965/brw_cfg.h
@@ -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 {