diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp index 7b03258ef51..713d92d14e6 100644 --- a/src/intel/compiler/brw_fs.cpp +++ b/src/intel/compiler/brw_fs.cpp @@ -1515,7 +1515,7 @@ brw::register_pressure::register_pressure(const fs_visitor *v) const unsigned payload_count = v->first_non_payload_grf; int *payload_last_use_ip = new int[payload_count]; - v->calculate_payload_ranges(payload_count, payload_last_use_ip); + v->calculate_payload_ranges(true, payload_count, payload_last_use_ip); for (unsigned reg = 0; reg < payload_count; reg++) { for (int ip = 0; ip < payload_last_use_ip[reg]; ip++) diff --git a/src/intel/compiler/brw_fs.h b/src/intel/compiler/brw_fs.h index 4a3e73db863..4c3730e92c1 100644 --- a/src/intel/compiler/brw_fs.h +++ b/src/intel/compiler/brw_fs.h @@ -294,7 +294,8 @@ public: void assign_curb_setup(); void convert_attr_sources_to_hw_regs(fs_inst *inst); - void calculate_payload_ranges(unsigned payload_node_count, + void calculate_payload_ranges(bool allow_spilling, + unsigned payload_node_count, int *payload_last_use_ip) const; void assign_constant_locations(); bool get_pull_locs(const brw_reg &src, unsigned *out_surf_index, diff --git a/src/intel/compiler/brw_fs_reg_allocate.cpp b/src/intel/compiler/brw_fs_reg_allocate.cpp index b08820bedd9..7785314a136 100644 --- a/src/intel/compiler/brw_fs_reg_allocate.cpp +++ b/src/intel/compiler/brw_fs_reg_allocate.cpp @@ -151,7 +151,8 @@ count_to_loop_end(const bblock_t *block) unreachable("not reached"); } -void fs_visitor::calculate_payload_ranges(unsigned payload_node_count, +void fs_visitor::calculate_payload_ranges(bool allow_spilling, + unsigned payload_node_count, int *payload_last_use_ip) const { int loop_depth = 0; @@ -226,18 +227,16 @@ void fs_visitor::calculate_payload_ranges(unsigned payload_node_count, if (inst->send_ex_desc_scratch) payload_last_use_ip[0] = use_ip; - if (inst->eot) { - /* We could omit this for the !inst->header_present case, except - * that the simulator apparently incorrectly reads from g0/g1 - * instead of sideband. It also really freaks out driver - * developers to see g0 used in unusual places, so just always - * reserve it. - */ - payload_last_use_ip[0] = use_ip; - } - ip++; } + + /* g0 is needed to construct scratch headers for spilling. While we could + * extend its live range each time we spill a register, and update the + * interference graph accordingly, this would get pretty messy. Instead, + * simply consider g0 live for the whole program if spilling is required. + */ + if (allow_spilling) + payload_last_use_ip[0] = ip - 1; } class fs_reg_alloc { @@ -292,7 +291,7 @@ private: int node_start_ip, int node_end_ip); void setup_inst_interference(const fs_inst *inst); - void build_interference_graph(); + void build_interference_graph(bool allow_spilling); brw_reg build_lane_offsets(const fs_builder &bld, uint32_t spill_offset, int ip); @@ -513,7 +512,7 @@ fs_reg_alloc::setup_inst_interference(const fs_inst *inst) } void -fs_reg_alloc::build_interference_graph() +fs_reg_alloc::build_interference_graph(bool allow_spilling) { /* Compute the RA node layout */ node_count = 0; @@ -528,7 +527,7 @@ fs_reg_alloc::build_interference_graph() last_vgrf_node = node_count - 1; first_spill_node = node_count; - fs->calculate_payload_ranges(payload_node_count, + fs->calculate_payload_ranges(allow_spilling, payload_node_count, payload_last_use_ip); assert(g == NULL); @@ -1069,7 +1068,7 @@ fs_reg_alloc::spill_reg(unsigned spill_reg) bool fs_reg_alloc::assign_regs(bool allow_spilling, bool spill_all) { - build_interference_graph(); + build_interference_graph(allow_spilling); unsigned spilled = 0; while (1) { diff --git a/src/intel/compiler/brw_schedule_instructions.cpp b/src/intel/compiler/brw_schedule_instructions.cpp index 3ed706216f1..4e27c856fc2 100644 --- a/src/intel/compiler/brw_schedule_instructions.cpp +++ b/src/intel/compiler/brw_schedule_instructions.cpp @@ -848,7 +848,7 @@ instruction_scheduler::setup_liveness(cfg_t *cfg) } int payload_last_use_ip[hw_reg_count]; - s->calculate_payload_ranges(hw_reg_count, payload_last_use_ip); + s->calculate_payload_ranges(true, hw_reg_count, payload_last_use_ip); for (unsigned i = 0; i < hw_reg_count; i++) { if (payload_last_use_ip[i] == -1)