summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2012-10-02 16:31:51 -0700
committerEric Anholt <eric@anholt.net>2012-10-17 13:02:06 -0700
commit8757fa65b8f1680147e046895770b1be829c2a3a (patch)
tree7bd9318d58a7fba1d6ba50fc7c7d40cba11a87fb /src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
parenta087e9f27f088c4bd00b2fddb65629c83d404860 (diff)
i965/fs: Allocate registers in the unused parts of the gen7 MRF hack range.
This should also reduce register pressure on gen7+, like the previous commit. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp62
1 files changed, 61 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
index 1d7c7733e8e..cfc2e51356a 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
@@ -319,6 +319,61 @@ fs_visitor::setup_payload_interference(struct ra_graph *g,
}
}
+/**
+ * Sets interference between virtual GRFs and usage of the high GRFs for SEND
+ * messages (treated as MRFs in code generation).
+ */
+void
+fs_visitor::setup_mrf_hack_interference(struct ra_graph *g, int first_mrf_node)
+{
+ int mrf_count = BRW_MAX_GRF - GEN7_MRF_HACK_START;
+ int reg_width = c->dispatch_width / 8;
+
+ /* Identify all the MRFs used in the program. */
+ bool mrf_used[mrf_count];
+ memset(mrf_used, 0, sizeof(mrf_used));
+ foreach_list(node, &this->instructions) {
+ fs_inst *inst = (fs_inst *)node;
+
+ if (inst->dst.file == MRF) {
+ int reg = inst->dst.reg & ~BRW_MRF_COMPR4;
+ mrf_used[reg] = true;
+ if (reg_width == 2) {
+ if (inst->dst.reg & BRW_MRF_COMPR4) {
+ mrf_used[reg + 4] = true;
+ } else {
+ mrf_used[reg + 1] = true;
+ }
+ }
+ }
+
+ if (inst->mlen > 0) {
+ for (int i = 0; i < implied_mrf_writes(inst); i++) {
+ mrf_used[inst->base_mrf + i] = true;
+ }
+ }
+ }
+
+ for (int i = 0; i < mrf_count; i++) {
+ /* Mark each payload reg node as being allocated to its physical register.
+ *
+ * The alternative would be to have per-physical-register classes, which
+ * would just be silly.
+ */
+ ra_set_node_reg(g, first_mrf_node + i,
+ (GEN7_MRF_HACK_START + i) / reg_width);
+
+ /* Since we don't have any live/dead analysis on the MRFs, just mark all
+ * that are used as conflicting with all virtual GRFs.
+ */
+ if (mrf_used[i]) {
+ for (int j = 0; j < this->virtual_grf_count; j++) {
+ ra_add_node_interference(g, first_mrf_node + i, j);
+ }
+ }
+ }
+}
+
bool
fs_visitor::assign_regs()
{
@@ -332,7 +387,7 @@ fs_visitor::assign_regs()
int hw_reg_mapping[this->virtual_grf_count];
int payload_node_count = (ALIGN(this->first_non_payload_grf, reg_width) /
reg_width);
- int base_reg_count = max_grf / reg_width;
+ int base_reg_count = BRW_MAX_GRF / reg_width;
calculate_live_intervals();
@@ -341,6 +396,9 @@ fs_visitor::assign_regs()
int node_count = this->virtual_grf_count;
int first_payload_node = node_count;
node_count += payload_node_count;
+ int first_mrf_hack_node = node_count;
+ if (intel->gen >= 7)
+ node_count += BRW_MAX_GRF - GEN7_MRF_HACK_START;
struct ra_graph *g = ra_alloc_interference_graph(brw->wm.regs, node_count);
for (int i = 0; i < this->virtual_grf_count; i++) {
@@ -373,6 +431,8 @@ fs_visitor::assign_regs()
}
setup_payload_interference(g, payload_node_count, first_payload_node);
+ if (intel->gen >= 7)
+ setup_mrf_hack_interference(g, first_mrf_hack_node);
if (!ra_allocate_no_spills(g)) {
/* Failed to allocate registers. Spill a reg, and the caller will