void
fs_instruction_scheduler::calculate_deps()
{
+ const bool gen6plus = v->brw->gen >= 6;
+
/* Pre-register-allocation, this tracks the last write per VGRF (so
* different reg_offsets within it can interfere when they shouldn't).
* After register allocation, reg_offsets are gone and we track individual
schedule_node *last_grf_write[grf_count];
schedule_node *last_mrf_write[BRW_MAX_MRF];
schedule_node *last_conditional_mod[2] = { NULL, NULL };
+ schedule_node *last_accumulator_write = NULL;
/* Fixed HW registers are assumed to be separate from the virtual
* GRFs, so they can be tracked separately. We don't really write
* to fixed GRFs much, so don't bother tracking them on a more
} else {
add_dep(last_fixed_grf_write, n);
}
+ } else if (inst->src[i].is_accumulator() && gen6plus) {
+ add_dep(last_accumulator_write, n);
} else if (inst->src[i].file != BAD_FILE &&
inst->src[i].file != IMM &&
inst->src[i].file != UNIFORM) {
add_dep(last_conditional_mod[inst->flag_subreg], n);
}
+ if (inst->reads_accumulator_implicitly()) {
+ if (gen6plus) {
+ add_dep(last_accumulator_write, n);
+ } else {
+ add_barrier_deps(n);
+ }
+ }
+
/* write-after-write deps. */
if (inst->dst.file == GRF) {
if (post_reg_alloc) {
} else {
last_fixed_grf_write = n;
}
+ } else if (inst->dst.is_accumulator() && gen6plus) {
+ add_dep(last_accumulator_write, n);
+ last_accumulator_write = n;
} else if (inst->dst.file != BAD_FILE) {
add_barrier_deps(n);
}
add_dep(last_conditional_mod[inst->flag_subreg], n, 0);
last_conditional_mod[inst->flag_subreg] = n;
}
+
+ if (inst->writes_accumulator) {
+ if (gen6plus) {
+ add_dep(last_accumulator_write, n);
+ last_accumulator_write = n;
+ } else {
+ add_barrier_deps(n);
+ }
+ }
}
/* bottom-to-top dependencies: WAR */
memset(last_grf_write, 0, sizeof(last_grf_write));
memset(last_mrf_write, 0, sizeof(last_mrf_write));
memset(last_conditional_mod, 0, sizeof(last_conditional_mod));
+ last_accumulator_write = NULL;
last_fixed_grf_write = NULL;
exec_node *node;
} else {
add_dep(n, last_fixed_grf_write);
}
+ } else if (inst->src[i].is_accumulator() && gen6plus) {
+ add_dep(n, last_accumulator_write);
} else if (inst->src[i].file != BAD_FILE &&
inst->src[i].file != IMM &&
inst->src[i].file != UNIFORM) {
add_dep(n, last_conditional_mod[inst->flag_subreg]);
}
+ if (inst->reads_accumulator_implicitly()) {
+ if (gen6plus) {
+ add_dep(n, last_accumulator_write);
+ } else {
+ add_barrier_deps(n);
+ }
+ }
+
/* Update the things this instruction wrote, so earlier reads
* can mark this as WAR dependency.
*/
} else {
last_fixed_grf_write = n;
}
+ } else if (inst->dst.is_accumulator() && gen6plus) {
+ last_accumulator_write = n;
} else if (inst->dst.file != BAD_FILE) {
add_barrier_deps(n);
}
if (inst->writes_flag()) {
last_conditional_mod[inst->flag_subreg] = n;
}
+
+ if (inst->writes_accumulator) {
+ if (gen6plus) {
+ last_accumulator_write = n;
+ } else {
+ add_barrier_deps(n);
+ }
+ }
}
}
void
vec4_instruction_scheduler::calculate_deps()
{
+ const bool gen6plus = v->brw->gen >= 6;
+
schedule_node *last_grf_write[grf_count];
schedule_node *last_mrf_write[BRW_MAX_MRF];
schedule_node *last_conditional_mod = NULL;
+ schedule_node *last_accumulator_write = NULL;
/* Fixed HW registers are assumed to be separate from the virtual
* GRFs, so they can be tracked separately. We don't really write
* to fixed GRFs much, so don't bother tracking them on a more
(inst->src[i].fixed_hw_reg.file ==
BRW_GENERAL_REGISTER_FILE)) {
add_dep(last_fixed_grf_write, n);
+ } else if (inst->src[i].is_accumulator() && gen6plus) {
+ assert(last_accumulator_write);
+ add_dep(last_accumulator_write, n);
} else if (inst->src[i].file != BAD_FILE &&
inst->src[i].file != IMM &&
inst->src[i].file != UNIFORM) {
add_dep(last_conditional_mod, n);
}
+ if (inst->reads_accumulator_implicitly()) {
+ if (gen6plus) {
+ assert(last_accumulator_write);
+ add_dep(last_accumulator_write, n);
+ } else {
+ add_barrier_deps(n);
+ }
+ }
+
/* write-after-write deps. */
if (inst->dst.file == GRF) {
add_dep(last_grf_write[inst->dst.reg], n);
} else if (inst->dst.file == HW_REG &&
inst->dst.fixed_hw_reg.file == BRW_GENERAL_REGISTER_FILE) {
last_fixed_grf_write = n;
+ } else if (inst->dst.is_accumulator() && gen6plus) {
+ add_dep(last_accumulator_write, n);
+ last_accumulator_write = n;
} else if (inst->dst.file != BAD_FILE) {
add_barrier_deps(n);
}
add_dep(last_conditional_mod, n, 0);
last_conditional_mod = n;
}
+
+ if (inst->writes_accumulator) {
+ if (gen6plus) {
+ add_dep(last_accumulator_write, n);
+ last_accumulator_write = n;
+ } else {
+ add_barrier_deps(n);
+ }
+ }
}
/* bottom-to-top dependencies: WAR */
memset(last_grf_write, 0, sizeof(last_grf_write));
memset(last_mrf_write, 0, sizeof(last_mrf_write));
last_conditional_mod = NULL;
+ last_accumulator_write = NULL;
last_fixed_grf_write = NULL;
exec_node *node;
(inst->src[i].fixed_hw_reg.file ==
BRW_GENERAL_REGISTER_FILE)) {
add_dep(n, last_fixed_grf_write);
+ } else if (inst->src[i].is_accumulator() && gen6plus) {
+ add_dep(n, last_accumulator_write);
} else if (inst->src[i].file != BAD_FILE &&
inst->src[i].file != IMM &&
inst->src[i].file != UNIFORM) {
add_dep(n, last_conditional_mod);
}
+ if (inst->reads_accumulator_implicitly()) {
+ if (gen6plus) {
+ add_dep(n, last_accumulator_write);
+ } else {
+ add_barrier_deps(n);
+ }
+ }
+
/* Update the things this instruction wrote, so earlier reads
* can mark this as WAR dependency.
*/
} else if (inst->dst.file == HW_REG &&
inst->dst.fixed_hw_reg.file == BRW_GENERAL_REGISTER_FILE) {
last_fixed_grf_write = n;
+ } else if (inst->dst.is_accumulator() && gen6plus) {
+ last_accumulator_write = n;
} else if (inst->dst.file != BAD_FILE) {
add_barrier_deps(n);
}
if (inst->writes_flag()) {
last_conditional_mod = n;
}
+
+ if (inst->writes_accumulator) {
+ if (gen6plus) {
+ last_accumulator_write = n;
+ } else {
+ add_barrier_deps(n);
+ }
+ }
}
}