bool fs_visitor::opt_saturate_propagation() { bool progress = false; calculate_live_intervals(); cfg_t cfg(&instructions); for (int b = 0; b < cfg.num_blocks; b++) { progress = opt_saturate_propagation_local(this, cfg.blocks[b]) || progress; } if (progress) invalidate_live_intervals(); return progress; }
bool fs_visitor::dead_code_eliminate() { bool progress = false; calculate_live_intervals(); int num_vars = live_intervals->num_vars; BITSET_WORD *live = ralloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars)); foreach_block (block, cfg) { memcpy(live, live_intervals->bd[block->num].liveout, sizeof(BITSET_WORD) * BITSET_WORDS(num_vars)); foreach_inst_in_block_reverse(fs_inst, inst, block) { if (inst->dst.file == GRF && !inst->has_side_effects() && !inst->writes_flag()) { bool result_live = false; if (inst->regs_written == 1) { int var = live_intervals->var_from_reg(&inst->dst); result_live = BITSET_TEST(live, var); } else { int var = live_intervals->var_from_vgrf[inst->dst.reg]; for (int i = 0; i < inst->regs_written; i++) { result_live = result_live || BITSET_TEST(live, var + i); } } if (!result_live) { progress = true; if (inst->writes_accumulator) { inst->dst = fs_reg(retype(brw_null_reg(), inst->dst.type)); } else { inst->opcode = BRW_OPCODE_NOP; continue; } } } if (inst->dst.file == GRF) { if (!inst->is_partial_write()) { int var = live_intervals->var_from_vgrf[inst->dst.reg]; for (int i = 0; i < inst->regs_written; i++) { BITSET_CLEAR(live, var + inst->dst.reg_offset + i); } } } for (int i = 0; i < inst->sources; i++) { if (inst->src[i].file == GRF) { int var = live_intervals->var_from_vgrf[inst->src[i].reg]; for (int j = 0; j < inst->regs_read(this, i); j++) { BITSET_SET(live, var + inst->src[i].reg_offset + j); } } } } }