* but we currently do not. It is easier for the consumers of this
* information to work with whole VGRFs.
*
- * However, we internally track use/def information at the per-component
- * (reg_offset) level for greater accuracy. Large VGRFs may be accessed
- * piecemeal over many (possibly non-adjacent) instructions. In this case,
- * examining a single instruction is insufficient to decide whether a whole
- * VGRF is ultimately used or defined. Tracking individual components
- * allows us to easily assemble this information.
+ * However, we internally track use/def information at the per-GRF level for
+ * greater accuracy. Large VGRFs may be accessed piecemeal over many
+ * (possibly non-adjacent) instructions. In this case, examining a single
+ * instruction is insufficient to decide whether a whole VGRF is ultimately
+ * used or defined. Tracking individual components allows us to easily
+ * assemble this information.
*
* See Muchnick's Advanced Compiler Design and Implementation, section
* 14.1 (p444).
int var = var_from_reg(reg);
assert(var < num_vars);
- /* In most cases, a register can be written over safely by the
- * same instruction that is its last use. For a single
- * instruction, the sources are dereferenced before writing of the
- * destination starts (naturally). This gets more complicated for
- * simd16, because the instruction:
- *
- * add(16) g4<1>F g4<8,8,1>F g6<8,8,1>F
- *
- * is actually decoded in hardware as:
- *
- * add(8) g4<1>F g4<8,8,1>F g6<8,8,1>F
- * add(8) g5<1>F g5<8,8,1>F g7<8,8,1>F
- *
- * Which is safe. However, if we have uniform accesses
- * happening, we get into trouble:
- *
- * add(8) g4<1>F g4<0,1,0>F g6<8,8,1>F
- * add(8) g5<1>F g4<0,1,0>F g7<8,8,1>F
- *
- * Now our destination for the first instruction overwrote the
- * second instruction's src0, and we get garbage for those 8
- * pixels. There's a similar issue for the pre-gen6
- * pixel_x/pixel_y, which are registers of 16-bit values and thus
- * would get stomped by the first decode as well.
- */
- int end_ip = ip;
- if (inst->exec_size == 16 && (reg.stride == 0 ||
- reg.type == BRW_REGISTER_TYPE_UW ||
- reg.type == BRW_REGISTER_TYPE_W ||
- reg.type == BRW_REGISTER_TYPE_UB ||
- reg.type == BRW_REGISTER_TYPE_B)) {
- end_ip++;
- }
-
start[var] = MIN2(start[var], ip);
- end[var] = MAX2(end[var], end_ip);
+ end[var] = MAX2(end[var], ip);
/* The use[] bitset marks when the block makes use of a variable (VGRF
* channel) without having completely defined that variable within the
/* The def[] bitset marks when an initialization in a block completely
* screens off previous updates of that variable (VGRF channel).
*/
- if (inst->dst.file == GRF && !inst->is_partial_write()) {
+ if (inst->dst.file == VGRF && !inst->is_partial_write()) {
if (!BITSET_TEST(bd->use, var))
BITSET_SET(bd->def, var);
}
for (unsigned int i = 0; i < inst->sources; i++) {
fs_reg reg = inst->src[i];
- if (reg.file != GRF)
+ if (reg.file != VGRF)
continue;
- for (int j = 0; j < inst->regs_read(i); j++) {
+ for (unsigned j = 0; j < regs_read(inst, i); j++) {
setup_one_read(bd, inst, ip, reg);
- reg.reg_offset++;
+ reg.offset += REG_SIZE;
}
}
- if (inst->reads_flag()) {
- /* The vertical combination predicates read f0.0 and f0.1. */
- if (inst->predicate == BRW_PREDICATE_ALIGN1_ANYV ||
- inst->predicate == BRW_PREDICATE_ALIGN1_ALLV) {
- assert(inst->flag_subreg == 0);
- if (!BITSET_TEST(bd->flag_def, 1)) {
- BITSET_SET(bd->flag_use, 1);
- }
- }
- if (!BITSET_TEST(bd->flag_def, inst->flag_subreg)) {
- BITSET_SET(bd->flag_use, inst->flag_subreg);
- }
- }
+
+ bd->flag_use[0] |= inst->flags_read(v->devinfo) & ~bd->flag_def[0];
/* Set def[] for this instruction */
- if (inst->dst.file == GRF) {
+ if (inst->dst.file == VGRF) {
fs_reg reg = inst->dst;
- for (int j = 0; j < inst->regs_written; j++) {
+ for (unsigned j = 0; j < regs_written(inst); j++) {
setup_one_write(bd, inst, ip, reg);
- reg.reg_offset++;
+ reg.offset += REG_SIZE;
}
}
- if (inst->writes_flag()) {
- if (!BITSET_TEST(bd->flag_use, inst->flag_subreg)) {
- BITSET_SET(bd->flag_def, inst->flag_subreg);
- }
- }
+
+ if (!inst->predicate && inst->exec_size >= 8)
+ bd->flag_def[0] |= inst->flags_written() & ~bd->flag_use[0];
ip++;
}