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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev