Procházet zdrojové kódy

intel/fs/ra: Put the VGRFs at the end of the nodes

This is slightly less convenient in some places but it will make it much
easier when we want to start adding nodes dynamically.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
tags/19.2-branchpoint
Jason Ekstrand před 6 roky
rodič
revize
147665d0a2
1 změnil soubory, kde provedl 32 přidání a 18 odebrání
  1. 32
    18
      src/intel/compiler/brw_fs_reg_allocate.cpp

+ 32
- 18
src/intel/compiler/brw_fs_reg_allocate.cpp Zobrazit soubor

@@ -448,6 +448,7 @@ private:
int first_payload_node;
int first_mrf_hack_node;
int grf127_send_hack_node;
int first_vgrf_node;
};

/**
@@ -558,10 +559,11 @@ fs_reg_alloc::setup_live_interference(unsigned node,
* node's. We only need to look at nodes below this one as the reflexivity
* of interference will take care of the rest.
*/
for (unsigned i = 0; i < node; i++) {
if (!(node_end_ip <= fs->virtual_grf_start[i] ||
fs->virtual_grf_end[i] <= node_start_ip))
ra_add_node_interference(g, node, i);
for (unsigned n2 = first_vgrf_node; n2 < node; n2++) {
unsigned vgrf = n2 - first_vgrf_node;
if (!(node_end_ip <= fs->virtual_grf_start[vgrf] ||
fs->virtual_grf_end[vgrf] <= node_start_ip))
ra_add_node_interference(g, node, n2);
}
}

@@ -574,7 +576,8 @@ fs_reg_alloc::setup_inst_interference(fs_inst *inst)
if (inst->dst.file == VGRF && inst->has_source_and_destination_hazard()) {
for (unsigned i = 0; i < inst->sources; i++) {
if (inst->src[i].file == VGRF) {
ra_add_node_interference(g, inst->dst.nr, inst->src[i].nr);
ra_add_node_interference(g, first_vgrf_node + inst->dst.nr,
first_vgrf_node + inst->src[i].nr);
}
}
}
@@ -593,7 +596,8 @@ fs_reg_alloc::setup_inst_interference(fs_inst *inst)
if (inst->exec_size >= 16 && inst->dst.file == VGRF) {
for (int i = 0; i < inst->sources; ++i) {
if (inst->src[i].file == VGRF) {
ra_add_node_interference(g, inst->dst.nr, inst->src[i].nr);
ra_add_node_interference(g, first_vgrf_node + inst->dst.nr,
first_vgrf_node + inst->src[i].nr);
}
}
}
@@ -614,7 +618,8 @@ fs_reg_alloc::setup_inst_interference(fs_inst *inst)
*/
if (inst->exec_size < 16 && inst->is_send_from_grf() &&
inst->dst.file == VGRF)
ra_add_node_interference(g, inst->dst.nr, grf127_send_hack_node);
ra_add_node_interference(g, first_vgrf_node + inst->dst.nr,
grf127_send_hack_node);

/* Spilling instruction are genereated as SEND messages from MRF but as
* Gen7+ supports sending from GRF the driver will maps assingn these
@@ -625,7 +630,8 @@ fs_reg_alloc::setup_inst_interference(fs_inst *inst)
if ((inst->opcode == SHADER_OPCODE_GEN7_SCRATCH_READ ||
inst->opcode == SHADER_OPCODE_GEN4_SCRATCH_READ) &&
inst->dst.file == VGRF)
ra_add_node_interference(g, inst->dst.nr, grf127_send_hack_node);
ra_add_node_interference(g, first_vgrf_node + inst->dst.nr,
grf127_send_hack_node);
}

/* From the Skylake PRM Vol. 2a docs for sends:
@@ -643,8 +649,8 @@ fs_reg_alloc::setup_inst_interference(fs_inst *inst)
if (inst->opcode == SHADER_OPCODE_SEND && inst->ex_mlen > 0 &&
inst->src[2].file == VGRF && inst->src[3].file == VGRF &&
inst->src[2].nr != inst->src[3].nr)
ra_add_node_interference(g, inst->src[2].nr,
inst->src[3].nr);
ra_add_node_interference(g, first_vgrf_node + inst->src[2].nr,
first_vgrf_node + inst->src[3].nr);
}

/* When we do send-from-GRF for FB writes, we need to ensure that the last
@@ -669,7 +675,7 @@ fs_reg_alloc::setup_inst_interference(fs_inst *inst)
if (first_mrf_hack_node >= 0)
reg -= BRW_MAX_MRF(devinfo->gen) - spill_base_mrf(fs);

ra_set_node_reg(g, vgrf, reg);
ra_set_node_reg(g, first_vgrf_node + vgrf, reg);
}
}

@@ -680,7 +686,7 @@ fs_reg_alloc::build_interference_graph(bool allow_spilling)
const brw_compiler *compiler = fs->compiler;

/* Compute the RA node layout */
node_count = fs->alloc.count;
node_count = 0;
first_payload_node = node_count;
node_count += payload_node_count;
if (devinfo->gen >= 7 && allow_spilling) {
@@ -695,6 +701,8 @@ fs_reg_alloc::build_interference_graph(bool allow_spilling)
} else {
grf127_send_hack_node = -1;
}
first_vgrf_node = node_count;
node_count += fs->alloc.count;

fs->calculate_live_intervals();
fs->calculate_payload_ranges(payload_node_count,
@@ -762,11 +770,12 @@ fs_reg_alloc::build_interference_graph(bool allow_spilling)
c = compiler->fs_reg_sets[rsi].aligned_pairs_class;
}

ra_set_node_class(g, i, c);
ra_set_node_class(g, first_vgrf_node + i, c);

/* Add interference based on the live range of the register */
setup_live_interference(i, fs->virtual_grf_start[i],
fs->virtual_grf_end[i]);
setup_live_interference(first_vgrf_node + i,
fs->virtual_grf_start[i],
fs->virtual_grf_end[i]);
}

/* Add interference based on the instructions in which a register is used.
@@ -902,10 +911,15 @@ fs_reg_alloc::choose_spill_reg()
*/
float adjusted_cost = spill_costs[i] / logf(live_length);
if (!no_spill[i])
ra_set_node_spill_cost(g, i, adjusted_cost);
ra_set_node_spill_cost(g, first_vgrf_node + i, adjusted_cost);
}

return ra_get_best_spill_node(g);
int node = ra_get_best_spill_node(g);
if (node < 0)
return -1;

assert(node >= first_vgrf_node);
return node - first_vgrf_node;
}

void
@@ -1078,7 +1092,7 @@ fs_reg_alloc::assign_regs(bool allow_spilling, bool spill_all)
unsigned hw_reg_mapping[fs->alloc.count];
fs->grf_used = fs->first_non_payload_grf;
for (unsigned i = 0; i < fs->alloc.count; i++) {
int reg = ra_get_node_reg(g, i);
int reg = ra_get_node_reg(g, first_vgrf_node + i);

hw_reg_mapping[i] = compiler->fs_reg_sets[rsi].ra_reg_to_grf[reg];
fs->grf_used = MAX2(fs->grf_used,

Načítá se…
Zrušit
Uložit