Commit e1fa42e4 authored by Matthias Braun's avatar Matthias Braun
Browse files

cleanup, use C99

parent 8dda77c8
......@@ -57,42 +57,43 @@ static firm_dbg_module_t *dbg = NULL;
typedef float real_t;
#define REAL(C) (C ## f)
static unsigned last_chunk_id = 0;
static int recolor_limit = 7;
static double dislike_influence = REAL(0.1);
static unsigned last_chunk_id;
static int recolor_limit = 7;
static double dislike_influence = REAL(0.1);
typedef struct col_cost_t {
int col;
real_t cost;
unsigned col;
real_t cost;
} col_cost_t;
/**
* An affinity chunk.
*/
typedef struct aff_chunk_t {
const ir_node **n; /**< An ARR_F containing all nodes of the chunk. */
const ir_node **interfere; /**< An ARR_F containing all inference. */
int weight; /**< Weight of this chunk */
unsigned weight_consistent : 1; /**< Set if the weight is consistent. */
unsigned deleted : 1; /**< For debugging: Set if the was deleted. */
unsigned id; /**< An id of this chunk. */
unsigned visited;
list_head list;
col_cost_t color_affinity[1];
const ir_node **n; /**< An ARR_F containing all nodes of the chunk. */
const ir_node **interfere; /**< An ARR_F containing all inference. */
int weight; /**< Weight of this chunk */
unsigned id; /**< An id of this chunk. */
unsigned visited;
list_head list;
bool weight_consistent: 1; /**< Set if the weight is consistent. */
#ifndef NDEBUG
bool deleted : 1; /**< For debugging: Set if the was deleted. */
#endif
col_cost_t color_affinity[];
} aff_chunk_t;
/**
* An affinity edge.
*/
typedef struct aff_edge_t {
const ir_node *src; /**< Source node. */
const ir_node *tgt; /**< Target node. */
int weight; /**< The weight of this edge. */
const ir_node *src; /**< Source node. */
const ir_node *tgt; /**< Target node. */
int weight; /**< The weight of this edge. */
} aff_edge_t;
/* main coalescing environment */
typedef struct co_mst_env_t {
int n_regs; /**< number of regs in class */
bitset_t const *allocatable_regs; /**< set containing all global ignore registers */
ir_nodemap map; /**< phase object holding data for nodes */
struct obstack obst;
......@@ -100,24 +101,25 @@ typedef struct co_mst_env_t {
list_head chunklist; /**< list holding all chunks */
be_ifg_t *ifg; /**< the interference graph */
copy_opt_t *co; /**< the copy opt object */
unsigned chunk_visited;
col_cost_t **single_cols;
unsigned n_regs; /**< number of regs in class */
unsigned chunk_visited;
} co_mst_env_t;
/* stores coalescing related information for a node */
typedef struct co_mst_irn_t {
const ir_node *irn; /**< the irn this information belongs to */
aff_chunk_t *chunk; /**< the chunk this irn belongs to */
bitset_t *adm_colors; /**< set of admissible colors for this irn */
ir_node **int_neighs; /**< array of all interfering neighbours (cached for speed reasons) */
int n_neighs; /**< length of the interfering neighbours array. */
int int_aff_neigh; /**< number of interfering affinity neighbours */
int col; /**< color currently assigned */
int init_col; /**< the initial color */
int tmp_col; /**< a temporary assigned color */
unsigned fixed : 1; /**< the color is fixed */
struct list_head list; /**< Queue for coloring undo. */
const ir_node *irn; /**< the irn this information belongs to */
aff_chunk_t *chunk; /**< the chunk this irn belongs to */
bitset_t *adm_colors; /**< set of admissible colors for this irn */
ir_node **int_neighs; /**< array of all interfering neighbours (cached for speed reasons) */
unsigned n_neighs; /**< length of the interfering neighbours array. */
int int_aff_neigh; /**< number of interfering affinity neighbours */
unsigned col; /**< color currently assigned */
unsigned init_col; /**< the initial color */
int tmp_col; /**< a temporary assigned color */
struct list_head list; /**< Queue for coloring undo. */
real_t constr_factor;
bool fixed:1; /**< the color is fixed */
} co_mst_irn_t;
/**
......@@ -177,7 +179,7 @@ static co_mst_irn_t *get_co_mst_irn(co_mst_env_t *env, const ir_node *node)
return res;
}
typedef int decide_func_t(const co_mst_irn_t *node, int col);
typedef bool decide_func_t(const co_mst_irn_t *node, unsigned col);
#ifdef DEBUG_libfirm
......@@ -186,12 +188,11 @@ typedef int decide_func_t(const co_mst_irn_t *node, int col);
*/
static void dbg_aff_chunk(const co_mst_env_t *env, const aff_chunk_t *c)
{
int i, l;
(void) env;
(void)env;
if (c->weight_consistent)
ir_fprintf(stderr, " $%d ", c->weight);
ir_fprintf(stderr, "{");
for (i = 0, l = ARR_LEN(c->n); i < l; ++i) {
for (size_t i = 0, l = ARR_LEN(c->n); i < l; ++i) {
const ir_node *n = c->n[i];
ir_fprintf(stderr, " %+F,", n);
}
......@@ -201,10 +202,10 @@ static void dbg_aff_chunk(const co_mst_env_t *env, const aff_chunk_t *c)
/**
* Dump all admissible colors to stderr.
*/
static void dbg_admissible_colors(const co_mst_env_t *env, const co_mst_irn_t *node)
static void dbg_admissible_colors(const co_mst_env_t *env,
const co_mst_irn_t *node)
{
(void) env;
(void)env;
if (bitset_popcount(node->adm_colors) < 1) {
fprintf(stderr, "no admissible colors?!?");
} else {
......@@ -219,30 +220,29 @@ static void dbg_admissible_colors(const co_mst_env_t *env, const co_mst_irn_t *n
*/
static void dbg_col_cost(const co_mst_env_t *env, const col_cost_t *cost)
{
int i;
for (i = 0; i < env->n_regs; ++i)
fprintf(stderr, " (%d, %.4f)", cost[i].col, cost[i].cost);
for (unsigned i = 0, n = env->n_regs; i < n; ++i)
fprintf(stderr, " (%u, %.4f)", cost[i].col, cost[i].cost);
}
#endif /* DEBUG_libfirm */
static inline int get_mst_irn_col(const co_mst_irn_t *node)
static inline unsigned get_mst_irn_col(const co_mst_irn_t *node)
{
return node->tmp_col >= 0 ? node->tmp_col : node->col;
return node->tmp_col >= 0 ? (unsigned)node->tmp_col : node->col;
}
/**
* @return 1 if node @p node has color @p col, 0 otherwise.
* @return true if node @p node has color @p col, false otherwise.
*/
static int decider_has_color(const co_mst_irn_t *node, int col)
static bool decider_has_color(const co_mst_irn_t *node, unsigned col)
{
return get_mst_irn_col(node) == col;
}
/**
* @return 1 if node @p node has not color @p col, 0 otherwise.
* @return true if node @p node has not color @p col, false otherwise.
*/
static int decider_hasnot_color(const co_mst_irn_t *node, int col)
static bool decider_hasnot_color(const co_mst_irn_t *node, unsigned col)
{
return get_mst_irn_col(node) != col;
}
......@@ -250,11 +250,11 @@ static int decider_hasnot_color(const co_mst_irn_t *node, int col)
/**
* Always returns true.
*/
static int decider_always_yes(const co_mst_irn_t *node, int col)
static bool decider_always_yes(const co_mst_irn_t *node, unsigned col)
{
(void) node;
(void) col;
return 1;
(void)node;
(void)col;
return true;
}
/** compares two affinity edges by its weight */
......@@ -276,9 +276,9 @@ static int cmp_aff_edge(const void *a, const void *b)
/** compares to color-cost pairs */
static __attribute__((unused)) int cmp_col_cost_lt(const void *a, const void *b)
{
const col_cost_t *c1 = (const col_cost_t*)a;
const col_cost_t *c2 = (const col_cost_t*)b;
real_t diff = c1->cost - c2->cost;
const col_cost_t *c1 = (const col_cost_t*)a;
const col_cost_t *c2 = (const col_cost_t*)b;
real_t diff = c1->cost - c2->cost;
if (diff < 0)
return 1;
......@@ -290,9 +290,9 @@ static __attribute__((unused)) int cmp_col_cost_lt(const void *a, const void *b)
static int cmp_col_cost_gt(const void *a, const void *b)
{
const col_cost_t *c1 = (const col_cost_t*)a;
const col_cost_t *c2 = (const col_cost_t*)b;
real_t diff = c2->cost - c1->cost;
const col_cost_t *c1 = (const col_cost_t*)a;
const col_cost_t *c2 = (const col_cost_t*)b;
real_t diff = c2->cost - c1->cost;
if (diff > 0)
return 1;
......@@ -311,8 +311,10 @@ static inline aff_chunk_t *new_aff_chunk(co_mst_env_t *env)
c->n = NEW_ARR_F(const ir_node *, 0);
c->interfere = NEW_ARR_F(const ir_node *, 0);
c->weight = -1;
c->weight_consistent = 0;
c->deleted = 0;
c->weight_consistent = false;
#ifndef NDEBUG
c->deleted = false;
#endif
c->id = ++last_chunk_id;
c->visited = 0;
list_add(&c->list, &env->chunklist);
......@@ -327,7 +329,9 @@ static inline void delete_aff_chunk(aff_chunk_t *c)
list_del(&c->list);
DEL_ARR_F(c->interfere);
DEL_ARR_F(c->n);
c->deleted = 1;
#ifndef NDEBUG
c->deleted = true;
#endif
free(c);
}
......@@ -339,11 +343,11 @@ static inline void delete_aff_chunk(aff_chunk_t *c)
*/
static inline int nodes_bsearch(const ir_node **arr, const ir_node *n)
{
int hi = ARR_LEN(arr);
int lo = 0;
unsigned hi = ARR_LEN(arr);
unsigned lo = 0;
while (lo < hi) {
int md = lo + ((hi - lo) >> 1);
unsigned md = lo + ((hi - lo) / 2);
if (arr[md] == n)
return md;
......@@ -357,7 +361,7 @@ static inline int nodes_bsearch(const ir_node **arr, const ir_node *n)
}
/** Check if a node n can be found inside arr. */
static int node_contains(const ir_node **arr, const ir_node *n)
static bool node_contains(const ir_node **arr, const ir_node *n)
{
int i = nodes_bsearch(arr, n);
return i >= 0;
......@@ -365,28 +369,23 @@ static int node_contains(const ir_node **arr, const ir_node *n)
/**
* Insert a node into the sorted nodes list.
*
* @return 1 if the node was inserted, 0 else
* @return true if the node was inserted
*/
static int nodes_insert(const ir_node ***arr, const ir_node *irn)
static bool nodes_insert(const ir_node ***arr, const ir_node *irn)
{
int idx = nodes_bsearch(*arr, irn);
if (idx < 0) {
int i, n = ARR_LEN(*arr);
const ir_node **l;
ARR_APP1(const ir_node *, *arr, irn);
/* move it */
idx = ~idx;
l = *arr;
for (i = n - 1; i >= idx; --i)
l[i + 1] = l[i];
l[idx] = irn;
return 1;
}
return 0;
if (idx >= 0)
return false;
ARR_APP1(const ir_node *, *arr, irn);
/* move it */
idx = ~idx;
const ir_node **l = *arr;
for (int i = ARR_LEN(*arr) - 2; i >= idx; --i)
l[i + 1] = l[i];
l[idx] = irn;
return true;
}
/**
......@@ -394,15 +393,13 @@ static int nodes_insert(const ir_node ***arr, const ir_node *irn)
*/
static inline void aff_chunk_add_node(aff_chunk_t *c, co_mst_irn_t *node)
{
int i;
if (! nodes_insert(&c->n, node->irn))
if (!nodes_insert(&c->n, node->irn))
return;
c->weight_consistent = 0;
c->weight_consistent = false;
node->chunk = c;
for (i = node->n_neighs - 1; i >= 0; --i) {
for (unsigned i = node->n_neighs; i-- > 0; ) {
ir_node *neigh = node->int_neighs[i];
nodes_insert(&c->interfere, neigh);
}
......@@ -411,7 +408,8 @@ static inline void aff_chunk_add_node(aff_chunk_t *c, co_mst_irn_t *node)
/**
* Check if affinity chunk @p chunk interferes with node @p irn.
*/
static inline int aff_chunk_interferes(const aff_chunk_t *chunk, const ir_node *irn)
static inline bool aff_chunk_interferes(const aff_chunk_t *chunk,
const ir_node *irn)
{
return node_contains(chunk->interfere, irn);
}
......@@ -420,23 +418,22 @@ static inline int aff_chunk_interferes(const aff_chunk_t *chunk, const ir_node *
* Check if there are interference edges from c1 to c2.
* @param c1 A chunk
* @param c2 Another chunk
* @return 1 if there are interferences between nodes of c1 and c2, 0 otherwise.
* @return true if there are interferences between nodes of c1 and c2
*/
static inline int aff_chunks_interfere(const aff_chunk_t *c1, const aff_chunk_t *c2)
static inline bool aff_chunks_interfere(const aff_chunk_t *c1,
const aff_chunk_t *c2)
{
int i;
if (c1 == c2)
return 0;
return false;
/* check if there is a node in c2 having an interfering neighbor in c1 */
for (i = ARR_LEN(c2->n) - 1; i >= 0; --i) {
for (size_t i = ARR_LEN(c2->n); i-- > 0; ) {
const ir_node *irn = c2->n[i];
if (node_contains(c1->interfere, irn))
return 1;
return true;
}
return 0;
return false;
}
/**
......@@ -452,36 +449,37 @@ static inline aff_chunk_t *get_aff_chunk(co_mst_env_t *env, const ir_node *irn)
/**
* Let chunk(src) absorb the nodes of chunk(tgt) (only possible when there
* are no interference edges from chunk(src) to chunk(tgt)).
* @return 1 if successful, 0 if not possible
* @return true if successful, false if not possible
*/
static int aff_chunk_absorb(co_mst_env_t *env, const ir_node *src, const ir_node *tgt)
static bool aff_chunk_absorb(co_mst_env_t *env, const ir_node *src,
const ir_node *tgt)
{
aff_chunk_t *c1 = get_aff_chunk(env, src);
aff_chunk_t *c2 = get_aff_chunk(env, tgt);
#ifdef DEBUG_libfirm
DB((dbg, LEVEL_4, "Attempt to let c1 (id %u): ", c1 ? c1->id : 0));
if (c1) {
DBG_AFF_CHUNK(env, LEVEL_4, c1);
} else {
DB((dbg, LEVEL_4, "{%+F}", src));
}
DB((dbg, LEVEL_4, "\n\tabsorb c2 (id %u): ", c2 ? c2->id : 0));
if (c2) {
DBG_AFF_CHUNK(env, LEVEL_4, c2);
} else {
DB((dbg, LEVEL_4, "{%+F}", tgt));
}
DB((dbg, LEVEL_4, "\n"));
DB((dbg, LEVEL_4, "Attempt to let c1 (id %u): ", c1 ? c1->id : 0));
if (c1) {
DBG_AFF_CHUNK(env, LEVEL_4, c1);
} else {
DB((dbg, LEVEL_4, "{%+F}", src));
}
DB((dbg, LEVEL_4, "\n\tabsorb c2 (id %u): ", c2 ? c2->id : 0));
if (c2) {
DBG_AFF_CHUNK(env, LEVEL_4, c2);
} else {
DB((dbg, LEVEL_4, "{%+F}", tgt));
}
DB((dbg, LEVEL_4, "\n"));
#endif
if (c1 == NULL) {
if (c2 == NULL) {
/* no chunk exists */
co_mst_irn_t *mirn = get_co_mst_irn(env, src);
int i;
for (i = mirn->n_neighs - 1; i >= 0; --i) {
int i;
for (i = mirn->n_neighs; i-- > 0; ) {
if (mirn->int_neighs[i] == tgt)
break;
}
......@@ -494,39 +492,37 @@ static int aff_chunk_absorb(co_mst_env_t *env, const ir_node *src, const ir_node
}
} else {
/* c2 already exists */
if (! aff_chunk_interferes(c2, src)) {
if (!aff_chunk_interferes(c2, src)) {
aff_chunk_add_node(c2, get_co_mst_irn(env, src));
goto absorbed;
}
}
} else if (c2 == NULL) {
/* c1 already exists */
if (! aff_chunk_interferes(c1, tgt)) {
if (!aff_chunk_interferes(c1, tgt)) {
aff_chunk_add_node(c1, get_co_mst_irn(env, tgt));
goto absorbed;
}
} else if (c1 != c2 && ! aff_chunks_interfere(c1, c2)) {
int idx, len;
for (idx = 0, len = ARR_LEN(c2->n); idx < len; ++idx)
} else if (c1 != c2 && !aff_chunks_interfere(c1, c2)) {
for (size_t idx = 0, len = ARR_LEN(c2->n); idx < len; ++idx)
aff_chunk_add_node(c1, get_co_mst_irn(env, c2->n[idx]));
for (idx = 0, len = ARR_LEN(c2->interfere); idx < len; ++idx) {
for (size_t idx = 0, len = ARR_LEN(c2->interfere); idx < len; ++idx) {
const ir_node *irn = c2->interfere[idx];
nodes_insert(&c1->interfere, irn);
}
c1->weight_consistent = 0;
c1->weight_consistent = false;
delete_aff_chunk(c2);
goto absorbed;
}
DB((dbg, LEVEL_4, " ... c1 interferes with c2, skipped\n"));
return 0;
return false;
absorbed:
DB((dbg, LEVEL_4, " ... absorbed\n"));
return 1;
return true;
}
/**
......@@ -534,19 +530,17 @@ absorbed:
*/
static void aff_chunk_assure_weight(co_mst_env_t *env, aff_chunk_t *c)
{
if (! c->weight_consistent) {
int w = 0;
int idx, len, i;
for (i = 0; i < env->n_regs; ++i) {
if (!c->weight_consistent) {
for (unsigned i = 0, n = env->n_regs; i < n; ++i) {
c->color_affinity[i].col = i;
c->color_affinity[i].cost = REAL(0.0);
}
for (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);
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);
node->chunk = c;
if (node->constr_factor > REAL(0.0)) {
......@@ -566,33 +560,32 @@ static void aff_chunk_assure_weight(co_mst_env_t *env, aff_chunk_t *c)
}
}
for (i = 0; i < env->n_regs; ++i)
for (unsigned i = 0, n = env->n_regs; i < n; ++i)
c->color_affinity[i].cost *= (REAL(1.0) / ARR_LEN(c->n));
c->weight = w;
// c->weight = bitset_popcount(c->nodes);
c->weight_consistent = 1;
c->weight_consistent = true;
}
}
/**
* Count the number of interfering affinity neighbours
*/
static int count_interfering_aff_neighs(co_mst_env_t *env, const affinity_node_t *an)
static unsigned count_interfering_aff_neighs(co_mst_env_t *env,
const affinity_node_t *an)
{
const ir_node *irn = an->irn;
const co_mst_irn_t *node = get_co_mst_irn(env, irn);
int res = 0;
unsigned res = 0;
co_gs_foreach_neighb(an, neigh) {
const ir_node *n = neigh->irn;
int i;
if (arch_irn_is_ignore(n))
continue;
/* check if the affinity neighbour interfere */
for (i = 0; i < node->n_neighs; ++i) {
for (unsigned i = 0, n_neighs = node->n_neighs; i < n_neighs; ++i) {
if (node->int_neighs[i] == n) {
++res;
break;
......@@ -616,15 +609,12 @@ static void build_affinity_chunks(co_mst_env_t *env)
/* at first we create the affinity edge objects */
be_ifg_foreach_node(env->ifg, n) {
int n_idx = get_irn_idx(n);
co_mst_irn_t *n1;
affinity_node_t *an;
if (arch_irn_is_ignore(n))
continue;
n1 = get_co_mst_irn(env, n);
an = get_affinity_info(env->co, n);
co_mst_irn_t *n1 = get_co_mst_irn(env, n);
affinity_node_t *an = get_affinity_info(env->co, n);
unsigned n_idx = get_irn_idx(n);
if (an != NULL) {
if (n1->int_aff_neigh < 0)
......@@ -633,21 +623,19 @@ static void build_affinity_chunks(co_mst_env_t *env)
/* build the affinity edges */
co_gs_foreach_neighb(an, neigh) {
const ir_node *m = neigh->irn;
int m_idx = get_irn_idx(m);
unsigned m_idx = get_irn_idx(m);
/* record the edge in only one direction */
if (n_idx < m_idx) {
co_mst_irn_t *n2;
aff_edge_t edge;
/* skip ignore nodes */
if (arch_irn_is_ignore(m))
continue;
aff_edge_t edge;
edge.src = n;
edge.tgt = m;
n2 = get_co_mst_irn(env, m);
co_mst_irn_t *n2 = get_co_mst_irn(env, m);
if (n2->int_aff_neigh < 0) {
affinity_node_t *am = get_affinity_info(env->co, m);
n2->int_aff_neigh = count_interfering_aff_neighs(env, am);
......@@ -682,7 +670,7 @@ static void build_affinity_chunks(co_mst_env_t *env)
pqueue_put(env->chunks, curr_chunk, curr_chunk->weight);
}
for (size_t pn = 0; pn < ARR_LEN(env->map.data); ++pn) {
for (size_t pn = 0, n = ARR_LEN(env->map.data); pn < n; ++pn) {
co_mst_irn_t *mirn = (co_mst_irn_t*)env->map.data[pn];
if (mirn == NULL)
continue;
......@@ -710,16 +698,14 @@ static __attribute__((unused)) void chunk_order_nodes(co_mst_env_t *env, aff_chu
pqueue_t *grow = new_pqueue();
ir_node const *max_node = NULL;
int max_weight = 0;
size_t i;
for (i = ARR_LEN(chunk->n); i != 0;) {
const ir_node *irn = chunk->n[--i];
affinity_node_t *an = get_affinity_info(env->co, irn);
int w = 0;
for (size_t i = ARR_LEN(chunk->n); i-- > 0; ) {
const ir_node *irn = chunk->n[i];
if (arch_irn_is_ignore(irn))
continue;
affinity_node_t *an = get_affinity_info(env->co, irn);
int w = 0;
if (an) {
co_gs_foreach_neighb(an, neigh)
w += neigh->costs;
......@@ -734,12 +720,12 @@ static __attribute__((unused)) void chunk_order_nodes(co_mst_env_t *env, aff_chu
if (max_node) {
bitset_t *visited = bitset_malloc(get_irg_last_idx(env->co->irg));
for (i = ARR_LEN(chunk->n); i != 0;)
bitset_set(visited, get_irn_idx(chunk->n[--i]));
for (size_t i = ARR_LEN(chunk->n); i-- > 0; )
bitset_set(visited, get_irn_idx(chunk->n[i]));
pqueue_put(grow, (void *) max_node, max_weight);
pqueue_put(grow, (void*)max_node, max_weight);
bitset_clear(visited, get_irn_idx(max_node));
i = 0;