diff --git a/src/intel/compiler/brw_disasm_info.cpp b/src/intel/compiler/brw_disasm_info.cpp index a703f63e922..4fec8307671 100644 --- a/src/intel/compiler/brw_disasm_info.cpp +++ b/src/intel/compiler/brw_disasm_info.cpp @@ -28,6 +28,54 @@ #include "dev/intel_debug.h" #include "compiler/nir/nir.h" +static bool +is_do_block(struct bblock_t *block) +{ + return block->start()->opcode == BRW_OPCODE_DO; +} + +static bool +is_flow_block(struct bblock_t *block) +{ + return block->start()->opcode == SHADER_OPCODE_FLOW; +} + +static bool +should_omit_link(struct bblock_t *block, + struct bblock_link *link) +{ + return link->kind == bblock_link_physical && + (is_do_block(block) || is_do_block(link->block)); +} + +static void +print_successors_for_disasm(struct bblock_t *block) +{ + brw_foreach_list_typed(struct bblock_link, succ, link, + &block->children) { + if (should_omit_link(block, succ)) + continue; + if (is_do_block(succ->block) || is_flow_block(succ->block)) + print_successors_for_disasm(succ->block); + else + fprintf(stderr, " ->B%d", succ->block->num); + } +} + +static void +print_predecessors_for_disasm(struct bblock_t *block) +{ + brw_foreach_list_typed(struct bblock_link, pred, link, + &block->parents) { + if (should_omit_link(block, pred)) + continue; + if (is_do_block(pred->block) || is_flow_block(pred->block)) + print_predecessors_for_disasm(pred->block); + else + fprintf(stderr, " <-B%d", pred->block->num); + } +} + void dump_assembly(void *assembly, int start_offset, int end_offset, struct disasm_info *disasm, const unsigned *block_latency) @@ -52,11 +100,7 @@ dump_assembly(void *assembly, int start_offset, int end_offset, if (group->block_start) { fprintf(stderr, " START B%d", group->block_start->num); - brw_foreach_list_typed(struct bblock_link, predecessor_link, link, - &group->block_start->parents) { - struct bblock_t *predecessor_block = predecessor_link->block; - fprintf(stderr, " <-B%d", predecessor_block->num); - } + print_predecessors_for_disasm(group->block_start); if (block_latency) fprintf(stderr, " (%u cycles)", block_latency[group->block_start->num]); @@ -78,11 +122,7 @@ dump_assembly(void *assembly, int start_offset, int end_offset, if (group->block_end) { fprintf(stderr, " END B%d", group->block_end->num); - brw_foreach_list_typed(struct bblock_link, successor_link, link, - &group->block_end->children) { - struct bblock_t *successor_block = successor_link->block; - fprintf(stderr, " ->B%d", successor_block->num); - } + print_successors_for_disasm(group->block_end); fprintf(stderr, "\n"); } } @@ -135,20 +175,15 @@ disasm_annotate(struct disasm_info *disasm, } #endif - if (cfg->blocks[disasm->cur_block]->start() == inst) { - group->block_start = cfg->blocks[disasm->cur_block]; + if (inst->opcode == BRW_OPCODE_DO || + inst->opcode == SHADER_OPCODE_FLOW) { + disasm->use_tail = true; + disasm->cur_block++; + return; } - /* There is no hardware DO instruction on Gfx6+, so since DO always - * starts a basic block, we need to set the .block_start of the next - * instruction's annotation with a pointer to the bblock started by - * the DO. - * - * There's also only complication from emitting an annotation without - * a corresponding hardware instruction to disassemble. - */ - if (inst->opcode == BRW_OPCODE_DO) { - disasm->use_tail = true; + if (cfg->blocks[disasm->cur_block]->start() == inst) { + group->block_start = cfg->blocks[disasm->cur_block]; } if (cfg->blocks[disasm->cur_block]->end() == inst) {