diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.cpp | 62 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_shader.h | 1 |
3 files changed, 44 insertions, 23 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index d004521facd..261f9061540 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -3192,6 +3192,7 @@ fs_visitor::run() { sanity_param_count = fp->Base.Parameters->NumParameters; uint32_t orig_nr_params = c->prog_data.nr_params; + bool allocated_without_spills; assign_binding_table_offsets(); @@ -3276,27 +3277,45 @@ fs_visitor::run() assign_curb_setup(); assign_urb_setup(); - schedule_instructions(SCHEDULE_PRE_NON_LIFO); + static enum instruction_scheduler_mode pre_modes[] = { + SCHEDULE_PRE, + SCHEDULE_PRE_NON_LIFO, + SCHEDULE_PRE_LIFO, + }; - if (0) - assign_regs_trivial(); - else { - if (!assign_regs(false)) { - /* Try a non-spilling register allocation again with a different - * scheduling heuristic. - */ - schedule_instructions(SCHEDULE_PRE_LIFO); - if (!assign_regs(false)) { - if (dispatch_width == 16) { - fail("Failure to register allocate. Reduce number of " - "live scalar values to avoid this."); - } else { - while (!assign_regs(true)) { - if (failed) - break; - } - } - } + /* Try each scheduling heuristic to see if it can successfully register + * allocate without spilling. They should be ordered by decreasing + * performance but increasing likelihood of allocating. + */ + for (unsigned i = 0; i < ARRAY_SIZE(pre_modes); i++) { + schedule_instructions(pre_modes[i]); + + if (0) { + assign_regs_trivial(); + allocated_without_spills = true; + } else { + allocated_without_spills = assign_regs(false); + } + if (allocated_without_spills) + break; + } + + if (!allocated_without_spills) { + /* We assume that any spilling is worse than just dropping back to + * SIMD8. There's probably actually some intermediate point where + * SIMD16 with a couple of spills is still better. + */ + if (dispatch_width == 16) { + fail("Failure to register allocate. Reduce number of " + "live scalar values to avoid this."); + } + + /* Since we're out of heuristics, just go spill registers until we + * get an allocation. + */ + while (!assign_regs(true)) { + if (failed) + break; } } } @@ -3311,7 +3330,8 @@ fs_visitor::run() if (failed) return false; - schedule_instructions(SCHEDULE_POST); + if (!allocated_without_spills) + schedule_instructions(SCHEDULE_POST); if (dispatch_width == 8) { c->prog_data.reg_blocks = brw_register_blocks(grf_used); diff --git a/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp b/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp index 1050d674d8c..baf67fb1ea2 100644 --- a/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp +++ b/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp @@ -1140,10 +1140,10 @@ fs_instruction_scheduler::choose_instruction_to_schedule() { schedule_node *chosen = NULL; - if (post_reg_alloc) { + if (mode == SCHEDULE_PRE || mode == SCHEDULE_POST) { int chosen_time = 0; - /* Of the instructions closest ready to execute or the closest to + /* Of the instructions ready to execute or the closest to * being ready, choose the oldest one. */ foreach_list(node, &instructions) { diff --git a/src/mesa/drivers/dri/i965/brw_shader.h b/src/mesa/drivers/dri/i965/brw_shader.h index ae7823e4064..ff5af932e08 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.h +++ b/src/mesa/drivers/dri/i965/brw_shader.h @@ -60,6 +60,7 @@ public: }; enum instruction_scheduler_mode { + SCHEDULE_PRE, SCHEDULE_PRE_NON_LIFO, SCHEDULE_PRE_LIFO, SCHEDULE_POST, |