summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Widawsky <benjamin.widawsky@intel.com>2015-06-15 19:14:24 -0700
committerBen Widawsky <benjamin.widawsky@intel.com>2015-06-15 19:14:24 -0700
commitbab87a5285c7a7255a7acf7afffd3e370a8b6264 (patch)
tree80c0a2b8492cc1919679bb910b10a26679a71433
parent8b24388647f626a5cad10fd48e61335ed26a8560 (diff)
i965/vec4: Use only one register to spill
The spilling code uses a temporary register for the scratch message. There is no reason to allocate this register multiple times, and in cases where there are a lot of scratch reads and writes, doing so is detrimental (running out of spillable registers). Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
index 5368a75bc0..913a874b75 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
@@ -342,12 +342,24 @@ vec4_visitor::spill_reg(int spill_reg_nr)
assert(alloc.sizes[spill_reg_nr] == 1);
unsigned int spill_offset = c->last_scratch++;
+ static struct {
+ int vgrf;
+ float size;
+ } scratch_reg = { -1, 0.0 };
+
/* Generate spill/unspill instructions for the objects being spilled. */
foreach_block_and_inst(block, vec4_instruction, inst, cfg) {
for (unsigned int i = 0; i < 3; i++) {
if (inst->src[i].file == GRF && inst->src[i].reg == spill_reg_nr) {
+ if (scratch_reg.size < alloc.sizes[spill_reg_nr]) {
+ scratch_reg.vgrf = alloc.allocate(1);
+ scratch_reg.size = alloc.sizes[spill_reg_nr];
+ }
+
+ assert(scratch_reg.vgrf > 0);
+
src_reg spill_reg = inst->src[i];
- inst->src[i].reg = alloc.allocate(1);
+ inst->src[i].reg = scratch_reg.vgrf;
dst_reg temp = dst_reg(inst->src[i]);
emit_scratch_read(block, inst, temp, spill_reg, spill_offset);