intel/compiler/fs: Switch liveness analysis to IR analysis framework

This involves wrapping fs_live_variables in a BRW_ANALYSIS object and
hooking it up to invalidate_analysis() so it's properly invalidated.
Seems like a lot of churn but it's fairly straightforward.  The
fs_visitor invalidate_ and calculate_live_intervals() methods are no
longer necessary after this change.

Reviewed-by: Matt Turner <mattst88@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4012>
This commit is contained in:
Francisco Jerez
2016-03-13 16:25:57 -07:00
committed by Matt Turner
parent bb8cfa6837
commit ea44de6d8c
12 changed files with 84 additions and 97 deletions

View File

@@ -3099,7 +3099,7 @@ fs_visitor::compute_to_mrf()
if (devinfo->gen >= 7) if (devinfo->gen >= 7)
return false; return false;
calculate_live_intervals(); const fs_live_variables &live = live_analysis.require();
foreach_block_and_inst_safe(block, fs_inst, inst, cfg) { foreach_block_and_inst_safe(block, fs_inst, inst, cfg) {
int ip = next_ip; int ip = next_ip;
@@ -3117,7 +3117,7 @@ fs_visitor::compute_to_mrf()
/* Can't compute-to-MRF this GRF if someone else was going to /* Can't compute-to-MRF this GRF if someone else was going to
* read it later. * read it later.
*/ */
if (live_intervals->vgrf_end[inst->src[0].nr] > ip) if (live.vgrf_end[inst->src[0].nr] > ip)
continue; continue;
/* Found a move of a GRF to a MRF. Let's see if we can go rewrite the /* Found a move of a GRF to a MRF. Let's see if we can go rewrite the
@@ -7362,8 +7362,7 @@ fs_visitor::setup_cs_payload()
void void
fs_visitor::calculate_register_pressure() fs_visitor::calculate_register_pressure()
{ {
invalidate_analysis(DEPENDENCY_EVERYTHING); const fs_live_variables &live = live_analysis.require();
calculate_live_intervals();
unsigned num_instructions = 0; unsigned num_instructions = 0;
foreach_block(block, cfg) foreach_block(block, cfg)
@@ -7372,8 +7371,7 @@ fs_visitor::calculate_register_pressure()
regs_live_at_ip = rzalloc_array(mem_ctx, int, num_instructions); regs_live_at_ip = rzalloc_array(mem_ctx, int, num_instructions);
for (unsigned reg = 0; reg < alloc.count; reg++) { for (unsigned reg = 0; reg < alloc.count; reg++) {
for (int ip = live_intervals->vgrf_start[reg]; for (int ip = live.vgrf_start[reg]; ip <= live.vgrf_end[reg]; ip++)
ip <= live_intervals->vgrf_end[reg]; ip++)
regs_live_at_ip[ip] += alloc.sizes[reg]; regs_live_at_ip[ip] += alloc.sizes[reg];
} }
} }
@@ -7382,6 +7380,7 @@ void
fs_visitor::invalidate_analysis(brw::analysis_dependency_class c) fs_visitor::invalidate_analysis(brw::analysis_dependency_class c)
{ {
backend_shader::invalidate_analysis(c); backend_shader::invalidate_analysis(c);
live_analysis.invalidate(c);
} }
void void
@@ -7668,15 +7667,15 @@ fs_visitor::fixup_nomask_control_flow()
unsigned depth = 0; unsigned depth = 0;
bool progress = false; bool progress = false;
calculate_live_intervals(); const fs_live_variables &live_vars = live_analysis.require();
/* Scan the program backwards in order to be able to easily determine /* Scan the program backwards in order to be able to easily determine
* whether the flag register is live at any point. * whether the flag register is live at any point.
*/ */
foreach_block_reverse_safe(block, cfg) { foreach_block_reverse_safe(block, cfg) {
BITSET_WORD flag_liveout = live_intervals->block_data[block->num] BITSET_WORD flag_liveout = live_vars.block_data[block->num]
.flag_liveout[0]; .flag_liveout[0];
STATIC_ASSERT(ARRAY_SIZE(live_intervals->block_data[0].flag_liveout) == 1); STATIC_ASSERT(ARRAY_SIZE(live_vars.block_data[0].flag_liveout) == 1);
foreach_inst_in_block_reverse_safe(fs_inst, inst, block) { foreach_inst_in_block_reverse_safe(fs_inst, inst, block) {
if (!inst->predicate && inst->exec_size >= 8) if (!inst->predicate && inst->exec_size >= 8)

View File

@@ -127,13 +127,13 @@ public:
void lower_constant_loads(); void lower_constant_loads();
void invalidate_live_intervals(); void invalidate_live_intervals();
virtual void invalidate_analysis(brw::analysis_dependency_class c); virtual void invalidate_analysis(brw::analysis_dependency_class c);
void calculate_live_intervals();
void calculate_register_pressure(); void calculate_register_pressure();
void validate(); void validate();
bool opt_algebraic(); bool opt_algebraic();
bool opt_redundant_discard_jumps(); bool opt_redundant_discard_jumps();
bool opt_cse(); bool opt_cse();
bool opt_cse_local(bblock_t *block, int &ip); bool opt_cse_local(const brw::fs_live_variables &live, bblock_t *block, int &ip);
bool opt_copy_propagation(); bool opt_copy_propagation();
bool try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry); bool try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry);
bool try_constant_propagate(fs_inst *inst, acp_entry *entry); bool try_constant_propagate(fs_inst *inst, acp_entry *entry);
@@ -321,7 +321,8 @@ public:
int *param_size; int *param_size;
brw::fs_live_variables *live_intervals; BRW_ANALYSIS(live_analysis, brw::fs_live_variables,
backend_shader *) live_analysis;
int *regs_live_at_ip; int *regs_live_at_ip;

View File

@@ -94,7 +94,7 @@ class fs_copy_prop_dataflow
{ {
public: public:
fs_copy_prop_dataflow(void *mem_ctx, cfg_t *cfg, fs_copy_prop_dataflow(void *mem_ctx, cfg_t *cfg,
const fs_live_variables *live, const fs_live_variables &live,
exec_list *out_acp[ACP_HASH_SIZE]); exec_list *out_acp[ACP_HASH_SIZE]);
void setup_initial_values(); void setup_initial_values();
@@ -104,7 +104,7 @@ public:
void *mem_ctx; void *mem_ctx;
cfg_t *cfg; cfg_t *cfg;
const fs_live_variables *live; const fs_live_variables &live;
acp_entry **acp; acp_entry **acp;
int num_acp; int num_acp;
@@ -115,7 +115,7 @@ public:
} /* anonymous namespace */ } /* anonymous namespace */
fs_copy_prop_dataflow::fs_copy_prop_dataflow(void *mem_ctx, cfg_t *cfg, fs_copy_prop_dataflow::fs_copy_prop_dataflow(void *mem_ctx, cfg_t *cfg,
const fs_live_variables *live, const fs_live_variables &live,
exec_list *out_acp[ACP_HASH_SIZE]) exec_list *out_acp[ACP_HASH_SIZE])
: mem_ctx(mem_ctx), cfg(cfg), live(live) : mem_ctx(mem_ctx), cfg(cfg), live(live)
{ {
@@ -265,8 +265,8 @@ fs_copy_prop_dataflow::setup_initial_values()
for (int i = 0; i < num_acp; i++) { for (int i = 0; i < num_acp; i++) {
BITSET_SET(bd[block->num].undef, i); BITSET_SET(bd[block->num].undef, i);
for (unsigned off = 0; off < acp[i]->size_written; off += REG_SIZE) { for (unsigned off = 0; off < acp[i]->size_written; off += REG_SIZE) {
if (BITSET_TEST(live->block_data[block->num].defout, if (BITSET_TEST(live.block_data[block->num].defout,
live->var_from_reg(byte_offset(acp[i]->dst, off)))) live.var_from_reg(byte_offset(acp[i]->dst, off))))
BITSET_CLEAR(bd[block->num].undef, i); BITSET_CLEAR(bd[block->num].undef, i);
} }
} }
@@ -1013,7 +1013,7 @@ fs_visitor::opt_copy_propagation()
for (int i = 0; i < cfg->num_blocks; i++) for (int i = 0; i < cfg->num_blocks; i++)
out_acp[i] = new exec_list [ACP_HASH_SIZE]; out_acp[i] = new exec_list [ACP_HASH_SIZE];
calculate_live_intervals(); const fs_live_variables &live = live_analysis.require();
/* First, walk through each block doing local copy propagation and getting /* First, walk through each block doing local copy propagation and getting
* the set of copies available at the end of the block. * the set of copies available at the end of the block.
@@ -1035,15 +1035,15 @@ fs_visitor::opt_copy_propagation()
for (unsigned a = 0; a < ACP_HASH_SIZE; a++) { for (unsigned a = 0; a < ACP_HASH_SIZE; a++) {
foreach_in_list_safe(acp_entry, entry, &out_acp[block->num][a]) { foreach_in_list_safe(acp_entry, entry, &out_acp[block->num][a]) {
assert(entry->dst.file == VGRF); assert(entry->dst.file == VGRF);
if (block->start_ip <= live_intervals->vgrf_start[entry->dst.nr] && if (block->start_ip <= live.vgrf_start[entry->dst.nr] &&
live_intervals->vgrf_end[entry->dst.nr] <= block->end_ip) live.vgrf_end[entry->dst.nr] <= block->end_ip)
entry->remove(); entry->remove();
} }
} }
} }
/* Do dataflow analysis for those available copies. */ /* Do dataflow analysis for those available copies. */
fs_copy_prop_dataflow dataflow(copy_prop_ctx, cfg, live_intervals, out_acp); fs_copy_prop_dataflow dataflow(copy_prop_ctx, cfg, live, out_acp);
/* Next, re-run local copy propagation, this time with the set of copies /* Next, re-run local copy propagation, this time with the set of copies
* provided by the dataflow analysis available at the start of a block. * provided by the dataflow analysis available at the start of a block.

View File

@@ -243,7 +243,7 @@ create_copy_instr(const fs_builder &bld, fs_inst *inst, fs_reg src, bool negate)
} }
bool bool
fs_visitor::opt_cse_local(bblock_t *block, int &ip) fs_visitor::opt_cse_local(const fs_live_variables &live, bblock_t *block, int &ip)
{ {
bool progress = false; bool progress = false;
exec_list aeb; exec_list aeb;
@@ -360,8 +360,7 @@ fs_visitor::opt_cse_local(bblock_t *block, int &ip)
/* Kill any AEB entries using registers that don't get reused any /* Kill any AEB entries using registers that don't get reused any
* more -- a sure sign they'll fail operands_match(). * more -- a sure sign they'll fail operands_match().
*/ */
if (src_reg->file == VGRF && if (src_reg->file == VGRF && live.vgrf_end[src_reg->nr] < ip) {
live_intervals->vgrf_end[src_reg->nr] < ip) {
entry->remove(); entry->remove();
ralloc_free(entry); ralloc_free(entry);
break; break;
@@ -380,13 +379,12 @@ fs_visitor::opt_cse_local(bblock_t *block, int &ip)
bool bool
fs_visitor::opt_cse() fs_visitor::opt_cse()
{ {
const fs_live_variables &live = live_analysis.require();
bool progress = false; bool progress = false;
int ip = 0; int ip = 0;
calculate_live_intervals();
foreach_block (block, cfg) { foreach_block (block, cfg) {
progress = opt_cse_local(block, ip) || progress; progress = opt_cse_local(live, block, ip) || progress;
} }
if (progress) if (progress)

View File

@@ -76,21 +76,20 @@ fs_visitor::dead_code_eliminate()
{ {
bool progress = false; bool progress = false;
calculate_live_intervals(); const fs_live_variables &live_vars = live_analysis.require();
int num_vars = live_vars.num_vars;
int num_vars = live_intervals->num_vars;
BITSET_WORD *live = rzalloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars)); BITSET_WORD *live = rzalloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));
BITSET_WORD *flag_live = rzalloc_array(NULL, BITSET_WORD, 1); BITSET_WORD *flag_live = rzalloc_array(NULL, BITSET_WORD, 1);
foreach_block_reverse_safe(block, cfg) { foreach_block_reverse_safe(block, cfg) {
memcpy(live, live_intervals->block_data[block->num].liveout, memcpy(live, live_vars.block_data[block->num].liveout,
sizeof(BITSET_WORD) * BITSET_WORDS(num_vars)); sizeof(BITSET_WORD) * BITSET_WORDS(num_vars));
memcpy(flag_live, live_intervals->block_data[block->num].flag_liveout, memcpy(flag_live, live_vars.block_data[block->num].flag_liveout,
sizeof(BITSET_WORD)); sizeof(BITSET_WORD));
foreach_inst_in_block_reverse_safe(fs_inst, inst, block) { foreach_inst_in_block_reverse_safe(fs_inst, inst, block) {
if (inst->dst.file == VGRF) { if (inst->dst.file == VGRF) {
const unsigned var = live_intervals->var_from_reg(inst->dst); const unsigned var = live_vars.var_from_reg(inst->dst);
bool result_live = false; bool result_live = false;
for (unsigned i = 0; i < regs_written(inst); i++) for (unsigned i = 0; i < regs_written(inst); i++)
@@ -111,7 +110,7 @@ fs_visitor::dead_code_eliminate()
if (inst->dst.file == VGRF) { if (inst->dst.file == VGRF) {
if (!inst->is_partial_write()) { if (!inst->is_partial_write()) {
int var = live_intervals->var_from_reg(inst->dst); const unsigned var = live_vars.var_from_reg(inst->dst);
for (unsigned i = 0; i < regs_written(inst); i++) { for (unsigned i = 0; i < regs_written(inst); i++) {
BITSET_CLEAR(live, var + i); BITSET_CLEAR(live, var + i);
} }
@@ -128,7 +127,7 @@ fs_visitor::dead_code_eliminate()
for (int i = 0; i < inst->sources; i++) { for (int i = 0; i < inst->sources; i++) {
if (inst->src[i].file == VGRF) { if (inst->src[i].file == VGRF) {
int var = live_intervals->var_from_reg(inst->src[i]); int var = live_vars.var_from_reg(inst->src[i]);
for (unsigned j = 0; j < regs_read(inst, i); j++) { for (unsigned j = 0; j < regs_read(inst, i); j++) {
BITSET_SET(live, var + j); BITSET_SET(live, var + j);

View File

@@ -367,23 +367,9 @@ fs_live_variables::validate(const backend_shader *s) const
void void
fs_visitor::invalidate_live_intervals() fs_visitor::invalidate_live_intervals()
{ {
ralloc_free(live_intervals); /* XXX -- Leave this around for the moment to keep the fs_vistor object
live_intervals = NULL; * concrete.
}
/**
* Compute the live intervals for each virtual GRF.
*
* This uses the per-component use/def data, but combines it to produce
* information about whole VGRFs.
*/ */
void
fs_visitor::calculate_live_intervals()
{
if (this->live_intervals)
return;
this->live_intervals = new(mem_ctx) fs_live_variables(this);
} }
bool bool

View File

@@ -28,6 +28,7 @@
#ifndef BRW_FS_LIVE_VARIABLES_H #ifndef BRW_FS_LIVE_VARIABLES_H
#define BRW_FS_LIVE_VARIABLES_H #define BRW_FS_LIVE_VARIABLES_H
#include "brw_ir_analysis.h"
#include "brw_ir_fs.h" #include "brw_ir_fs.h"
#include "util/bitset.h" #include "util/bitset.h"
@@ -76,13 +77,19 @@ public:
BITSET_WORD flag_liveout[1]; BITSET_WORD flag_liveout[1];
}; };
DECLARE_RALLOC_CXX_OPERATORS(fs_live_variables)
fs_live_variables(const backend_shader *s); fs_live_variables(const backend_shader *s);
~fs_live_variables(); ~fs_live_variables();
bool validate(const backend_shader *s) const; bool validate(const backend_shader *s) const;
analysis_dependency_class
dependency_class() const
{
return (DEPENDENCY_INSTRUCTION_IDENTITY |
DEPENDENCY_INSTRUCTION_DATA_FLOW |
DEPENDENCY_VARIABLES);
}
bool vars_interfere(int a, int b) const; bool vars_interfere(int a, int b) const;
bool vgrfs_interfere(int a, int b) const; bool vgrfs_interfere(int a, int b) const;
int var_from_reg(const fs_reg &reg) const int var_from_reg(const fs_reg &reg) const

View File

@@ -410,7 +410,8 @@ void fs_visitor::calculate_payload_ranges(int payload_node_count,
class fs_reg_alloc { class fs_reg_alloc {
public: public:
fs_reg_alloc(fs_visitor *fs): fs_reg_alloc(fs_visitor *fs):
fs(fs), devinfo(fs->devinfo), compiler(fs->compiler), g(NULL), fs(fs), devinfo(fs->devinfo), compiler(fs->compiler),
live(fs->live_analysis.require()), g(NULL),
have_spill_costs(false) have_spill_costs(false)
{ {
mem_ctx = ralloc_context(NULL); mem_ctx = ralloc_context(NULL);
@@ -457,6 +458,7 @@ private:
fs_visitor *fs; fs_visitor *fs;
const gen_device_info *devinfo; const gen_device_info *devinfo;
const brw_compiler *compiler; const brw_compiler *compiler;
const fs_live_variables &live;
/* Which compiler->fs_reg_sets[] to use */ /* Which compiler->fs_reg_sets[] to use */
int rsi; int rsi;
@@ -590,8 +592,8 @@ fs_reg_alloc::setup_live_interference(unsigned node,
for (unsigned n2 = first_vgrf_node; for (unsigned n2 = first_vgrf_node;
n2 < (unsigned)first_spill_node && n2 < node; n2++) { n2 < (unsigned)first_spill_node && n2 < node; n2++) {
unsigned vgrf = n2 - first_vgrf_node; unsigned vgrf = n2 - first_vgrf_node;
if (!(node_end_ip <= fs->live_intervals->vgrf_start[vgrf] || if (!(node_end_ip <= live.vgrf_start[vgrf] ||
fs->live_intervals->vgrf_end[vgrf] <= node_start_ip)) live.vgrf_end[vgrf] <= node_start_ip))
ra_add_node_interference(g, node, n2); ra_add_node_interference(g, node, n2);
} }
} }
@@ -740,7 +742,6 @@ fs_reg_alloc::build_interference_graph(bool allow_spilling)
node_count += fs->alloc.count; node_count += fs->alloc.count;
first_spill_node = node_count; first_spill_node = node_count;
fs->calculate_live_intervals();
fs->calculate_payload_ranges(payload_node_count, fs->calculate_payload_ranges(payload_node_count,
payload_last_use_ip); payload_last_use_ip);
@@ -812,8 +813,8 @@ fs_reg_alloc::build_interference_graph(bool allow_spilling)
/* Add interference based on the live range of the register */ /* Add interference based on the live range of the register */
for (unsigned i = 0; i < fs->alloc.count; i++) { for (unsigned i = 0; i < fs->alloc.count; i++) {
setup_live_interference(first_vgrf_node + i, setup_live_interference(first_vgrf_node + i,
fs->live_intervals->vgrf_start[i], live.vgrf_start[i],
fs->live_intervals->vgrf_end[i]); live.vgrf_end[i]);
} }
/* Add interference based on the instructions in which a register is used. /* Add interference based on the instructions in which a register is used.
@@ -953,7 +954,7 @@ fs_reg_alloc::set_spill_costs()
if (no_spill[i]) if (no_spill[i])
continue; continue;
int live_length = fs->live_intervals->vgrf_end[i] - fs->live_intervals->vgrf_start[i]; int live_length = live.vgrf_end[i] - live.vgrf_start[i];
if (live_length <= 0) if (live_length <= 0)
continue; continue;

View File

@@ -97,17 +97,17 @@ is_coalesce_candidate(const fs_visitor *v, const fs_inst *inst)
} }
static bool static bool
can_coalesce_vars(brw::fs_live_variables *live_intervals, can_coalesce_vars(const fs_live_variables &live,
const cfg_t *cfg, const fs_inst *inst, const cfg_t *cfg, const fs_inst *inst,
int dst_var, int src_var) int dst_var, int src_var)
{ {
if (!live_intervals->vars_interfere(src_var, dst_var)) if (!live.vars_interfere(src_var, dst_var))
return true; return true;
int dst_start = live_intervals->start[dst_var]; int dst_start = live.start[dst_var];
int dst_end = live_intervals->end[dst_var]; int dst_end = live.end[dst_var];
int src_start = live_intervals->start[src_var]; int src_start = live.start[src_var];
int src_end = live_intervals->end[src_var]; int src_end = live.end[src_var];
/* Variables interfere and one line range isn't a subset of the other. */ /* Variables interfere and one line range isn't a subset of the other. */
if ((dst_end > src_end && src_start < dst_start) || if ((dst_end > src_end && src_start < dst_start) ||
@@ -155,9 +155,7 @@ bool
fs_visitor::register_coalesce() fs_visitor::register_coalesce()
{ {
bool progress = false; bool progress = false;
fs_live_variables &live = live_analysis.require();
calculate_live_intervals();
int src_size = 0; int src_size = 0;
int channels_remaining = 0; int channels_remaining = 0;
unsigned src_reg = ~0u, dst_reg = ~0u; unsigned src_reg = ~0u, dst_reg = ~0u;
@@ -227,11 +225,10 @@ fs_visitor::register_coalesce()
break; break;
} }
dst_var[i] = live_intervals->var_from_vgrf[dst_reg] + dst_reg_offset[i]; dst_var[i] = live.var_from_vgrf[dst_reg] + dst_reg_offset[i];
src_var[i] = live_intervals->var_from_vgrf[src_reg] + i; src_var[i] = live.var_from_vgrf[src_reg] + i;
if (!can_coalesce_vars(live_intervals, cfg, inst, if (!can_coalesce_vars(live, cfg, inst, dst_var[i], src_var[i])) {
dst_var[i], src_var[i])) {
can_coalesce = false; can_coalesce = false;
src_reg = ~0u; src_reg = ~0u;
break; break;
@@ -273,12 +270,10 @@ fs_visitor::register_coalesce()
} }
for (int i = 0; i < src_size; i++) { for (int i = 0; i < src_size; i++) {
live_intervals->start[dst_var[i]] = live.start[dst_var[i]] = MIN2(live.start[dst_var[i]],
MIN2(live_intervals->start[dst_var[i]], live.start[src_var[i]]);
live_intervals->start[src_var[i]]); live.end[dst_var[i]] = MAX2(live.end[dst_var[i]],
live_intervals->end[dst_var[i]] = live.end[src_var[i]]);
MAX2(live_intervals->end[dst_var[i]],
live_intervals->end[src_var[i]]);
} }
src_reg = ~0u; src_reg = ~0u;
} }

View File

@@ -25,6 +25,8 @@
#include "brw_fs_live_variables.h" #include "brw_fs_live_variables.h"
#include "brw_cfg.h" #include "brw_cfg.h"
using namespace brw;
/** @file brw_fs_saturate_propagation.cpp /** @file brw_fs_saturate_propagation.cpp
* *
* Implements a pass that propagates the SAT modifier from a MOV.SAT into the * Implements a pass that propagates the SAT modifier from a MOV.SAT into the
@@ -43,7 +45,7 @@
*/ */
static bool static bool
opt_saturate_propagation_local(fs_visitor *v, bblock_t *block) opt_saturate_propagation_local(const fs_live_variables &live, bblock_t *block)
{ {
bool progress = false; bool progress = false;
int ip = block->end_ip + 1; int ip = block->end_ip + 1;
@@ -59,8 +61,8 @@ opt_saturate_propagation_local(fs_visitor *v, bblock_t *block)
inst->src[0].abs) inst->src[0].abs)
continue; continue;
int src_var = v->live_intervals->var_from_reg(inst->src[0]); int src_var = live.var_from_reg(inst->src[0]);
int src_end_ip = v->live_intervals->end[src_var]; int src_end_ip = live.end[src_var];
bool interfered = false; bool interfered = false;
foreach_inst_in_block_reverse_starting_from(fs_inst, scan_inst, inst) { foreach_inst_in_block_reverse_starting_from(fs_inst, scan_inst, inst) {
@@ -149,12 +151,11 @@ opt_saturate_propagation_local(fs_visitor *v, bblock_t *block)
bool bool
fs_visitor::opt_saturate_propagation() fs_visitor::opt_saturate_propagation()
{ {
const fs_live_variables &live = live_analysis.require();
bool progress = false; bool progress = false;
calculate_live_intervals();
foreach_block (block, cfg) { foreach_block (block, cfg) {
progress = opt_saturate_propagation_local(this, block) || progress; progress = opt_saturate_propagation_local(live, block) || progress;
} }
/* Live intervals are still valid. */ /* Live intervals are still valid. */

View File

@@ -886,6 +886,7 @@ fs_visitor::fs_visitor(const struct brw_compiler *compiler, void *log_data,
: backend_shader(compiler, log_data, mem_ctx, shader, prog_data), : backend_shader(compiler, log_data, mem_ctx, shader, prog_data),
key(key), gs_compile(NULL), prog_data(prog_data), key(key), gs_compile(NULL), prog_data(prog_data),
input_vue_map(input_vue_map), input_vue_map(input_vue_map),
live_analysis(this),
dispatch_width(dispatch_width), dispatch_width(dispatch_width),
shader_time_index(shader_time_index), shader_time_index(shader_time_index),
bld(fs_builder(this, dispatch_width).at_end()) bld(fs_builder(this, dispatch_width).at_end())
@@ -903,6 +904,7 @@ fs_visitor::fs_visitor(const struct brw_compiler *compiler, void *log_data,
&prog_data->base.base), &prog_data->base.base),
key(&c->key.base), gs_compile(c), key(&c->key.base), gs_compile(c),
prog_data(&prog_data->base.base), prog_data(&prog_data->base.base),
live_analysis(this),
dispatch_width(8), dispatch_width(8),
shader_time_index(shader_time_index), shader_time_index(shader_time_index),
bld(fs_builder(this, dispatch_width).at_end()) bld(fs_builder(this, dispatch_width).at_end())
@@ -933,7 +935,6 @@ fs_visitor::init()
this->first_non_payload_grf = 0; this->first_non_payload_grf = 0;
this->max_grf = devinfo->gen >= 7 ? GEN7_MRF_HACK_START : BRW_MAX_GRF; this->max_grf = devinfo->gen >= 7 ? GEN7_MRF_HACK_START : BRW_MAX_GRF;
this->live_intervals = NULL;
this->regs_live_at_ip = NULL; this->regs_live_at_ip = NULL;
this->uniforms = 0; this->uniforms = 0;

View File

@@ -730,21 +730,23 @@ fs_instruction_scheduler::count_reads_remaining(backend_instruction *be)
void void
fs_instruction_scheduler::setup_liveness(cfg_t *cfg) fs_instruction_scheduler::setup_liveness(cfg_t *cfg)
{ {
const fs_live_variables &live = v->live_analysis.require();
/* First, compute liveness on a per-GRF level using the in/out sets from /* First, compute liveness on a per-GRF level using the in/out sets from
* liveness calculation. * liveness calculation.
*/ */
for (int block = 0; block < cfg->num_blocks; block++) { for (int block = 0; block < cfg->num_blocks; block++) {
for (int i = 0; i < v->live_intervals->num_vars; i++) { for (int i = 0; i < live.num_vars; i++) {
if (BITSET_TEST(v->live_intervals->block_data[block].livein, i)) { if (BITSET_TEST(live.block_data[block].livein, i)) {
int vgrf = v->live_intervals->vgrf_from_var[i]; int vgrf = live.vgrf_from_var[i];
if (!BITSET_TEST(livein[block], vgrf)) { if (!BITSET_TEST(livein[block], vgrf)) {
reg_pressure_in[block] += v->alloc.sizes[vgrf]; reg_pressure_in[block] += v->alloc.sizes[vgrf];
BITSET_SET(livein[block], vgrf); BITSET_SET(livein[block], vgrf);
} }
} }
if (BITSET_TEST(v->live_intervals->block_data[block].liveout, i)) if (BITSET_TEST(live.block_data[block].liveout, i))
BITSET_SET(liveout[block], v->live_intervals->vgrf_from_var[i]); BITSET_SET(liveout[block], live.vgrf_from_var[i]);
} }
} }
@@ -754,8 +756,8 @@ fs_instruction_scheduler::setup_liveness(cfg_t *cfg)
*/ */
for (int block = 0; block < cfg->num_blocks - 1; block++) { for (int block = 0; block < cfg->num_blocks - 1; block++) {
for (int i = 0; i < grf_count; i++) { for (int i = 0; i < grf_count; i++) {
if (v->live_intervals->vgrf_start[i] <= cfg->blocks[block]->end_ip && if (live.vgrf_start[i] <= cfg->blocks[block]->end_ip &&
v->live_intervals->vgrf_end[i] >= cfg->blocks[block + 1]->start_ip) { live.vgrf_end[i] >= cfg->blocks[block + 1]->start_ip) {
if (!BITSET_TEST(livein[block + 1], i)) { if (!BITSET_TEST(livein[block + 1], i)) {
reg_pressure_in[block + 1] += v->alloc.sizes[i]; reg_pressure_in[block + 1] += v->alloc.sizes[i];
BITSET_SET(livein[block + 1], i); BITSET_SET(livein[block + 1], i);
@@ -1826,9 +1828,6 @@ instruction_scheduler::run(cfg_t *cfg)
void void
fs_visitor::schedule_instructions(instruction_scheduler_mode mode) fs_visitor::schedule_instructions(instruction_scheduler_mode mode)
{ {
if (mode != SCHEDULE_POST)
calculate_live_intervals();
int grf_count; int grf_count;
if (mode == SCHEDULE_POST) if (mode == SCHEDULE_POST)
grf_count = grf_used; grf_count = grf_used;