summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2011-05-05 19:37:10 -0700
committerEric Anholt <eric@anholt.net>2011-08-10 11:03:48 -0700
commit4e10d5825b31d2c58c0af3e29b7fc2eacb2b4709 (patch)
treea613dbeb1d5d0548e01628a8b6868f70048f44c7
parentb76378d46a211521582cfab56dc05031a57502a6 (diff)
i965/fs: Simplify the register allocator using a map from RA reg to GRF.
It's fewer pointers to track, and when we start caching the register set, should be algorithmically better in the cache hit case (lookup in a byte-per-register array, instead of a linear walk through desctiption of register classes to find how to translate that class).
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp79
1 files changed, 38 insertions, 41 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 83dd629aaf..42ab66df6d 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
@@ -102,7 +102,7 @@ fs_visitor::assign_regs()
int base_reg_count = (BRW_MAX_GRF - first_assigned_grf) / reg_width;
int class_sizes[base_reg_count];
int class_count = 0;
- int aligned_pair_class = -1;
+ int aligned_pairs_class = -1;
calculate_live_intervals();
@@ -137,52 +137,59 @@ fs_visitor::assign_regs()
}
}
+ /* Compute the total number of registers across all classes. */
int ra_reg_count = 0;
- int class_base_reg[class_count];
- int class_reg_count[class_count];
- int classes[class_count + 1];
-
for (int i = 0; i < class_count; i++) {
- class_base_reg[i] = ra_reg_count;
- class_reg_count[i] = base_reg_count - (class_sizes[i] - 1);
- ra_reg_count += class_reg_count[i];
+ ra_reg_count += base_reg_count - (class_sizes[i] - 1);
}
struct ra_regs *regs = ra_alloc_reg_set(ra_reg_count);
+ uint8_t ra_reg_to_grf[ra_reg_count];
+ int classes[class_count + 1];
+
+ /* Now, add the registers to their classes, and add the conflicts
+ * between them and the base GRF registers (and also each other).
+ */
+ int reg = 0;
+ int pairs_base_reg = 0;
+ int pairs_reg_count = 0;
for (int i = 0; i < class_count; i++) {
+ int class_reg_count = base_reg_count - (class_sizes[i] - 1);
classes[i] = ra_alloc_reg_class(regs);
- for (int i_r = 0; i_r < class_reg_count[i]; i_r++) {
- int class_reg = class_base_reg[i] + i_r;
+ /* Save this off for the aligned pair class at the end. */
+ if (class_sizes[i] == 2) {
+ pairs_base_reg = reg;
+ pairs_reg_count = class_reg_count;
+ }
+
+ for (int j = 0; j < class_reg_count; j++) {
+ ra_class_add_reg(regs, classes[i], reg);
- ra_class_add_reg(regs, classes[i], class_reg);
+ ra_reg_to_grf[reg] = j;
- for (int base_reg = i_r;
- base_reg < i_r + class_sizes[i];
+ for (int base_reg = j;
+ base_reg < j + class_sizes[i];
base_reg++) {
- ra_add_transitive_reg_conflict(regs, base_reg, class_reg);
+ ra_add_transitive_reg_conflict(regs, base_reg, reg);
}
+
+ reg++;
}
}
+ assert(reg == ra_reg_count);
/* Add a special class for aligned pairs, which we'll put delta_x/y
* in on gen5 so that we can do PLN.
*/
if (brw->has_pln && reg_width == 1 && intel->gen < 6) {
- int reg_count = (base_reg_count - 1) / 2;
- int unaligned_pair_class = 1;
- assert(class_sizes[unaligned_pair_class] == 2);
-
- aligned_pair_class = class_count;
- classes[aligned_pair_class] = ra_alloc_reg_class(regs);
- class_sizes[aligned_pair_class] = 2;
- class_base_reg[aligned_pair_class] = 0;
- class_reg_count[aligned_pair_class] = 0;
- int start = (first_assigned_grf & 1) ? 1 : 0;
-
- for (int i = 0; i < reg_count; i++) {
- ra_class_add_reg(regs, classes[aligned_pair_class],
- class_base_reg[unaligned_pair_class] + i * 2 + start);
+ aligned_pairs_class = ra_alloc_reg_class(regs);
+
+ for (int i = 0; i < pairs_reg_count; i++) {
+ if ((ra_reg_to_grf[pairs_base_reg + i] & 1) == 0) {
+ ra_class_add_reg(regs, aligned_pairs_class,
+ pairs_base_reg + i);
+ }
}
class_count++;
}
@@ -195,9 +202,9 @@ fs_visitor::assign_regs()
for (int i = 0; i < this->virtual_grf_next; i++) {
for (int c = 0; c < class_count; c++) {
if (class_sizes[c] == this->virtual_grf_sizes[i]) {
- if (aligned_pair_class >= 0 &&
+ if (aligned_pairs_class >= 0 &&
this->delta_x.reg == i) {
- ra_set_node_class(g, i, classes[aligned_pair_class]);
+ ra_set_node_class(g, i, aligned_pairs_class);
} else {
ra_set_node_class(g, i, classes[c]);
}
@@ -242,18 +249,8 @@ fs_visitor::assign_regs()
this->grf_used = first_assigned_grf;
for (int i = 0; i < this->virtual_grf_next; i++) {
int reg = ra_get_node_reg(g, i);
- int hw_reg = -1;
-
- for (int c = 0; c < class_count; c++) {
- if (reg >= class_base_reg[c] &&
- reg < class_base_reg[c] + class_reg_count[c]) {
- hw_reg = reg - class_base_reg[c];
- break;
- }
- }
- assert(hw_reg >= 0);
- hw_reg_mapping[i] = first_assigned_grf + hw_reg * reg_width;
+ hw_reg_mapping[i] = first_assigned_grf + ra_reg_to_grf[reg] * reg_width;
this->grf_used = MAX2(this->grf_used,
hw_reg_mapping[i] + this->virtual_grf_sizes[i] *
reg_width);