From 158ac265dfd0647830e8bca3e7fecc92e7fa421b Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 23 Aug 2023 02:19:06 -0700 Subject: [PATCH] intel/fs: Make helpers for saving/restoring instruction order This moves a bit of code out of a large function, but also lets us reuse it a few extra places in the next commit. I opted to stop using ralloc here since this is short-lived data that doesn't need to stick around for the rest of the compile, and it's easy enough to free. Reviewed-by: Emma Anholt Part-of: --- src/intel/compiler/brw_fs.cpp | 59 +++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp index 54d0093..a7f2886 100644 --- a/src/intel/compiler/brw_fs.cpp +++ b/src/intel/compiler/brw_fs.cpp @@ -6736,6 +6736,42 @@ fs_visitor::compute_max_register_pressure() return max_pressure; } +static fs_inst ** +save_instruction_order(const struct cfg_t *cfg) +{ + /* Before we schedule anything, stash off the instruction order as an array + * of fs_inst *. This way, we can reset it between scheduling passes to + * prevent dependencies between the different scheduling modes. + */ + int num_insts = cfg->last_block()->end_ip + 1; + fs_inst **inst_arr = new fs_inst * [num_insts]; + + int ip = 0; + foreach_block_and_inst(block, fs_inst, inst, cfg) { + assert(ip >= block->start_ip && ip <= block->end_ip); + inst_arr[ip++] = inst; + } + assert(ip == num_insts); + + return inst_arr; +} + +static void +restore_instruction_order(struct cfg_t *cfg, fs_inst **inst_arr) +{ + int num_insts = cfg->last_block()->end_ip + 1; + + int ip = 0; + foreach_block (block, cfg) { + block->instructions.make_empty(); + + assert(ip == block->start_ip); + for (; ip <= block->end_ip; ip++) + block->instructions.push_tail(inst_arr[ip]); + } + assert(ip == num_insts); +} + void fs_visitor::allocate_registers(bool allow_spilling) { @@ -6769,15 +6805,7 @@ fs_visitor::allocate_registers(bool allow_spilling) * of fs_inst *. This way, we can reset it between scheduling passes to * prevent dependencies between the different scheduling modes. */ - int num_insts = cfg->last_block()->end_ip + 1; - fs_inst **inst_arr = ralloc_array(mem_ctx, fs_inst *, num_insts); - - int ip = 0; - foreach_block_and_inst(block, fs_inst, inst, cfg) { - assert(ip >= block->start_ip && ip <= block->end_ip); - inst_arr[ip++] = inst; - } - assert(ip == num_insts); + fs_inst **orig_order = save_instruction_order(cfg); /* Try each scheduling heuristic to see if it can successfully register * allocate without spilling. They should be ordered by decreasing @@ -6788,16 +6816,7 @@ fs_visitor::allocate_registers(bool allow_spilling) if (i > 0) { /* Unless we're the first pass, reset back to the original order */ - ip = 0; - foreach_block (block, cfg) { - block->instructions.make_empty(); - - assert(ip == block->start_ip); - for (; ip <= block->end_ip; ip++) - block->instructions.push_tail(inst_arr[ip]); - } - assert(ip == num_insts); - + restore_instruction_order(cfg, orig_order); invalidate_analysis(DEPENDENCY_INSTRUCTIONS); } @@ -6821,6 +6840,8 @@ fs_visitor::allocate_registers(bool allow_spilling) break; } + delete[] orig_order; + if (!allocated) { fail("Failure to register allocate. Reduce number of " "live scalar values to avoid this."); -- 2.7.4