diff options
author | Matt Turner <[email protected]> | 2013-10-30 16:51:32 -0700 |
---|---|---|
committer | Matt Turner <[email protected]> | 2013-12-04 20:05:41 -0800 |
commit | ed85c0f409116b42f032d0e7939d4ea55d3ca2f3 (patch) | |
tree | 390adb4207bc17455cc42ec27122c733e9eead15 /src/mesa | |
parent | 51194932d3b866e56b0001874c28f862d382dbd3 (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]>
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_cfg.cpp | 31 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_cfg.h | 10 |
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 { |