diff --git a/src/intel/compiler/brw_cfg.cpp b/src/intel/compiler/brw_cfg.cpp index fd88586bac7..6cbbaaf53c2 100644 --- a/src/intel/compiler/brw_cfg.cpp +++ b/src/intel/compiler/brw_cfg.cpp @@ -63,7 +63,7 @@ push_stack(exec_list *list, void *mem_ctx, bblock_t *block) } bblock_t::bblock_t(cfg_t *cfg) : - cfg(cfg), start_ip(0), end_ip(0), num(0) + cfg(cfg), start_ip(0), end_ip(0), end_ip_delta(0), num(0) { instructions.make_empty(); parents.make_empty(); diff --git a/src/intel/compiler/brw_cfg.h b/src/intel/compiler/brw_cfg.h index 591d9b4dae2..90af5a95f14 100644 --- a/src/intel/compiler/brw_cfg.h +++ b/src/intel/compiler/brw_cfg.h @@ -115,6 +115,11 @@ struct bblock_t { int start_ip; int end_ip; + /** + * Change in end_ip since the last time IPs of later blocks were updated. + */ + int end_ip_delta; + struct exec_list instructions; struct exec_list parents; struct exec_list children; diff --git a/src/intel/compiler/brw_ir.h b/src/intel/compiler/brw_ir.h index 9cb3ce10242..a8e899359e9 100644 --- a/src/intel/compiler/brw_ir.h +++ b/src/intel/compiler/brw_ir.h @@ -107,7 +107,7 @@ struct backend_instruction : public exec_node { */ bool uses_indirect_addressing() const; - void remove(bblock_t *block); + void remove(bblock_t *block, bool defer_later_block_ip_updates = false); void insert_after(bblock_t *block, backend_instruction *inst); void insert_before(bblock_t *block, backend_instruction *inst); void insert_before(bblock_t *block, exec_list *list); diff --git a/src/intel/compiler/brw_shader.cpp b/src/intel/compiler/brw_shader.cpp index 6edc53ea3dc..6ba2e7c0325 100644 --- a/src/intel/compiler/brw_shader.cpp +++ b/src/intel/compiler/brw_shader.cpp @@ -1196,6 +1196,7 @@ void backend_instruction::insert_after(bblock_t *block, backend_instruction *inst) { assert(this != inst); + assert(block->end_ip_delta == 0); if (!this->is_head_sentinel()) assert(inst_is_in_block(block, this) || !"Instruction not in block"); @@ -1211,6 +1212,7 @@ void backend_instruction::insert_before(bblock_t *block, backend_instruction *inst) { assert(this != inst); + assert(block->end_ip_delta == 0); if (!this->is_tail_sentinel()) assert(inst_is_in_block(block, this) || !"Instruction not in block"); @@ -1226,6 +1228,7 @@ void backend_instruction::insert_before(bblock_t *block, exec_list *list) { assert(inst_is_in_block(block, this) || !"Instruction not in block"); + assert(block->end_ip_delta == 0); unsigned num_inst = list->length(); @@ -1237,13 +1240,23 @@ backend_instruction::insert_before(bblock_t *block, exec_list *list) } void -backend_instruction::remove(bblock_t *block) +backend_instruction::remove(bblock_t *block, bool defer_later_block_ip_updates) { assert(inst_is_in_block(block, this) || !"Instruction not in block"); - adjust_later_block_ips(block, -1); + if (defer_later_block_ip_updates) { + block->end_ip_delta--; + } else { + assert(block->end_ip_delta == 0); + adjust_later_block_ips(block, -1); + } if (block->start_ip == block->end_ip) { + if (block->end_ip_delta != 0) { + adjust_later_block_ips(block, block->end_ip_delta); + block->end_ip_delta = 0; + } + block->cfg->remove_block(block); } else { block->end_ip--;