From 369aef851dda305ab8e769e3d9e18035a3c0d0df Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 3 Jan 2020 14:53:11 -0800 Subject: [PATCH] intel/fs/gen4-6: Allocate registers from aligned_pairs_class based on LINTERP use. Previously we would hardcode fs_visitor::delta_xy barycentrics to be allocated from aligned_pairs_class on hardware with PLN source alignment restrictions (pre-Gen7). Instead allocate any registers consumed by LINTERP from aligned_pairs_class, even if some barycentric vector had ended up in a temporary. On SNB this prevents the following shader-db regressions (including SIMD32 programs) in combination with the interpolation rework part of this series: total instructions in shared programs: 13983257 -> 14527274 (3.89%) instructions in affected programs: 1766255 -> 2310272 (30.80%) helped: 0 HURT: 11608 LOST: 26 GAINED: 13 Reviewed-by: Kenneth Graunke --- src/intel/compiler/brw_fs_reg_allocate.cpp | 37 +++++++++++----------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/intel/compiler/brw_fs_reg_allocate.cpp b/src/intel/compiler/brw_fs_reg_allocate.cpp index 966080f6b6c..f53fb2bf253 100644 --- a/src/intel/compiler/brw_fs_reg_allocate.cpp +++ b/src/intel/compiler/brw_fs_reg_allocate.cpp @@ -769,32 +769,33 @@ fs_reg_alloc::build_interference_graph(bool allow_spilling) if (grf127_send_hack_node >= 0) ra_set_node_reg(g, grf127_send_hack_node, 127); + /* Specify the classes of each virtual register. */ for (unsigned i = 0; i < fs->alloc.count; i++) { unsigned size = fs->alloc.sizes[i]; - int c; assert(size <= ARRAY_SIZE(compiler->fs_reg_sets[rsi].classes) && "Register allocation relies on split_virtual_grfs()"); - c = compiler->fs_reg_sets[rsi].classes[size - 1]; - /* Special case: on pre-GEN6 hardware that supports PLN, the - * second operand of a PLN instruction needs to be an - * even-numbered register, so we have a special register class - * wm_aligned_pairs_class to handle this case. pre-GEN6 always - * uses fs->delta_xy[BRW_BARYCENTRIC_PERSPECTIVE_PIXEL] as the - * second operand of a PLN instruction (since it doesn't support - * any other interpolation modes). So all we need to do is find - * that register and set it to the appropriate class. - */ - if (compiler->fs_reg_sets[rsi].aligned_pairs_class >= 0 && - fs->delta_xy[BRW_BARYCENTRIC_PERSPECTIVE_PIXEL].file == VGRF && - fs->delta_xy[BRW_BARYCENTRIC_PERSPECTIVE_PIXEL].nr == i) { - c = compiler->fs_reg_sets[rsi].aligned_pairs_class; + ra_set_node_class(g, first_vgrf_node + i, + compiler->fs_reg_sets[rsi].classes[size - 1]); + } + + /* Special case: on pre-Gen7 hardware that supports PLN, the second operand + * of a PLN instruction needs to be an even-numbered register, so we have a + * special register class aligned_pairs_class to handle this case. + */ + if (compiler->fs_reg_sets[rsi].aligned_pairs_class >= 0) { + foreach_block_and_inst(block, fs_inst, inst, fs->cfg) { + if (inst->opcode == FS_OPCODE_LINTERP && inst->src[0].file == VGRF && + fs->alloc.sizes[inst->src[0].nr] == 2) { + ra_set_node_class(g, first_vgrf_node + inst->src[0].nr, + compiler->fs_reg_sets[rsi].aligned_pairs_class); + } } + } - ra_set_node_class(g, first_vgrf_node + i, c); - - /* Add interference based on the live range of the register */ + /* Add interference based on the live range of the register */ + for (unsigned i = 0; i < fs->alloc.count; i++) { setup_live_interference(first_vgrf_node + i, fs->virtual_grf_start[i], fs->virtual_grf_end[i]);