summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMaximilian Stemmer-Grabow <mail@mxsg.de>2021-05-07 16:12:07 +0200
committerAndreas Fried <andreas.fried@kit.edu>2021-12-02 12:57:28 +0100
commitfd3ab82d524c6fa45ced64a5963eeff0580a40b8 (patch)
treedcbc0ccba068ae76bedf5930a2186f7806f4ed3e
parentc461c7591b87a0ffc563e2aadaae93d95cd0942a (diff)
Adjust color costs in copy optimization based on compressible registers
-rw-r--r--ir/be/becopyheur4.c52
1 files changed, 50 insertions, 2 deletions
diff --git a/ir/be/becopyheur4.c b/ir/be/becopyheur4.c
index cb8fa92..29aa0a7 100644
--- a/ir/be/becopyheur4.c
+++ b/ir/be/becopyheur4.c
@@ -56,7 +56,8 @@ static firm_dbg_module_t *dbg = NULL;
static unsigned last_chunk_id;
static int recolor_limit = 7;
static double dislike_influence = 0.1;
-static double compression_cost_scale = 0.1;
+static double compressibility_influence = 0.05;
+static double compression_cost_scale = 0.2;
typedef struct col_cost_t {
unsigned col;
@@ -74,10 +75,15 @@ typedef struct aff_chunk_t {
unsigned visited;
list_head list;
bool weight_consistent : 1; /**< Set if the weight is consistent. */
+
+ /** The number of nodes in this chunk that have a register requirement to allow to be compressed */
+ int comp_reg_restr_count;
+
#ifndef NDEBUG
bool deleted : 1; /**< For debugging: Set if the was deleted. */
#endif
col_cost_t color_affinity[];
+
} aff_chunk_t;
/**
@@ -103,6 +109,9 @@ typedef struct co_mst_env_t {
col_cost_t **single_cols;
unsigned n_regs; /**< number of regs in class */
unsigned chunk_visited;
+
+ compression_reqs_fct_t get_compression_reqs;
+ bitset_t const *compressible_regs;
} co_mst_env_t;
/* stores coalescing related information for a node */
@@ -119,6 +128,9 @@ typedef struct co_mst_irn_t {
struct list_head list; /**< Queue for coloring undo. */
double constr_factor;
bool fixed:1; /**< the color is fixed */
+
+ /** The node has a register restriction to be compressed. */
+ bool comp_reg_restricted : 1;
} co_mst_irn_t;
static double scaled_edge_weight(const aff_edge_t * edge)
@@ -151,6 +163,14 @@ static co_mst_irn_t *co_mst_irn_init(co_mst_env_t *env, const ir_node *irn)
DB((dbg, LEVEL_4, "Creating phase info for %+F\n", irn));
+ /* Check if there are compression requirements in place */
+ compression_reqs_fct_t get_compression_reqs = env->get_compression_reqs;
+
+ if(get_compression_reqs) {
+ compression_req_t req = get_compression_reqs(irn);
+ res->comp_reg_restricted = (req == comp_req_register_subset) || (req == comp_req_2addr_register_subset);
+ }
+
/* set admissible registers */
unsigned const n_regs = env->n_regs;
bitset_t *const adm = bitset_obstack_alloc(&env->obst, n_regs);
@@ -526,12 +546,19 @@ static void aff_chunk_assure_weight(co_mst_env_t *env, aff_chunk_t *c)
c->color_affinity[i].cost = 0.0;
}
+ int register_restr_count = 0;
int w = 0;
for (unsigned idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) {
const ir_node *n = c->n[idx];
const affinity_node_t *an = get_affinity_info(env->co, n);
co_mst_irn_t *node = get_co_mst_irn(env, n);
+ // Check for register restrictions on the node
+ if(node->comp_reg_restricted) {
+ register_restr_count++;
+ }
+
+
node->chunk = c;
if (node->constr_factor > 0.0) {
bitset_foreach (node->adm_colors, col)
@@ -553,6 +580,8 @@ static void aff_chunk_assure_weight(co_mst_env_t *env, aff_chunk_t *c)
for (unsigned i = 0, n = env->n_regs; i < n; ++i)
c->color_affinity[i].cost *= (1.0 / ARR_LEN(c->n));
+ c->comp_reg_restr_count = register_restr_count;
+
c->weight = w;
// c->weight = bitset_popcount(c->nodes);
c->weight_consistent = true;
@@ -626,7 +655,6 @@ static void build_affinity_chunks(co_mst_env_t *env)
* these weights are pure hackery ;-).
* It's not chriswue's fault but mine.
*/
-
edge.original_weight = neigh->costs;
edge.weight = MAX(1, edge.original_weight * compression_cost_scale);
@@ -1062,10 +1090,18 @@ static void color_aff_chunk(co_mst_env_t *env, aff_chunk_t *c)
}
}
+ double compressibility_factor = c->comp_reg_restr_count / (double)ARR_LEN(c->n);
+
for (unsigned i = 0, n = env->n_regs; i < n; ++i) {
double dislike = n_int_chunks > 0 ? 1.0 - order[i].cost / n_int_chunks : 0.0;
order[i].col = i;
order[i].cost = (1.0 - dislike_influence) * c->color_affinity[i].cost + dislike_influence * dislike;
+
+ // If the register is not compressible, adjust the cost upwards according to the compressibility factor,
+ // up to a maximum set by the compressibility influence parameter.
+ if (!bitset_is_set(env->compressible_regs, i)) {
+ order[i].cost *= compressibility_factor * compressibility_influence;
+ }
}
QSORT(order, env->n_regs, cmp_col_cost_gt);
@@ -1269,6 +1305,14 @@ static int co_solve_heuristic_mst(copy_opt_t *co)
mst_env.chunk_visited = 0;
mst_env.single_cols = OALLOCN(&mst_env.obst, col_cost_t*, n_regs);
+ mst_env.get_compression_reqs = co->cenv->get_compression_reqs;
+
+ // Used to store which registers have compressible register specifiers
+ bitset_t *const bitset_comp_reg = bitset_obstack_alloc(&mst_env.obst, n_regs);
+ mst_env.compressible_regs = bitset_comp_reg;
+
+ const arch_register_class_t *cls = co->cls;
+
for (unsigned i = 0; i < n_regs; ++i) {
col_cost_t *vec = OALLOCN(&mst_env.obst, col_cost_t, n_regs);
@@ -1280,6 +1324,10 @@ static int co_solve_heuristic_mst(copy_opt_t *co)
vec[i].col = 0;
vec[0].col = i;
vec[0].cost = 1.0;
+
+ if (arch_register_for_index(cls, i)->is_compressible) {
+ bitset_set(bitset_comp_reg, i);
+ }
}
DBG((dbg, LEVEL_1, "==== Coloring %+F, class %s ====\n", co->irg, co->cls->name));