using namespace brw;
-static bool
-can_do_writemask(const struct brw_device_info *devinfo,
- const vec4_instruction *inst)
-{
- switch (inst->opcode) {
- case SHADER_OPCODE_GEN4_SCRATCH_READ:
- case VS_OPCODE_PULL_CONSTANT_LOAD:
- case VS_OPCODE_PULL_CONSTANT_LOAD_GEN7:
- case VS_OPCODE_SET_SIMD4X2_HEADER_GEN9:
- return false;
- default:
- /* The MATH instruction on Gen6 only executes in align1 mode, which does
- * not support writemasking.
- */
- if (devinfo->gen == 6 && inst->is_math())
- return false;
-
- if (inst->is_tex())
- return false;
-
- return true;
- }
-}
-
bool
vec4_visitor::dead_code_eliminate()
{
calculate_live_intervals();
int num_vars = live_intervals->num_vars;
- BITSET_WORD *live = ralloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));
- BITSET_WORD *flag_live = ralloc_array(NULL, BITSET_WORD, 1);
+ BITSET_WORD *live = rzalloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));
+ BITSET_WORD *flag_live = rzalloc_array(NULL, BITSET_WORD, 1);
- foreach_block(block, cfg) {
+ foreach_block_reverse_safe(block, cfg) {
memcpy(live, live_intervals->block_data[block->num].liveout,
sizeof(BITSET_WORD) * BITSET_WORDS(num_vars));
memcpy(flag_live, live_intervals->block_data[block->num].flag_liveout,
sizeof(BITSET_WORD));
- foreach_inst_in_block_reverse(vec4_instruction, inst, block) {
+ foreach_inst_in_block_reverse_safe(vec4_instruction, inst, block) {
if ((inst->dst.file == VGRF && !inst->has_side_effects()) ||
(inst->dst.is_null() && inst->writes_flag())){
bool result_live[4] = { false };
if (inst->dst.file == VGRF) {
- for (unsigned i = 0; i < inst->regs_written; i++) {
+ for (unsigned i = 0; i < regs_written(inst); i++) {
for (int c = 0; c < 4; c++)
- result_live[c] |= BITSET_TEST(
- live, var_from_reg(alloc, offset(inst->dst, i), c));
+ result_live[c] |= BITSET_TEST(live,
+ var_from_reg(alloc,
+ byte_offset(inst->dst, i * REG_SIZE), c));
}
} else {
for (unsigned c = 0; c < 4; c++)
/* If the instruction can't do writemasking, then it's all or
* nothing.
*/
- if (!can_do_writemask(devinfo, inst)) {
+ if (!inst->can_do_writemask(devinfo)) {
bool result = result_live[0] | result_live[1] |
result_live[2] | result_live[3];
result_live[0] = result;
inst->dst = dst_reg(retype(brw_null_reg(), inst->dst.type));
} else {
inst->opcode = BRW_OPCODE_NOP;
- continue;
+ break;
}
}
}
if (!combined_live) {
inst->opcode = BRW_OPCODE_NOP;
progress = true;
- continue;
}
}
if (inst->dst.file == VGRF && !inst->predicate) {
- for (unsigned i = 0; i < inst->regs_written; i++) {
+ for (unsigned i = 0; i < regs_written(inst); i++) {
for (int c = 0; c < 4; c++) {
if (inst->dst.writemask & (1 << c)) {
- BITSET_CLEAR(live, var_from_reg(alloc,
- offset(inst->dst, i), c));
+ BITSET_CLEAR(live,
+ var_from_reg(alloc,
+ byte_offset(inst->dst,
+ i * REG_SIZE),
+ c));
}
}
}
BITSET_CLEAR(flag_live, c);
}
+ if (inst->opcode == BRW_OPCODE_NOP) {
+ inst->remove(block);
+ continue;
+ }
+
for (int i = 0; i < 3; i++) {
if (inst->src[i].file == VGRF) {
- for (unsigned j = 0; j < inst->regs_read(i); j++) {
+ for (unsigned j = 0; j < regs_read(inst, i); j++) {
for (int c = 0; c < 4; c++) {
BITSET_SET(live, var_from_reg(alloc,
- offset(inst->src[i], j), c));
+ byte_offset(inst->src[i],
+ j * REG_SIZE),
+ c));
}
}
}
ralloc_free(live);
ralloc_free(flag_live);
- if (progress) {
- foreach_block_and_inst_safe(block, backend_instruction, inst, cfg) {
- if (inst->opcode == BRW_OPCODE_NOP) {
- inst->remove(block);
- }
- }
-
+ if (progress)
invalidate_live_intervals();
- }
return progress;
}