[Mesa-dev] [PATCH 6/6] i965/vec4: allow partial DF register spilling
Samuel Iglesias Gonsálvez
siglesias at igalia.com
Thu Jun 15 11:15:10 UTC 2017
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>
---
src/intel/compiler/brw_vec4_reg_allocate.cpp | 32 +++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/src/intel/compiler/brw_vec4_reg_allocate.cpp b/src/intel/compiler/brw_vec4_reg_allocate.cpp
index 58cd862841..0fc9e3ca36 100644
--- a/src/intel/compiler/brw_vec4_reg_allocate.cpp
+++ b/src/intel/compiler/brw_vec4_reg_allocate.cpp
@@ -409,7 +409,9 @@ vec4_visitor::evaluate_spill_costs(float *spill_costs, bool *no_spill)
spill_costs[inst->src[i].nr] +=
loop_scale * spill_cost_for_type(inst->src[i].type);
if (inst->src[i].reladdr ||
- inst->src[i].offset >= REG_SIZE)
+ (inst->src[i].offset >= REG_SIZE &&
+ (type_sz(inst->src[i].type) != 8 ||
+ !(inst->src[i].offset == 32 && inst->group == 4))))
no_spill[inst->src[i].nr] = true;
/* We don't support unspills of partial DF reads.
@@ -419,7 +421,8 @@ vec4_visitor::evaluate_spill_costs(float *spill_costs, bool *no_spill)
* we need to shuffle into correct 64-bit data. Ensure that we
* are reading data for both threads.
*/
- if (type_sz(inst->src[i].type) == 8 && inst->exec_size != 8)
+ if (type_sz(inst->src[i].type) == 8 && inst->exec_size != 8 &&
+ (devinfo->gen != 7 || devinfo->is_haswell || inst->exec_size != 4))
no_spill[inst->src[i].nr] = true;
}
@@ -437,7 +440,10 @@ vec4_visitor::evaluate_spill_costs(float *spill_costs, bool *no_spill)
if (inst->dst.file == VGRF && !no_spill[inst->dst.nr]) {
spill_costs[inst->dst.nr] +=
loop_scale * spill_cost_for_type(inst->dst.type);
- if (inst->dst.reladdr || inst->dst.offset >= REG_SIZE)
+ if (inst->dst.reladdr ||
+ (inst->dst.offset >= REG_SIZE &&
+ (type_sz(inst->dst.type) != 8 ||
+ !(inst->dst.offset == 32 && inst->group == 4))))
no_spill[inst->dst.nr] = true;
/* We don't support spills of partial DF writes.
@@ -446,7 +452,8 @@ vec4_visitor::evaluate_spill_costs(float *spill_costs, bool *no_spill)
* each one writing that for both SIMD4x2 threads. Ensure that we
* are writing data for both threads.
*/
- if (type_sz(inst->dst.type) == 8 && inst->exec_size != 8)
+ if (type_sz(inst->dst.type) == 8 && inst->exec_size != 8 &&
+ (devinfo->gen != 7 || devinfo->is_haswell || inst->exec_size != 4))
no_spill[inst->dst.nr] = true;
/* We can't spill registers that mix 32-bit and 64-bit access (that
@@ -514,11 +521,24 @@ vec4_visitor::spill_reg(int spill_reg_nr)
/* Generate spill/unspill instructions for the objects being spilled. */
int scratch_reg = -1;
+ bool done_scratch_read = false;
foreach_block_and_inst(block, vec4_instruction, inst, cfg) {
for (unsigned int i = 0; i < 3; i++) {
if (inst->src[i].file == VGRF && inst->src[i].nr == spill_reg_nr) {
+ /* On IVB, DF scratch reads are not actual partial reads because we are
+ * going to read both GRFs on the first found instruction.
+ * Because of that, we will skip scratch read of the other splitted
+ * instruction, as it can reuse the read value. We check the value of
+ * done_scratch_read to know if we need to do scratch read or not.
+ *
+ * For the rest of generations, just return true.
+ */
+ bool do_df_scratch_read = type_sz(inst->src[i].type) == 8 &&
+ (devinfo->gen != 7 || devinfo->is_haswell || !done_scratch_read);
+
if (scratch_reg == -1 ||
- !can_use_scratch_for_source(inst, i, scratch_reg)) {
+ (!can_use_scratch_for_source(inst, i, scratch_reg) &&
+ (do_df_scratch_read || type_sz(inst->src[i].type) != 8))) {
/* We need to unspill anyway so make sure we read the full vec4
* in any case. This way, the cached register can be reused
* for consecutive instructions that read different channels of
@@ -532,6 +552,7 @@ vec4_visitor::spill_reg(int spill_reg_nr)
emit_scratch_read(block, inst,
dst_reg(temp), inst->src[i], spill_offset, false);
temp.offset = inst->src[i].offset;
+ done_scratch_read = true;
}
assert(scratch_reg != -1);
inst->src[i].nr = scratch_reg;
@@ -541,6 +562,7 @@ vec4_visitor::spill_reg(int spill_reg_nr)
if (inst->dst.file == VGRF && inst->dst.nr == spill_reg_nr) {
emit_scratch_write(block, inst, spill_offset, false);
scratch_reg = inst->dst.nr;
+ done_scratch_read = false;
}
}
--
2.11.0
More information about the mesa-dev
mailing list