Previously, if we were spilling the result of a texture call, we would store all 4 regs, then for each use of one of those regs as the source of an instruction, we would unspill all 4 regs even though only one was needed.
In an app we're looking at, one shader goes from 2817 instructions to 2179, and another one successfully compiles that didn't before. --- src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp | 56 ++++++++++----------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp index 3f10ca6..ebf5eaa 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp @@ -281,24 +281,17 @@ fs_visitor::assign_regs() void fs_visitor::emit_unspill(fs_inst *inst, fs_reg dst, uint32_t spill_offset) { - int size = virtual_grf_sizes[dst.reg]; - dst.reg_offset = 0; - - for (int chan = 0; chan < size; chan++) { - fs_inst *unspill_inst = new(mem_ctx) fs_inst(FS_OPCODE_UNSPILL, - dst); - dst.reg_offset++; - unspill_inst->offset = spill_offset + chan * REG_SIZE; - unspill_inst->ir = inst->ir; - unspill_inst->annotation = inst->annotation; - - /* Choose a MRF that won't conflict with an MRF that's live across the - * spill. Nothing else will make it up to MRF 14/15. - */ - unspill_inst->base_mrf = 14; - unspill_inst->mlen = 1; /* header contains offset */ - inst->insert_before(unspill_inst); - } + fs_inst *unspill_inst = new(mem_ctx) fs_inst(FS_OPCODE_UNSPILL, dst); + unspill_inst->offset = spill_offset; + unspill_inst->ir = inst->ir; + unspill_inst->annotation = inst->annotation; + + /* Choose a MRF that won't conflict with an MRF that's live across the + * spill. Nothing else will make it up to MRF 14/15. + */ + unspill_inst->base_mrf = 14; + unspill_inst->mlen = 1; /* header contains offset */ + inst->insert_before(unspill_inst); } int @@ -322,14 +315,12 @@ fs_visitor::choose_spill_reg(struct ra_graph *g) for (unsigned int i = 0; i < 3; i++) { if (inst->src[i].file == GRF) { - int size = virtual_grf_sizes[inst->src[i].reg]; - spill_costs[inst->src[i].reg] += size * loop_scale; + spill_costs[inst->src[i].reg] += loop_scale; } } if (inst->dst.file == GRF) { - int size = virtual_grf_sizes[inst->dst.reg]; - spill_costs[inst->dst.reg] += size * loop_scale; + spill_costs[inst->dst.reg] += inst->regs_written() * loop_scale; } switch (inst->opcode) { @@ -384,21 +375,30 @@ fs_visitor::spill_reg(int spill_reg) for (unsigned int i = 0; i < 3; i++) { if (inst->src[i].file == GRF && inst->src[i].reg == spill_reg) { - inst->src[i].reg = virtual_grf_alloc(size); - emit_unspill(inst, inst->src[i], spill_offset); + inst->src[i].reg = virtual_grf_alloc(1); + emit_unspill(inst, inst->src[i], + spill_offset + REG_SIZE * inst->src[i].reg_offset); } } if (inst->dst.file == GRF && inst->dst.reg == spill_reg) { - inst->dst.reg = virtual_grf_alloc(size); + int subset_spill_offset = (spill_offset + + REG_SIZE * inst->dst.reg_offset); + inst->dst.reg = virtual_grf_alloc(inst->regs_written()); + inst->dst.reg_offset = 0; /* Since we spill/unspill the whole thing even if we access * just a component, we may need to unspill before the * instruction we're spilling for. */ if (size != 1 || inst->predicated) { - emit_unspill(inst, inst->dst, spill_offset); + fs_reg unspill_reg = inst->dst; + for (int chan = 0; chan < inst->regs_written(); chan++) { + emit_unspill(inst, unspill_reg, + subset_spill_offset + REG_SIZE * chan); + unspill_reg.reg_offset++; + } } fs_reg spill_src = inst->dst; @@ -407,11 +407,11 @@ fs_visitor::spill_reg(int spill_reg) spill_src.negate = false; spill_src.smear = -1; - for (int chan = 0; chan < size; chan++) { + for (int chan = 0; chan < inst->regs_written(); chan++) { fs_inst *spill_inst = new(mem_ctx) fs_inst(FS_OPCODE_SPILL, reg_null_f, spill_src); spill_src.reg_offset++; - spill_inst->offset = spill_offset + chan * REG_SIZE; + spill_inst->offset = subset_spill_offset + chan * REG_SIZE; spill_inst->ir = inst->ir; spill_inst->annotation = inst->annotation; spill_inst->base_mrf = 14; -- 1.7.10 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev