tmp = ir_timer_pop();
(void) tmp;
+ (void) id;
assert(tmp == be_timers[id] && "Attempt to pop wrong timer.");
}
#include "besched.h"
#include "belive_t.h"
#include "bearch.h"
-#include "beifg_t.h"
-#include "beifg_impl.h"
+#include "beifg.h"
#include "benode.h"
#include "bestatevent.h"
#include "bestat.h"
int irn_col = qnode_get_new_color(qn, irn);
ir_node *sub_res, *curr;
be_ifg_t *ifg = chordal_env->ifg;
- void *iter = be_ifg_neighbours_iter_alloca(ifg);
+ neighbours_iter_t iter;
DBG((dbg, LEVEL_3, "\t %+F \tcaused col(%+F) \t%2d --> %2d\n", trigger, irn, irn_col, col));
bitset_clear(free_cols, irn_col);
/* Exclude all colors used by adjacent nodes */
- be_ifg_foreach_neighbour(ifg, iter, irn, curr)
+ be_ifg_foreach_neighbour(ifg, &iter, irn, curr)
bitset_clear(free_cols, qnode_get_new_color(qn, curr));
free_col = bitset_next_set(free_cols, 0);
* If we arrive here changing color may be possible, but there may be conflicts.
* Try to color all conflicting nodes 'curr' with the color of the irn itself.
*/
- be_ifg_foreach_neighbour(ifg, iter, irn, curr) {
+ be_ifg_foreach_neighbour(ifg, &iter, irn, curr) {
DBG((dbg, LEVEL_3, "\t Confl %+F(%d)\n", curr, qnode_get_new_color(qn, curr)));
if (qnode_get_new_color(qn, curr) == col && curr != trigger) {
sub_res = qnode_color_irn(qn, curr, irn_col, irn);
if (sub_res != CHANGE_SAVE) {
- be_ifg_neighbours_break(ifg, iter);
+ be_ifg_neighbours_break(&iter);
return sub_res;
}
}
unsigned elm;
const ir_node *pos;
- void *it;
+ neighbours_iter_t it;
int i;
/* Put all forbidden colors into the aux bitset. */
}
}
- it = be_ifg_neighbours_iter_alloca(ifg);
- be_ifg_foreach_neighbour(ifg, it, irn, pos) {
+ be_ifg_foreach_neighbour(ifg, &it, irn, pos) {
col_t col = get_col(env, pos);
if (color_is_fix(env, pos)) {
col_costs[col].costs = INT_MAX;
col_costs[col].costs = add_saturated(col_costs[col].costs, 8 * be_ifg_degree(ifg, pos));
}
}
- be_ifg_neighbours_break(ifg, it);
+ be_ifg_neighbours_break(&it);
/* Set the costs to infinity for each color which is not allowed at this node. */
bitset_foreach(forb, elm) {
struct list_head changed;
const ir_node *n;
- void *it;
+ neighbours_iter_t it;
DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}trying color %d(%d) on %+F\n", depth, tgt_col, costs, irn));
INIT_LIST_HEAD(&changed);
list_add(&ci->changed_list, &changed);
- it = be_ifg_neighbours_iter_alloca(ifg);
- be_ifg_foreach_neighbour(ifg, it, irn, n) {
+ be_ifg_foreach_neighbour(ifg, &it, irn, n) {
/* try to re-color the neighbor if it has the target color. */
if (get_col(env, n) == tgt_col) {
break;
}
}
- be_ifg_neighbours_break(ifg, it);
+ be_ifg_neighbours_break(&it);
/*
We managed to assign the target color to all neighbors, so from the perspective
unsigned elm;
const ir_node *irn;
- void *it;
+ neighbours_iter_t it;
admissible_colors(env, &ci->inh, bs);
bitset_flip_all(bs);
badness[elm] = ci->costs;
/* Use constrained/fixed interfering neighbors to influence the color badness */
- it = be_ifg_neighbours_iter_alloca(ifg);
- be_ifg_foreach_neighbour(ifg, it, ir->irn, irn) {
+ be_ifg_foreach_neighbour(ifg, &it, ir->irn, irn) {
co2_irn_t *ni = get_co2_irn(env, irn);
admissible_colors(env, ni, bs);
badness[c] += ci->costs;
}
}
- be_ifg_neighbours_break(ifg, it);
+ be_ifg_neighbours_break(&it);
}
/**
if (!old) {
const arch_register_req_t *req;
- void *nodes_it = be_ifg_nodes_iter_alloca(env->ifg);
+ neighbours_iter_t nodes_it;
ir_node *neigh;
unsigned len;
/* build list of interfering neighbours */
len = 0;
- be_ifg_foreach_neighbour(env->ifg, nodes_it, irn, neigh) {
+ be_ifg_foreach_neighbour(env->ifg, &nodes_it, irn, neigh) {
if (!arch_irn_is_ignore(neigh)) {
obstack_ptr_grow(phase_obst(ph), neigh);
++len;
*/
static void build_affinity_chunks(co_mst_env_t *env)
{
- void *nodes_it = be_ifg_nodes_iter_alloca(env->ifg);
+ nodes_iter_t nodes_it;
aff_edge_t *edges = NEW_ARR_F(aff_edge_t, 0);
ir_node *n;
int i, len;
aff_chunk_t *curr_chunk;
/* at first we create the affinity edge objects */
- be_ifg_foreach_node(env->ifg, nodes_it, n) {
+ be_ifg_foreach_node(env->ifg, &nodes_it, n) {
int n_idx = get_irn_idx(n);
co_mst_irn_t *n1;
affinity_node_t *an;
}
#include "becopyilp_t.h"
-#include "beifg_t.h"
+#include "beifg.h"
/******************************************************************************
_____ _ _ _ _
static inline int sr_is_simplicial(size_red_t *sr, const ir_node *ifn)
{
be_ifg_t *ifg = sr->co->cenv->ifg;
- void *iter = be_ifg_neighbours_iter_alloca(ifg);
+ neighbours_iter_t iter;
ir_node **all = ALLOCAN(ir_node*, be_ifg_degree(ifg, ifn));
ir_node *curr;
int size = 0;
int o;
/* get all non-removed neighbors */
- be_ifg_foreach_neighbour(ifg, iter, ifn, curr)
+ be_ifg_foreach_neighbour(ifg, &iter, ifn, curr)
if (!sr_is_removed(sr, curr))
all[size++] = curr;
ir_node *irn;
int redo = 1;
const be_ifg_t *ifg = sr->co->cenv->ifg;
- void *iter = be_ifg_nodes_iter_alloca(ifg);
+ nodes_iter_t iter;
while (redo) {
redo = 0;
- be_ifg_foreach_node(ifg, iter, irn) {
+ be_ifg_foreach_node(ifg, &iter, irn) {
const arch_register_req_t *req = arch_get_register_req_out(irn);
if (!arch_register_req_is(req, limited) && !sr_is_removed(sr, irn) && !co_gs_is_optimizable(sr->co, irn)) {
coloring_suffix_t *cs;
be_ifg_t *ifg = sr->co->cenv->ifg;
bitset_t *used_cols = bitset_alloca(arch_register_class_n_regs(sr->co->cls));
- void *iter = be_ifg_neighbours_iter_alloca(ifg);
+ neighbours_iter_t iter;
/* color the removed nodes in right order */
for (cs = sr->col_suff; cs; cs = cs->next) {
irn = cs->irn;
bitset_clear_all(used_cols);
- be_ifg_foreach_neighbour(ifg, iter, irn, other) {
+ be_ifg_foreach_neighbour(ifg, &iter, irn, other) {
if (!sr_is_removed(sr, other)) /* only inspect nodes which are in graph right now */
bitset_set(used_cols, get_irn_col(other));
}
#include "irtools.h"
#include "irgwalk.h"
#include "becopyilp_t.h"
-#include "beifg_t.h"
+#include "beifg.h"
#include "besched.h"
#include "bemodule.h"
static void build_coloring_cstr(ilp_env_t *ienv)
{
be_ifg_t *ifg = ienv->co->cenv->ifg;
- void *iter = be_ifg_nodes_iter_alloca(ifg);
+ nodes_iter_t iter;
bitset_t *colors;
ir_node *irn;
char buf[16];
colors = bitset_alloca(arch_register_class_n_regs(ienv->co->cls));
- be_ifg_foreach_node(ifg, iter, irn)
+ be_ifg_foreach_node(ifg, &iter, irn)
if (!sr_is_removed(ienv->sr, irn)) {
unsigned col;
int cst_idx;
local_env_t *lenv = ienv->env;
be_ifg_t *ifg = ienv->co->cenv->ifg;
int n_colors = lenv->n_colors;
- void *iter = be_ifg_cliques_iter_alloca(ifg);
+ cliques_iter_t iter;
ir_node **clique = ALLOCAN(ir_node*, n_colors);
int size;
int col;
char buf[16];
/* for each maximal clique */
- be_ifg_foreach_clique(ifg, iter, clique, &size) {
+ be_ifg_foreach_clique(ifg, &iter, clique, &size) {
int realsize = 0;
for (i=0; i<size; ++i)
#include "bearch.h"
#include "benode.h"
#include "beutil.h"
-#include "beifg_t.h"
+#include "beifg.h"
#include "beintlive_t.h"
#include "becopyopt_t.h"
#include "becopystat.h"
int *node_map = XMALLOCN(int, get_irg_last_idx(co->irg) + 1);
ir_node *irn;
- void *it, *nit;
+ nodes_iter_t it;
+ neighbours_iter_t nit;
int n, n_regs;
unsigned i;
* the values below n are the pre-colored register nodes
*/
- it = be_ifg_nodes_iter_alloca(ifg);
- nit = be_ifg_neighbours_iter_alloca(ifg);
-
n = n_regs;
- be_ifg_foreach_node(ifg, it, irn) {
+ be_ifg_foreach_node(ifg, &it, irn) {
if (arch_irn_is_ignore(irn))
continue;
node_map[get_irn_idx(irn)] = n++;
fprintf(f, "%d %d\n", n, n_regs);
- be_ifg_foreach_node(ifg, it, irn) {
+ be_ifg_foreach_node(ifg, &it, irn) {
if (!arch_irn_is_ignore(irn)) {
int idx = node_map[get_irn_idx(irn)];
affinity_node_t *a = get_affinity_info(co, irn);
}
}
- be_ifg_foreach_neighbour(ifg, nit, irn, adj) {
+ be_ifg_foreach_neighbour(ifg, &nit, irn, adj) {
if (!arch_irn_is_ignore(adj) &&
!co_dump_appel_disjoint_constraints(co, irn, adj)) {
int adj_idx = node_map[get_irn_idx(adj)];
#include "becopyopt_t.h"
#include "beifg.h"
-#include "beifg_t.h"
+#include "beifg.h"
#include "bemodule.h"
#include "irprintf_t.h"
static int co_solve_heuristic_pbqp(copy_opt_t *co)
{
- void *nodes_it = be_ifg_nodes_iter_alloca(co->cenv->ifg);
- void *neigh_it = be_ifg_neighbours_iter_alloca(co->cenv->ifg);
+ nodes_iter_t nodes_it;
+ neighbours_iter_t neigh_it;
unsigned number_registers = co->cls->n_regs;
unsigned number_nodes = get_irg_last_idx(co->irg);
ir_timer_t *t_ra_copymin_pbqp_create = ir_timer_new();
be_put_ignore_regs(co->cenv->birg, co->cls, pbqp_co.ignore_reg);
/* add costs vector to nodes */
- be_ifg_foreach_node(co->cenv->ifg, nodes_it, ifg_node) {
+ be_ifg_foreach_node(co->cenv->ifg, &nodes_it, ifg_node) {
int cntFreeChoosableRegs = 0;
/* create costs vector */
}
/* add pbqp edges and cost matrix */
- be_ifg_foreach_node(co->cenv->ifg, nodes_it, ifg_node) {
+ be_ifg_foreach_node(co->cenv->ifg, &nodes_it, ifg_node) {
/* add costs matrix between nodes (interference edge) */
- be_ifg_foreach_neighbour(co->cenv->ifg, neigh_it, ifg_node, if_neighb_node) {
+ be_ifg_foreach_neighbour(co->cenv->ifg, &neigh_it, ifg_node, if_neighb_node) {
if (get_edge(pbqp_co.pbqp,get_irn_idx(ifg_node), get_irn_idx(if_neighb_node)) == NULL) {
/* copy matrix */
struct pbqp_matrix *matrix = pbqp_matrix_copy(pbqp_co.pbqp, ife_matrix);
assert(solution != INF_COSTS && "No PBQP solution found");
/* coloring ifg */
- be_ifg_foreach_node(co->cenv->ifg, nodes_it, ifg_node) {
+ be_ifg_foreach_node(co->cenv->ifg, &nodes_it, ifg_node) {
num index = get_node_solution(pbqp_co.pbqp, get_irn_idx(ifg_node));
const arch_register_t *reg = arch_register_for_index(co->cls, index);
arch_set_irn_register(ifg_node, reg);
#include "irprintf.h"
#include "irtools.h"
#include "irbitset.h"
-#include "beifg_t.h"
-#include "beifg_impl.h"
+#include "beifg.h"
#include "irphase_t.h"
#include "error.h"
#include "xmalloc.h"
#include "becopyopt.h"
#include "beirg.h"
#include "bemodule.h"
+#include "beintlive_t.h"
-/** Defines values for the ifg performance test */
-#define BE_CH_PERFORMANCETEST_MIN_NODES (50)
-#define BE_CH_PERFORMANCETEST_COUNT (500)
-
-typedef struct _coloring_t coloring_t;
-
-struct _coloring_t {
- ir_phase ph;
- ir_graph *irg;
-};
-
-size_t (be_ifg_nodes_iter_size)(const be_ifg_t *ifg)
+void be_ifg_free(be_ifg_t *self)
{
- return ifg->impl->nodes_iter_size;
+ free(self);
}
-size_t (be_ifg_neighbours_iter_size)(const be_ifg_t *ifg)
+int be_ifg_connected(const be_ifg_t *ifg, const ir_node *a, const ir_node *b)
{
- return ifg->impl->neighbours_iter_size;
+ return be_values_interfere(ifg->env->birg->lv, a, b);
}
-size_t (be_ifg_cliques_iter_size)(const be_ifg_t *ifg)
+static void nodes_walker(ir_node *bl, void *data)
{
- return ifg->impl->cliques_iter_size;
+ nodes_iter_t *it = data;
+ struct list_head *head = get_block_border_head(it->env, bl);
+ border_t *b;
+
+ foreach_border_head(head, b) {
+ if (b->is_def && b->is_real) {
+ obstack_ptr_grow(&it->obst, b->irn);
+ it->n++;
+ }
+ }
}
-static void *regs_irn_data_init(ir_phase *ph, const ir_node *irn, void *data)
+static void find_nodes(const be_ifg_t *ifg, nodes_iter_t *iter)
{
- (void)ph;
- (void)data;
+ obstack_init(&iter->obst);
+ iter->n = 0;
+ iter->curr = 0;
+ iter->env = ifg->env;
- return (void*)arch_get_irn_register(irn);
+ irg_block_walk_graph(ifg->env->irg, nodes_walker, NULL, iter);
+ obstack_ptr_grow(&iter->obst, NULL);
+ iter->nodes = obstack_finish(&iter->obst);
}
-static coloring_t *coloring_init(coloring_t *c, ir_graph *irg)
+static inline void node_break(nodes_iter_t *it, int force)
{
- phase_init(&c->ph, irg, regs_irn_data_init);
- c->irg = irg;
- return c;
+ if ((it->curr >= it->n || force) && it->nodes) {
+ obstack_free(&it->obst, NULL);
+ it->nodes = NULL;
+ }
}
-static void get_irn_color(ir_node *irn, void *c)
+static ir_node *get_next_node(nodes_iter_t *it)
{
- coloring_t *coloring = c;
- phase_get_or_set_irn_data(&coloring->ph, irn);
-}
+ ir_node *res = NULL;
-static void restore_irn_color(ir_node *irn, void *c)
-{
- coloring_t *coloring = c;
- const arch_register_t *reg = phase_get_irn_data(&coloring->ph, irn);
- if (reg)
- arch_set_irn_register(irn, reg);
-}
+ if (it->curr < it->n)
+ res = it->nodes[it->curr++];
-static void coloring_save(coloring_t *c)
-{
- irg_walk_graph(c->irg, NULL, get_irn_color, c);
-}
+ node_break(it, 0);
-static void coloring_restore(coloring_t *c)
-{
- irg_walk_graph(c->irg, NULL, restore_irn_color, c);
+ return res;
}
-void (be_ifg_free)(be_ifg_t *ifg)
+ir_node *be_ifg_nodes_begin(const be_ifg_t *ifg, nodes_iter_t *iter)
{
- ifg->impl->free(ifg);
+ find_nodes(ifg, iter);
+ return get_next_node(iter);
}
-int (be_ifg_connected)(const be_ifg_t *ifg, const ir_node *a, const ir_node *b)
+ir_node *be_ifg_nodes_next(nodes_iter_t *iter)
{
- return ifg->impl->connected(ifg, a, b);
+ return get_next_node(iter);
}
-ir_node *(be_ifg_neighbours_begin)(const be_ifg_t *ifg, void *iter, const ir_node *irn)
+void be_ifg_nodes_break(nodes_iter_t *iter)
{
- return ifg->impl->neighbours_begin(ifg, iter, irn);
+ node_break(iter, 1);
}
-ir_node *(be_ifg_neighbours_next)(const be_ifg_t *ifg, void *iter)
+static void find_neighbour_walker(ir_node *block, void *data)
{
- return ifg->impl->neighbours_next(ifg, iter);
-}
+ neighbours_iter_t *it = data;
+ struct list_head *head = get_block_border_head(it->env, block);
-void (be_ifg_neighbours_break)(const be_ifg_t *ifg, void *iter)
-{
- ifg->impl->neighbours_break(ifg, iter);
-}
+ border_t *b;
+ int has_started = 0;
-ir_node *(be_ifg_nodes_begin)(const be_ifg_t *ifg, void *iter)
-{
- return ifg->impl->nodes_begin(ifg, iter);
-}
+ if (!be_is_live_in(it->env->birg->lv, block, it->irn) && block != get_nodes_block(it->irn))
+ return;
-ir_node *(be_ifg_nodes_next)(const be_ifg_t *ifg, void *iter)
-{
- return ifg->impl->nodes_next(ifg, iter);
+ foreach_border_head(head, b) {
+ ir_node *irn = b->irn;
+
+ if (irn == it->irn) {
+ if (b->is_def)
+ has_started = 1;
+ else
+ break; /* if we reached the end of the node's lifetime we can safely break */
+ }
+ else if (b->is_def) {
+ /* if any other node than the one in question starts living, add it to the set */
+ ir_nodeset_insert(&it->neighbours, irn);
+ }
+ else if (!has_started) {
+ /* we only delete, if the live range in question has not yet started */
+ ir_nodeset_remove(&it->neighbours, irn);
+ }
+
+ }
}
-void (be_ifg_nodes_break)(const be_ifg_t *ifg, void *iter)
+static void find_neighbours(const be_ifg_t *ifg, neighbours_iter_t *it, const ir_node *irn)
{
- ifg->impl->nodes_break(ifg, iter);
+ it->env = ifg->env;
+ it->irn = irn;
+ it->valid = 1;
+ ir_nodeset_init(&it->neighbours);
+
+ dom_tree_walk(get_nodes_block(irn), find_neighbour_walker, NULL, it);
+
+ ir_nodeset_iterator_init(&it->iter, &it->neighbours);
}
-int (be_ifg_cliques_begin)(const be_ifg_t *ifg, void *iter, ir_node **buf)
+static inline void neighbours_break(neighbours_iter_t *it, int force)
{
- return ifg->impl->cliques_begin(ifg, iter, buf);
+ (void) force;
+ assert(it->valid == 1);
+ ir_nodeset_destroy(&it->neighbours);
+ it->valid = 0;
}
-int (be_ifg_cliques_next)(const be_ifg_t *ifg, void *iter)
+static ir_node *get_next_neighbour(neighbours_iter_t *it)
{
- return ifg->impl->cliques_next(ifg, iter);
+ ir_node *res = ir_nodeset_iterator_next(&it->iter);
+
+ if (res == NULL) {
+ ir_nodeset_destroy(&it->neighbours);
+ }
+ return res;
}
-void (be_ifg_cliques_break)(const be_ifg_t *ifg, void *iter)
+ir_node *be_ifg_neighbours_begin(const be_ifg_t *ifg, neighbours_iter_t *iter,
+ const ir_node *irn)
{
- ifg->impl->cliques_break(ifg, iter);
+ find_neighbours(ifg, iter, irn);
+ return ir_nodeset_iterator_next(&iter->iter);
}
-int (be_ifg_degree)(const be_ifg_t *ifg, const ir_node *irn)
+ir_node *be_ifg_neighbours_next(neighbours_iter_t *iter)
{
- return ifg->impl->degree(ifg, irn);
+ return get_next_neighbour(iter);
}
-
-void be_ifg_check(const be_ifg_t *ifg)
+void be_ifg_neighbours_break(neighbours_iter_t *iter)
{
- void *iter1 = be_ifg_nodes_iter_alloca(ifg);
- void *iter2 = be_ifg_neighbours_iter_alloca(ifg);
-
- ir_node *n, *m;
- int node_count = 0;
- int neighbours_count = 0;
- int degree = 0;
-
- /* count all nodes */
- ir_printf("\n\nFound the following nodes in the graph %+F:\n\n", current_ir_graph);
- be_ifg_foreach_node(ifg,iter1,n)
- {
- node_count++;
- degree = be_ifg_degree(ifg, n);
- ir_printf("%d. %+F with degree: %d\n", node_count, n, degree);
- }
-
- ir_printf("\n\nNumber of nodes: %d\n\n", node_count);
-
- /* Check, if all neighbours are indeed connected to the node. */
- be_ifg_foreach_node(ifg, iter1, n)
- {
- ir_printf("\n%+F; ", n);
- be_ifg_foreach_neighbour(ifg, iter2, n, m)
- {
- ir_printf("%+F; ", m);
- neighbours_count++;
- if (!be_ifg_connected(ifg, n, m))
- ir_fprintf(stderr, "%+F is a neighbour of %+F but they are not connected!\n", n, m);
- }
- }
- ir_printf("\n\nFound %d nodes in the 'check neighbour section'\n", neighbours_count);
+ neighbours_break(iter, 1);
}
-static int be_ifg_check_get_node_count(const be_ifg_t *ifg)
+static inline void free_clique_iter(cliques_iter_t *it)
{
- void *iter = be_ifg_nodes_iter_alloca(ifg);
- int node_count = 0;
- ir_node *n;
-
- be_ifg_foreach_node(ifg, iter, n)
- {
- node_count++;
- }
-
- return node_count;
+ it->n_blocks = -1;
+ obstack_free(&it->ob, NULL);
+ del_pset(it->living);
}
-static int be_ifg_check_cmp_nodes(const void *a, const void *b)
+static void get_blocks_dom_order(ir_node *blk, void *env)
{
- const ir_node *node_a = *(ir_node **)a;
- const ir_node *node_b = *(ir_node **)b;
-
- long nr_a = get_irn_idx(node_a);
- long nr_b = get_irn_idx(node_b);
-
- return QSORT_CMP(nr_a, nr_b);
+ cliques_iter_t *it = env;
+ obstack_ptr_grow(&it->ob, blk);
}
-void be_ifg_check_sorted(const be_ifg_t *ifg)
+/**
+ * NOTE: Be careful when changing this function!
+ * First understand the control flow of consecutive calls.
+ */
+static inline int get_next_clique(cliques_iter_t *it)
{
- void *iter1 = be_ifg_nodes_iter_alloca(ifg);
- void *iter2 = be_ifg_neighbours_iter_alloca(ifg);
- ir_node *n, *m;
- const int node_count = be_ifg_check_get_node_count(ifg);
- int i = 0;
+ /* continue in the block we left the last time */
+ for (; it->blk < it->n_blocks; it->blk++) {
+ int output_on_shrink = 0;
+ struct list_head *head = get_block_border_head(it->cenv, it->blocks[it->blk]);
- ir_node **all_nodes = XMALLOCN(ir_node*, node_count);
+ /* on entry to a new block set the first border ... */
+ if (!it->bor)
+ it->bor = head->prev;
- be_ifg_foreach_node(ifg, iter1, n)
- {
- if (!node_is_in_irgs_storage(ifg->env->irg, n))
- {
- ir_printf("+%F is in ifg but not in the current irg!", n);
- assert (node_is_in_irgs_storage(ifg->env->irg, n));
- }
+ /* ... otherwise continue with the border we left the last time */
+ for (; it->bor != head; it->bor = it->bor->prev) {
+ border_t *b = list_entry(it->bor, border_t, list);
- all_nodes[i] = n;
- i++;
- }
-
- qsort(all_nodes, node_count, sizeof(all_nodes[0]), be_ifg_check_cmp_nodes);
+ /* if its a definition irn starts living */
+ if (b->is_def) {
+ pset_insert_ptr(it->living, b->irn);
+ if (b->is_real)
+ output_on_shrink = 1;
+ } else
- for (i = 0; i < node_count; i++)
- {
- ir_node **neighbours = XMALLOCN(ir_node*, node_count);
- int j = 0;
- int k = 0;
- int degree = 0;
+ /* if its the last usage the irn dies */
+ {
+ /* before shrinking the set, return the current maximal clique */
+ if (output_on_shrink) {
+ int count = 0;
+ ir_node *irn;
- degree = be_ifg_degree(ifg, all_nodes[i]);
+ /* fill the output buffer */
+ for (irn = pset_first(it->living); irn != NULL;
+ irn = pset_next(it->living)) {
+ it->buf[count++] = irn;
+ }
- be_ifg_foreach_neighbour(ifg, iter2, all_nodes[i], m)
- {
- neighbours[j] = m;
- j++;
- }
+ assert(count > 0 && "We have a 'last usage', so there must be sth. in it->living");
- qsort(neighbours, j, sizeof(neighbours[0]), be_ifg_check_cmp_nodes);
+ return count;
+ }
- ir_printf("%d. %+F's neighbours(%d): ", i+1, all_nodes[i], degree);
-
- for (k = 0; k < j; k++)
- {
- ir_printf("%+F, ", neighbours[k]);
+ pset_remove_ptr(it->living, b->irn);
+ }
}
- ir_printf("\n");
-
- free(neighbours);
+ it->bor = NULL;
+ assert(0 == pset_count(it->living) && "Something has survived! (At the end of the block it->living must be empty)");
}
- free(all_nodes);
+ if (it->n_blocks != -1)
+ free_clique_iter(it);
+ return -1;
}
-void be_ifg_check_sorted_to_file(const be_ifg_t *ifg, FILE *f)
+int be_ifg_cliques_begin(const be_ifg_t *ifg, cliques_iter_t *it,
+ ir_node **buf)
{
- void *iter1 = be_ifg_nodes_iter_alloca(ifg);
- void *iter2 = be_ifg_neighbours_iter_alloca(ifg);
-
- ir_node *n, *m;
- const int node_count = be_ifg_check_get_node_count(ifg);
- int i = 0;
-
- ir_node **all_nodes = XMALLOCN(ir_node*, node_count);
-
- be_ifg_foreach_node(ifg, iter1, n)
- {
- if (!node_is_in_irgs_storage(ifg->env->irg, n))
- {
- ir_fprintf (f,"+%F is in ifg but not in the current irg!",n);
- assert (node_is_in_irgs_storage(ifg->env->irg, n));
- }
-
- all_nodes[i] = n;
- i++;
- }
+ ir_node *start_bl = get_irg_start_block(ifg->env->irg);
- qsort(all_nodes, node_count, sizeof(all_nodes[0]), be_ifg_check_cmp_nodes);
+ obstack_init(&it->ob);
+ dom_tree_walk(start_bl, get_blocks_dom_order, NULL, it);
- for (i = 0; i < node_count; i++)
- {
- ir_node **neighbours = XMALLOCN(ir_node*, node_count);
- int j = 0;
- int k = 0;
- int degree = 0;
-
- degree = be_ifg_degree(ifg, all_nodes[i]);
-
- be_ifg_foreach_neighbour(ifg, iter2, all_nodes[i], m)
- {
- neighbours[j] = m;
- j++;
- }
-
- qsort(neighbours, j, sizeof(neighbours[0]), be_ifg_check_cmp_nodes);
-
- ir_fprintf (f,"%d. %+F's neighbours(%d): ", i+1, all_nodes[i], degree);
-
- for (k = 0; k < j; k++)
- {
- ir_fprintf (f,"%+F, ", neighbours[k]);
- }
-
- ir_fprintf (f,"\n");
-
- free(neighbours);
- }
-
- free(all_nodes);
+ it->cenv = ifg->env;
+ it->buf = buf;
+ it->n_blocks = obstack_object_size(&it->ob) / sizeof(void *);
+ it->blocks = obstack_finish(&it->ob);
+ it->blk = 0;
+ it->bor = NULL;
+ it->living = pset_new_ptr(2 * arch_register_class_n_regs(it->cenv->cls));
+ return get_next_clique(it);
}
-void be_ifg_check_performance(be_chordal_env_t *chordal_env)
+int be_ifg_cliques_next(cliques_iter_t *iter)
{
- int tests = BE_CH_PERFORMANCETEST_COUNT;
- coloring_t coloring;
-
- int used_memory;
-
- int i = 0;
- int rt;
- copy_opt_t *co;
- be_ifg_t *old_if = chordal_env->ifg;
-
- ir_timer_t *timer = ir_timer_new();
- unsigned long elapsed_usec = 0;
-
- if (get_irg_estimated_node_cnt(chordal_env->irg) >= BE_CH_PERFORMANCETEST_MIN_NODES)
- {
- coloring_init(&coloring, chordal_env->irg);
- coloring_save(&coloring);
-
- ir_timer_reset(timer);
-
- for (i = 0; i<tests; i++) /* performance test with std */
- {
-
- used_memory = ir_get_heap_used_bytes();
-
- rt = ir_timer_enter_high_priority();
- ir_timer_start(timer);
-
- chordal_env->ifg = be_ifg_std_new(chordal_env);
-
- ir_timer_stop(timer);
- rt = ir_timer_leave_high_priority();
-
- used_memory = ir_get_heap_used_bytes() - used_memory;
-
- coloring_restore(&coloring);
-
- co = NULL;
- co = new_copy_opt(chordal_env, co_get_costs_loop_depth);
- co_build_ou_structure(co);
- co_build_graph_structure(co);
-
- rt = ir_timer_enter_high_priority();
- ir_timer_start(timer);
-
- co_solve_heuristic_new(co);
-
- ir_timer_stop(timer);
- rt = ir_timer_leave_high_priority();
-
- co_free_graph_structure(co);
- co_free_ou_structure(co);
- free_copy_opt(co);
- be_ifg_free(chordal_env->ifg);
-
- }
-
- elapsed_usec = ir_timer_elapsed_usec(timer);
- /* calculating average */
- elapsed_usec = elapsed_usec / tests;
-
- ir_printf("\nstd:; %+F; %u; %u ",current_ir_graph, used_memory, elapsed_usec);
-
- used_memory=0;
- elapsed_usec=0;
-
- for (i = 0; i<tests; i++) /* performance test with clique */
- {
- used_memory = ir_get_heap_used_bytes();
-
- rt = ir_timer_enter_high_priority();
- ir_timer_start(timer);
-
- chordal_env->ifg = be_ifg_clique_new(chordal_env);
-
- ir_timer_stop(timer);
- rt = ir_timer_leave_high_priority();
-
- used_memory = ir_get_heap_used_bytes() - used_memory;
-
- coloring_restore(&coloring);
-
- co = NULL;
- co = new_copy_opt(chordal_env, co_get_costs_loop_depth);
- co_build_ou_structure(co);
- co_build_graph_structure(co);
-
- rt = ir_timer_enter_high_priority();
- ir_timer_start(timer);
-
- co_solve_heuristic_new(co);
-
- ir_timer_stop(timer);
- rt = ir_timer_leave_high_priority();
-
- co_free_graph_structure(co);
- co_free_ou_structure(co);
- free_copy_opt(co);
- be_ifg_free(chordal_env->ifg);
-
- }
-
- elapsed_usec = ir_timer_elapsed_usec(timer);
- /* calculating average */
- elapsed_usec = elapsed_usec / tests;
-
- ir_printf("\nclique:; %+F; %u; %u ",current_ir_graph, used_memory, elapsed_usec);
-
- used_memory=0;
- elapsed_usec=0;
-
- for (i = 0; i<tests; i++) /* performance test with list */
- {
- used_memory = ir_get_heap_used_bytes();
-
- rt = ir_timer_enter_high_priority();
- ir_timer_start(timer);
-
- chordal_env->ifg = be_ifg_list_new(chordal_env);
-
- ir_timer_stop(timer);
- rt = ir_timer_leave_high_priority();
-
- used_memory = ir_get_heap_used_bytes() - used_memory;
-
- coloring_restore(&coloring);
-
- co = NULL;
- co = new_copy_opt(chordal_env, co_get_costs_loop_depth);
- co_build_ou_structure(co);
- co_build_graph_structure(co);
-
- rt = ir_timer_enter_high_priority();
- ir_timer_start(timer);
-
- co_solve_heuristic_new(co);
-
- ir_timer_stop(timer);
- rt = ir_timer_leave_high_priority();
-
- co_free_graph_structure(co);
- co_free_ou_structure(co);
- free_copy_opt(co);
- be_ifg_free(chordal_env->ifg);
-
- }
-
- elapsed_usec = ir_timer_elapsed_usec(timer);
- /* calculating average */
- elapsed_usec = elapsed_usec / tests;
-
- ir_printf("\nlist:; %+F; %u; %u ",current_ir_graph, used_memory, elapsed_usec);
-
- used_memory=0;
- elapsed_usec=0;
-
- for (i = 0; i<tests; i++) /* performance test with pointer */
- {
- used_memory = ir_get_heap_used_bytes();
-
- rt = ir_timer_enter_high_priority();
- ir_timer_start(timer);
-
- chordal_env->ifg = be_ifg_pointer_new(chordal_env);
-
- ir_timer_stop(timer);
- rt = ir_timer_leave_high_priority();
-
- used_memory = ir_get_heap_used_bytes() - used_memory;
-
- coloring_restore(&coloring);
-
- co = NULL;
- co = new_copy_opt(chordal_env, co_get_costs_loop_depth);
- co_build_ou_structure(co);
- co_build_graph_structure(co);
-
- rt = ir_timer_enter_high_priority();
- ir_timer_start(timer);
-
- co_solve_heuristic_new(co);
-
- ir_timer_stop(timer);
- rt = ir_timer_leave_high_priority();
-
- co_free_graph_structure(co);
- co_free_ou_structure(co);
- free_copy_opt(co);
- be_ifg_free(chordal_env->ifg);
-
- }
-
- elapsed_usec = ir_timer_elapsed_usec(timer);
- /* calculating average */
- elapsed_usec = elapsed_usec / tests;
+ return get_next_clique(iter);
+}
- ir_printf("\npointer:; %+F; %u; %u ",current_ir_graph, used_memory, elapsed_usec);
+void be_ifg_cliques_break(cliques_iter_t *iter)
+{
+ free_clique_iter(iter);
+}
- i=0;
- used_memory=0;
- elapsed_usec=0;
- }
+int be_ifg_degree(const be_ifg_t *ifg, const ir_node *irn)
+{
+ neighbours_iter_t it;
+ int degree;
+ find_neighbours(ifg, &it, irn);
+ degree = ir_nodeset_size(&it.neighbours);
+ neighbours_break(&it, 1);
+ return degree;
+}
- chordal_env->ifg = old_if;
+be_ifg_t *be_create_ifg(const be_chordal_env_t *env)
+{
+ be_ifg_t *ifg = XMALLOC(be_ifg_t);
+ ifg->env = env;
- ir_timer_free(timer);
+ return ifg;
}
void be_ifg_dump_dot(be_ifg_t *ifg, ir_graph *irg, FILE *file, const be_ifg_dump_dot_cb_t *cb, void *self)
{
- void *nodes_it = be_ifg_nodes_iter_alloca(ifg);
- void *neigh_it = be_ifg_neighbours_iter_alloca(ifg);
+ nodes_iter_t nodes_it;
+ neighbours_iter_t neigh_it;
bitset_t *nodes = bitset_malloc(get_irg_last_idx(irg));
ir_node *n, *m;
if (cb->at_begin)
cb->at_begin(file, self);
- be_ifg_foreach_node(ifg, nodes_it, n) {
+ be_ifg_foreach_node(ifg, &nodes_it, n) {
if (cb->is_dump_node && cb->is_dump_node(self, n)) {
int idx = get_irn_idx(n);
bitset_set(nodes, idx);
}
/* Check, if all neighbours are indeed connected to the node. */
- be_ifg_foreach_node(ifg, nodes_it, n) {
- be_ifg_foreach_neighbour(ifg, neigh_it, n, m) {
+ be_ifg_foreach_node(ifg, &nodes_it, n) {
+ be_ifg_foreach_neighbour(ifg, &neigh_it, n, m) {
int n_idx = get_irn_idx(n);
int m_idx = get_irn_idx(m);
static void int_comp_rec(be_ifg_t *ifg, ir_node *n, bitset_t *seen)
{
- void *neigh_it = be_ifg_neighbours_iter_alloca(ifg);
+ neighbours_iter_t neigh_it;
ir_node *m;
- be_ifg_foreach_neighbour(ifg, neigh_it, n, m) {
+ be_ifg_foreach_neighbour(ifg, &neigh_it, n, m) {
if (bitset_contains_irn(seen, m))
continue;
static int int_component_stat(be_irg_t *birg, be_ifg_t *ifg)
{
int n_comp = 0;
- void *nodes_it = be_ifg_nodes_iter_alloca(ifg);
+ nodes_iter_t nodes_it;
bitset_t *seen = bitset_irg_malloc(birg->irg);
ir_node *n;
- be_ifg_foreach_node(ifg, nodes_it, n) {
+ be_ifg_foreach_node(ifg, &nodes_it, n) {
if (bitset_contains_irn(seen, n))
continue;
void be_ifg_stat(be_irg_t *birg, be_ifg_t *ifg, be_ifg_stat_t *stat)
{
- void *nodes_it = be_ifg_nodes_iter_alloca(ifg);
- void *neigh_it = be_ifg_neighbours_iter_alloca(ifg);
- bitset_t *nodes = bitset_irg_malloc(birg->irg);
- ir_node *n, *m;
+ nodes_iter_t nodes_it;
+ neighbours_iter_t neigh_it;
+ bitset_t *nodes = bitset_irg_malloc(birg->irg);
+ ir_node *n, *m;
memset(stat, 0, sizeof(stat[0]));
- be_ifg_foreach_node(ifg, nodes_it, n) {
+ be_ifg_foreach_node(ifg, &nodes_it, n) {
stat->n_nodes += 1;
- be_ifg_foreach_neighbour(ifg, neigh_it, n, m) {
+ be_ifg_foreach_neighbour(ifg, &neigh_it, n, m) {
bitset_add_irn(nodes, n);
stat->n_edges += !bitset_contains_irn(nodes, m);
}
stat->n_comps = int_component_stat(birg, ifg);
bitset_free(nodes);
}
-
-enum {
- BE_IFG_STD = 1,
- BE_IFG_FAST = 2,
- BE_IFG_CLIQUE = 3,
- BE_IFG_POINTER = 4,
- BE_IFG_LIST = 5,
- BE_IFG_CHECK = 6
-};
-
-static int ifg_flavor = BE_IFG_STD;
-
-static const lc_opt_enum_int_items_t ifg_flavor_items[] = {
- { "std", BE_IFG_STD },
- { "fast", BE_IFG_FAST },
- { "clique", BE_IFG_CLIQUE },
- { "pointer", BE_IFG_POINTER },
- { "list", BE_IFG_LIST },
- { "check", BE_IFG_CHECK },
- { NULL, 0 }
-};
-
-static lc_opt_enum_int_var_t ifg_flavor_var = {
- &ifg_flavor, ifg_flavor_items
-};
-
-static const lc_opt_table_entry_t be_ifg_options[] = {
- LC_OPT_ENT_ENUM_PTR ("ifg", "interference graph flavour", &ifg_flavor_var),
- LC_OPT_LAST
-};
-
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_ifg);
-void be_init_ifg(void)
-{
- lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
- lc_opt_entry_t *ifg_grp = lc_opt_get_grp(be_grp, "ifg");
-
- lc_opt_add_table(ifg_grp, be_ifg_options);
-}
-
-
-static FILE *be_ifg_open(const be_chordal_env_t *env, const char *prefix)
-{
- FILE *result;
- char buf[1024];
-
- ir_snprintf(buf, sizeof(buf), "%s%F_%s.log", prefix, env->irg, env->cls->name);
- result = fopen(buf, "wt");
- if (result == NULL) {
- panic("Couldn't open '%s' for writing.", buf);
- }
-
- return result;
-}
-
-static void check_ifg_implementations(const be_chordal_env_t *chordal_env)
-{
- be_ifg_t *ifg;
- FILE *f;
-
- f = be_ifg_open(chordal_env, "std");
- ifg = be_ifg_std_new(chordal_env);
- be_ifg_check_sorted_to_file(ifg, f);
- fclose(f);
- be_ifg_free(ifg);
-
- f = be_ifg_open(chordal_env, "list");
- ifg = be_ifg_list_new(chordal_env);
- be_ifg_check_sorted_to_file(ifg, f);
- fclose(f);
- be_ifg_free(ifg);
-
- f = be_ifg_open(chordal_env, "clique");
- ifg = be_ifg_clique_new(chordal_env);
- be_ifg_check_sorted_to_file(ifg, f);
- fclose(f);
- be_ifg_free(ifg);
-
- f = be_ifg_open(chordal_env, "pointer");
- ifg = be_ifg_pointer_new(chordal_env);
- be_ifg_check_sorted_to_file(ifg, f);
- fclose(f);
- be_ifg_free(ifg);
-};
-
-be_ifg_t *be_create_ifg(const be_chordal_env_t *chordal_env)
-{
- be_ifg_t *ifg = NULL;
-
- switch (ifg_flavor) {
- default:
- panic("invalid ifg flavour selected");
- case BE_IFG_STD:
- case BE_IFG_FAST:
- ifg = be_ifg_std_new(chordal_env);
- break;
- case BE_IFG_CLIQUE:
- ifg = be_ifg_clique_new(chordal_env);
- break;
- case BE_IFG_POINTER:
- ifg = be_ifg_pointer_new(chordal_env);
- break;
- case BE_IFG_LIST:
- ifg = be_ifg_list_new(chordal_env);
- break;
- case BE_IFG_CHECK:
- check_ifg_implementations(chordal_env);
- /* Build the interference graph. */
- ifg = be_ifg_std_new(chordal_env);
- break;
- }
-
- return ifg;
-}
#include <stdio.h>
#include "irnode.h"
+#include "irnodeset.h"
#include "becopyopt.h"
#include "beirg.h"
-typedef struct _be_ifg_impl_t be_ifg_impl_t;
-typedef struct _be_ifg_t be_ifg_t;
-
-#define be_ifg_nodes_iter_alloca(self) (alloca(be_ifg_nodes_iter_size(self)))
-#define be_ifg_neighbours_iter_alloca(self) (alloca(be_ifg_neighbours_iter_size(self)))
-#define be_ifg_cliques_iter_alloca(self) (alloca(be_ifg_cliques_iter_size(self)))
-
-size_t (be_ifg_nodes_iter_size)(const be_ifg_t *self);
-size_t (be_ifg_neighbours_iter_size)(const be_ifg_t *self);
-size_t (be_ifg_cliques_iter_size)(const be_ifg_t *self);
-void (be_ifg_free)(be_ifg_t *self);
-int (be_ifg_connected)(const be_ifg_t *self, const ir_node *a, const ir_node *b);
-ir_node *(be_ifg_neighbours_begin)(const be_ifg_t *self, void *iter, const ir_node *irn);
-ir_node *(be_ifg_neighbours_next)(const be_ifg_t *self, void *iter);
-void (be_ifg_neighbours_break)(const be_ifg_t *self, void *iter);
-ir_node *(be_ifg_nodes_begin)(const be_ifg_t *self, void *iter);
-ir_node *(be_ifg_nodes_next)(const be_ifg_t *self, void *iter);
-void (be_ifg_nodes_break)(const be_ifg_t *self, void *iter);
-int (be_ifg_cliques_begin)(const be_ifg_t *self, void *iter, ir_node **buf);
-int (be_ifg_cliques_next)(const be_ifg_t *self, void *iter);
-void (be_ifg_cliques_break)(const be_ifg_t *self, void *iter);
-int (be_ifg_degree)(const be_ifg_t *self, const ir_node *irn);
-
-#define be_ifg_foreach_neighbour(self, iter, irn, pos) \
- for(pos = be_ifg_neighbours_begin(self, iter, irn); (pos); pos = be_ifg_neighbours_next(self, iter))
-
-#define be_ifg_foreach_node(self, iter, pos) \
- for(pos = be_ifg_nodes_begin(self, iter); (pos); pos = be_ifg_nodes_next(self, iter))
-
-#define be_ifg_foreach_clique(self, iter, buf, count) \
- for(*(count) = be_ifg_cliques_begin(self, iter, buf); \
+typedef struct be_ifg_t {
+ const be_chordal_env_t *env;
+} be_ifg_t;
+
+typedef struct nodes_iter_t {
+ const be_chordal_env_t *env;
+ struct obstack obst;
+ int n;
+ int curr;
+ ir_node **nodes;
+} nodes_iter_t;
+
+typedef struct neighbours_iter_t {
+ const be_chordal_env_t *env;
+ const ir_node *irn;
+ int valid;
+ ir_nodeset_t neighbours;
+ ir_nodeset_iterator_t iter;
+} neighbours_iter_t;
+
+typedef struct cliques_iter_t {
+ struct obstack ob;
+ const be_chordal_env_t *cenv;
+ ir_node **buf;
+ ir_node **blocks;
+ int n_blocks, blk;
+ struct list_head *bor;
+ pset *living;
+} cliques_iter_t;
+
+void be_ifg_free(be_ifg_t *ifg);
+int be_ifg_connected(const be_ifg_t *ifg, const ir_node *a,
+ const ir_node *b);
+ir_node *be_ifg_neighbours_begin(const be_ifg_t *ifg, neighbours_iter_t *iter,
+ const ir_node *irn);
+ir_node *be_ifg_neighbours_next(neighbours_iter_t *iter);
+void be_ifg_neighbours_break(neighbours_iter_t *iter);
+ir_node *be_ifg_nodes_begin(const be_ifg_t *ifg, nodes_iter_t *iter);
+ir_node *be_ifg_nodes_next(nodes_iter_t *iter);
+void be_ifg_nodes_break(nodes_iter_t *iter);
+int be_ifg_cliques_begin(const be_ifg_t *ifg, cliques_iter_t *iter,
+ ir_node **buf);
+int be_ifg_cliques_next(cliques_iter_t *iter);
+void be_ifg_cliques_break(cliques_iter_t *iter);
+int be_ifg_degree(const be_ifg_t *ifg, const ir_node *irn);
+
+#define be_ifg_foreach_neighbour(ifg, iter, irn, pos) \
+ for(pos = be_ifg_neighbours_begin(ifg, iter, irn); pos != NULL; pos = be_ifg_neighbours_next(iter))
+
+#define be_ifg_foreach_node(ifg, iter, pos) \
+ for(pos = be_ifg_nodes_begin(ifg, iter); pos != NULL; pos = be_ifg_nodes_next(iter))
+
+#define be_ifg_foreach_clique(ifg, iter, buf, count) \
+ for(*(count) = be_ifg_cliques_begin(ifg, iter, buf); \
*(count) != -1 ; \
- *(count) = be_ifg_cliques_next(self, iter))
+ *(count) = be_ifg_cliques_next(iter))
typedef struct {
int n_nodes;
} be_ifg_dump_dot_cb_t;
void be_ifg_dump_dot(be_ifg_t *ifg, ir_graph *irg, FILE *file, const be_ifg_dump_dot_cb_t *cb, void *self);
-void be_ifg_check_sorted(const be_ifg_t *ifg);
-void be_ifg_check_sorted_to_file(const be_ifg_t *ifg, FILE *f);
-void be_ifg_check_performance(be_chordal_env_t *chordal_env);
-
-#endif /* FIRM_BE_BEIFG_H */
+#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief Clique calculation for chordal ifg.
- * @author Sebastian Hack
- * @date 18.11.2005
- * @version $Id$
- */
-#include "config.h"
-
-#include <stdlib.h>
-
-#include "belive_t.h"
-#include "list.h"
-
-#include "irnode_t.h"
-#include "irgraph_t.h"
-#include "irgwalk.h"
-#include "irbitset.h"
-
-#include "bearch.h"
-#include "be_t.h"
-#include "beintlive_t.h"
-#include "beifg_t.h"
-#include "beifg_impl.h"
-#include "bechordal_t.h"
-
-typedef struct _cli_head_t {
- struct list_head list;
- struct _cli_head_t *next_cli_head;
- ir_node *min;
- ir_node *max;
-} cli_head_t;
-
-typedef struct _ifg_clique_t {
- const be_ifg_impl_t *impl;
- const be_chordal_env_t *env;
- cli_head_t *cli_root;
- struct obstack obst;
- cli_head_t *curr_cli_head;
-} ifg_clique_t;
-
-typedef struct _cli_element_t {
- struct list_head list;
- ir_node *irn;
-} cli_element_t;
-
-typedef struct _cli_iter_t {
- const ifg_clique_t *ifg;
- cli_head_t *curr_cli_head;
- cli_element_t *curr_cli_element;
- const ir_node *curr_irn;
- bitset_t *visited_neighbours;
- bitset_t *visited_nodes;
-} cli_iter_t;
-
-/* PRIVATE FUNCTIONS */
-static cli_head_t *get_new_cli_head(ifg_clique_t *ifg)
-{
- cli_head_t *cli_head;
- cli_head_t *new_cli_head;
-
- if (ifg->cli_root == NULL)
- {
- new_cli_head = OALLOC(&ifg->obst, cli_head_t);
- INIT_LIST_HEAD(&new_cli_head->list);
- ifg->cli_root = new_cli_head;
- }
- else
- {
- cli_head = ifg->cli_root;
- while (!(cli_head->next_cli_head == NULL))
- {
- cli_head = cli_head->next_cli_head;
- }
- new_cli_head = OALLOC(&ifg->obst, cli_head_t);
- INIT_LIST_HEAD(&new_cli_head->list);
- cli_head->next_cli_head = new_cli_head;
- }
-
- new_cli_head->min = NULL;
- new_cli_head->max = NULL;
- new_cli_head->next_cli_head = NULL;
- ifg->curr_cli_head = new_cli_head;
-
- return new_cli_head;
-}
-
-static cli_element_t *get_new_cli_element(ifg_clique_t *ifg)
-{
- cli_element_t *cli_element;
-
- cli_element = OALLOC(&ifg->obst, cli_element_t);
- INIT_LIST_HEAD(&cli_element->list);
-
- return cli_element;
-}
-
-static void write_clique(ir_nodeset_t *live_set, ifg_clique_t *ifg)
-{
- ir_node *live_irn;
- ir_node *test_node;
- int test_int = 0;
- ir_node *max_node = NULL;
- ir_node *min_node = NULL;
- cli_element_t *new_element = NULL;
- cli_element_t *element = NULL;
- cli_head_t *cli_head = get_new_cli_head(ifg);
- int is_element = 0;
- ir_nodeset_iterator_t iter;
-
- foreach_ir_nodeset(live_set, live_irn, iter)
- {
- /* test if node is max or min dominator*/
- test_node = live_irn;
- if (max_node == NULL)
- {
- max_node = test_node;
- min_node = test_node;
- }
- else
- {
- test_int = value_dominates(test_node, max_node);
- if (test_int == 1)
- {
- max_node = test_node;
- }
- test_int = value_dominates(min_node, test_node);
- if (test_int == 1)
- {
- min_node = test_node;
- }
- }
-
- list_for_each_entry(cli_element_t, element, &cli_head->list, list){
- if (element->irn == live_irn){
- is_element = 1;
- break;
- }
- }
-
- if (!is_element){
- new_element = get_new_cli_element(ifg);
- new_element->irn = live_irn;
- list_add(&new_element->list, &cli_head->list) ;
- }
- }
-
- cli_head->min = min_node;
- cli_head->max = max_node;
-}
-
-static cli_head_t *get_next_cli_head(const ir_node *irn, cli_iter_t *it) /* ...containing the node *irn */
-{
- cli_head_t *head;
- cli_element_t *element;
-
- int is_dominated_by_max;
-
- if (it->curr_cli_head == NULL || it->curr_cli_head->next_cli_head == NULL) /* way back of recursion or this is the last clique */
- {
- it->curr_cli_head = NULL;
- return NULL;
- }
-
- head = it->curr_cli_head->next_cli_head;
-
- is_dominated_by_max = value_dominates(head->max, irn);
-
- if ((is_dominated_by_max) || (irn == head->max)) /* node could be in clique */
- {
- /* check if node is in clique */
- list_for_each_entry(cli_element_t, element, &head->list, list)
- {
- if (&element->list != &head->list)
- {
- if (element->irn == irn)
- {
- /* node is in clique */
- it->curr_cli_head = head;
- /* needed because the next element is searched with list.next of it->curr_cli_element */
- it->curr_cli_element = (void *) head;
- break;
- }
- }
- }
-
- if (it->curr_cli_head != head) /*node was not in clique */
- {
- it->curr_cli_head = head;
- head = get_next_cli_head(irn, it);
- }
- }
- else
- {
- it->curr_cli_head = head;
- head = get_next_cli_head(irn, it);
- }
- return head;
-}
-
-/* ... of the current clique, returns NULL if there were no more elements ..*/
-static cli_element_t *get_next_element(const ir_node *irn, cli_iter_t *it)
-{
- cli_element_t *element = it->curr_cli_element;
- cli_head_t *head = it->curr_cli_head;
-
- if (!head || it->curr_cli_element == NULL) /* way back of recursion or there are no more heads */
- {
- it->curr_cli_element = NULL;
- return NULL;
- }
- else
- {
- element = list_entry(element->list.next, cli_element_t, list);
-
- if (&element->list == &head->list) /* Clique has no more elements */
- {
- head = get_next_cli_head(irn, it);
- element = get_next_element(irn, it);
- }
-
- if (element && element->irn == irn) /* the node you are searching neighbors for */
- {
- it->curr_cli_element = element;
- element = get_next_element(irn, it);
- }
-
- it->curr_cli_element = element;
-
- return element;
- }
-}
-
-static void find_nodes(const ifg_clique_t *ifg, cli_iter_t *it)
-{
- cli_element_t *element;
- cli_head_t *cli_head = ifg->cli_root;
-
- bitset_t *bitset_visnodes = bitset_malloc(get_irg_last_idx(ifg->env->irg));
-
- it->visited_nodes = bitset_visnodes;
- it->curr_cli_head = cli_head;
-
- assert(cli_head && "There is no root entry to work on!");
-
- if (cli_head->list.next != &cli_head->list) /* if cli_head contains an element */
- {
- element = list_entry(cli_head->list.next, cli_element_t, list);
- it->curr_cli_element = element;
- }
-}
-
-static ir_node *get_next_node(cli_iter_t *it)
-{
- cli_head_t *cli_head = NULL;
- cli_element_t *element = it->curr_cli_element;
-
- ir_node *irn;
-
- if (element == NULL)
- return NULL;
-
- if (!(&it->curr_cli_head->list == element->list.next))
- {
- irn = element->irn;
- element = list_entry(element->list.next, cli_element_t, list);
- it->curr_cli_element = element;
- }
- else /* reached end of clique */
- {
- cli_head = it->curr_cli_head;
- if (!(cli_head->next_cli_head == NULL))
- {
- irn = element->irn;
- cli_head = cli_head->next_cli_head;
- it->curr_cli_head = cli_head;
- element = list_entry(cli_head->list.next, cli_element_t, list);
- it->curr_cli_element = element;
- }
- else
- {
- it->curr_cli_head = NULL;
- it->curr_cli_element = NULL;
- irn = element->irn;
- }
- }
- if (!(irn == NULL))
- {
- if (bitset_is_set(it->visited_nodes, get_irn_idx(irn)))
- {
- irn = get_next_node(it);
- }
- if (!(irn == NULL))
- {
- bitset_set(it->visited_nodes, get_irn_idx(irn));
- }
- }
-
- return irn;
-}
-
-static void find_neighbour_walker(ir_node *bl, void *data)
-{
- ifg_clique_t *ifg = data;
- struct list_head *head = get_block_border_head(ifg->env, bl);
- int was_def = 0;
- ir_nodeset_t live;
- border_t *b;
-
- ir_nodeset_init(&live);
-
- assert(is_Block(bl) && "There is no block to work on.");
-
- foreach_border_head(head, b) /* follow the borders of the block */
- {
- ir_node *irn = b->irn;
-
- if (b->is_def) /* b is a new node */
- {
- ir_nodeset_insert(&live, irn);
- if (b->is_real)
- {
- was_def = 1;
- }
- }
- else
- {
- if (was_def == 1) /* if there is a USE after a DEF... */
- {
- write_clique(&live, ifg); /* ...add the clique. */
- was_def = 0;
- }
- ir_nodeset_remove(&live, irn);
- }
- }
- ir_nodeset_destroy(&live);
-}
-
-static void find_first_neighbour(const ifg_clique_t *ifg, cli_iter_t *it, const ir_node *irn)
-{
- cli_head_t *cli_head = ifg->cli_root;
- cli_element_t *element;
- bitset_t *bitset_visneighbours = bitset_malloc(get_irg_last_idx(ifg->env->irg));
-
- int is_dominated_by_max = 0;
- int is_in_clique = 0;
-
- it->curr_cli_head = cli_head;
- it->ifg = ifg;
- it->visited_neighbours = bitset_visneighbours;
-
- assert(cli_head && "There is no root entry for a cli_head.");
-
- is_dominated_by_max = value_dominates(cli_head->max, irn);
-
- if ((is_dominated_by_max) || (irn == cli_head->max)) /* node could be in clique */
- {
- /* check if node is in clique */
- list_for_each_entry(cli_element_t, element, &cli_head->list, list)
- {
- if (element->irn == irn) /* node is in clique */
- {
- it->curr_cli_element = (void *) cli_head; /* needed because the next element is searched with list.next of it->curr_cli_element */
- is_in_clique = 1;
- element = get_next_element(irn, it);
- break;
- }
- }
- }
- if (!is_in_clique)
- {
- cli_head = get_next_cli_head(irn, it);
- element = get_next_element(irn, it);
- }
-
- it->curr_cli_element = element;
- it->curr_irn = irn;
-}
-
-static ir_node *get_next_neighbour(cli_iter_t *it)
-{
- ir_node *res = NULL;
- const ir_node *irn = it->curr_irn;
-
- if (it->curr_cli_element != NULL)
- res = it->curr_cli_element->irn;
- else
- return NULL;
-
- it->curr_cli_element = get_next_element(irn, it);
-
- if (res)
- {
- if (bitset_contains_irn(it->visited_neighbours, res))
- {
- res = get_next_neighbour(it);
- }
- else
- {
- bitset_set(it->visited_neighbours, get_irn_idx(res));
- }
- }
-
- return res;
-}
-
-
-/* PUBLIC FUNCTIONS */
-
-static void ifg_clique_free(void *self)
-{
- ifg_clique_t *ifg = self;
- obstack_free(&ifg->obst, NULL);
-
- free(self);
-}
-
-static int ifg_clique_connected(const void *self, const ir_node *a, const ir_node *b)
-{
- const ifg_clique_t *ifg = self;
- cli_iter_t it;
- int connected = -1;
- ir_node *irn = NULL;
-
- find_first_neighbour(ifg, &it, a);
- connected = 0;
- irn = get_next_neighbour(&it);
- while (irn != NULL)
- {
- if (irn == b)
- {
- connected = 1;
- break;
- }
- irn = get_next_neighbour(&it);
- }
-
- return connected;
-}
-
-static ir_node *ifg_clique_neighbours_begin(const void *self, void *iter, const ir_node *irn)
-{
- find_first_neighbour(self, iter, irn);
- return get_next_neighbour(iter);
-}
-
-static ir_node *ifg_clique_neighbours_next(const void *self, void *iter)
-{
- (void) self;
- return get_next_neighbour(iter);
-}
-
-static void ifg_clique_neighbours_break(const void *self, void *iter)
-{
- cli_iter_t *it = iter;
- (void) self;
-
- bitset_free(it->visited_neighbours);
-}
-
-static ir_node *ifg_clique_nodes_begin(const void *self, void *iter)
-{
- find_nodes(self, iter);
- return get_next_node(iter);
-}
-
-static ir_node *ifg_clique_nodes_next(const void *self, void *iter)
-{
- (void) self;
- return get_next_node(iter);
-}
-
-static void ifg_clique_nodes_break(const void *self, void *iter)
-{
- cli_iter_t *it = iter;
- (void) self;
-
- bitset_free(it->visited_nodes);
-}
-
-static int ifg_clique_degree(const void *self, const ir_node *irn)
-{
- int degree = -1;
- cli_iter_t it;
-
- find_first_neighbour(self, &it, irn);
- degree = 0;
- irn = get_next_neighbour(&it);
- while (irn != NULL)
- {
- degree++;
- irn = get_next_neighbour(&it);
- }
-
- return degree;
-}
-
-static const be_ifg_impl_t ifg_clique_impl = {
- sizeof(cli_iter_t),
- sizeof(cli_iter_t),
- 0,
- ifg_clique_free,
- ifg_clique_connected,
- ifg_clique_neighbours_begin,
- ifg_clique_neighbours_next,
- ifg_clique_neighbours_break,
- ifg_clique_nodes_begin,
- ifg_clique_nodes_next,
- ifg_clique_nodes_break,
- NULL,
- NULL,
- NULL,
- ifg_clique_degree
-};
-
-be_ifg_t *be_ifg_clique_new(const be_chordal_env_t *env)
-{
- ifg_clique_t *ifg = XMALLOC(ifg_clique_t);
-
- ifg->impl = &ifg_clique_impl;
- ifg->env = env;
-
- ifg->cli_root = NULL;
- obstack_init(&ifg->obst);
-
- dom_tree_walk_irg(env->irg, find_neighbour_walker, NULL, ifg);
-
- obstack_finish(&ifg->obst);
- return (be_ifg_t *) ifg;
-}
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief Constructors for different implementations of chordal interference graphs.
- * @author Sebastian Hack
- * @date 01.12.2005
- * @version $Id$
- */
-#ifndef FIRM_BE_BEIFG_IMPL_H
-#define FIRM_BE_BEIFG_IMPL_H
-
-#include "beifg.h"
-#include "bechordal.h"
-
-be_ifg_t *be_ifg_std_new(const be_chordal_env_t *env);
-be_ifg_t *be_ifg_list_new(const be_chordal_env_t *env);
-be_ifg_t *be_ifg_clique_new(const be_chordal_env_t *env);
-be_ifg_t *be_ifg_pointer_new(const be_chordal_env_t *env);
-
-#endif /* FIRM_BE_BEIFG_IMPL_H */
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief List based implementation of chordal interference graphs.
- * @author Sebastian Hack
- * @date 18.11.2005
- * @version $Id$
- */
-#include "config.h"
-
-#include <stdlib.h>
-
-#include "list.h"
-
-#include "irnode_t.h"
-#include "irgraph_t.h"
-#include "irgwalk.h"
-
-#include "beifg_impl.h"
-#include "bearch.h"
-#include "be_t.h"
-#include "bera.h"
-#include "beifg_t.h"
-#include "bechordal_t.h"
-
-typedef struct _adj_head_t adj_head_t;
-
-typedef struct _ifg_list_t {
- const be_ifg_impl_t *impl;
- const be_chordal_env_t *env;
- struct obstack obst;
- adj_head_t **adj_heads;
-} ifg_list_t;
-
-typedef struct _adj_element_t adj_element_t;
-
-struct _adj_element_t {
- adj_element_t *next_adj_element;
- ir_node *neighbour;
-};
-
-struct _adj_head_t {
- ir_node *irn; /* the node you search neighbours for */
- adj_element_t *first_adj_element;
- int degree;
-};
-
-typedef struct _nodes_iter_t {
- const ifg_list_t *ifg;
- unsigned int curr_node_idx;
-} nodes_iter_t;
-
-typedef struct _adj_iter_t {
- const ifg_list_t *ifg;
- adj_element_t *curr_adj_element;
-} adj_iter_t;
-
-/* PRIVATE FUNCTIONS */
-
-/* add node to the array of all nodes in this ifg implementation, if the node isn't already in the ifg */
-static void create_node(ifg_list_t *ifg, ir_node *irn)
-{
- adj_head_t *adj_head = NULL;
-
- adj_head = ifg->adj_heads[irn->node_idx];
- if (!adj_head)
- {
- adj_head = OALLOC(&ifg->obst, adj_head_t);
- adj_head->irn = irn;
- adj_head->first_adj_element = NULL;
- adj_head->degree = 0;
- ifg->adj_heads[irn->node_idx] = adj_head;
- }
-}
-
-static adj_element_t *create_adj_element(ifg_list_t *ifg, ir_node *irn)
-{
- adj_element_t *element = NULL;
-
- element = OALLOC(&ifg->obst, adj_element_t);
- element->next_adj_element = NULL;
- element->neighbour = irn;
-
- return element;
-}
-
-/* write the information about the edge between a and b */
-static void add_edge(ifg_list_t *ifg, ir_node *node_a, ir_node *node_b)
-{
- adj_head_t *adj_head = NULL;
- adj_element_t *curr_element = NULL;
- adj_element_t *new_element = NULL;
-
- adj_head = ifg->adj_heads[node_a->node_idx]; /* find the neighbours list of a */
-
- assert (adj_head && "There is no entry for node a");
- curr_element = adj_head->first_adj_element;
-
- if (curr_element)
- {
- while (curr_element->neighbour != node_b && curr_element->next_adj_element)
- {
- curr_element = curr_element->next_adj_element;
- }
-
- if (curr_element->neighbour != node_b && curr_element->next_adj_element == NULL)
- {
- adj_head->degree++;
- new_element = create_adj_element(ifg, node_b); /* if b isn't in list, add b */
- curr_element->next_adj_element = new_element;
- }
- }
- else
- {
- adj_head->degree++;
- new_element = create_adj_element(ifg, node_b); /* a has no neighbours, add b as the first one*/
- adj_head->first_adj_element = new_element;
- }
-
- /* do the same vice versa */
- adj_head = ifg->adj_heads[node_b->node_idx];
-
- assert (adj_head && "There is no entry for node a");
- curr_element = adj_head->first_adj_element;
-
- if (curr_element)
- {
- while (curr_element->neighbour != node_a && curr_element->next_adj_element)
- {
- curr_element = curr_element->next_adj_element;
- }
-
- if (curr_element->neighbour != node_a && curr_element->next_adj_element == NULL)
- {
- adj_head->degree++;
- new_element = create_adj_element(ifg, node_a);
- curr_element->next_adj_element = new_element;
- }
- }
- else
- {
- adj_head->degree++;
- new_element = create_adj_element(ifg, node_a);
- adj_head->first_adj_element = new_element;
- }
-}
-
-/* find all adjacent nodes in the irg */
-static void find_neighbour_walker(ir_node *bl, void *data)
-{
- ifg_list_t *ifg = data;
- struct list_head *head = get_block_border_head(ifg->env, bl);
- ir_nodeset_t live;
- ir_node *live_irn = NULL;
- border_t *b = NULL;
-
- ir_nodeset_init(&live);
-
- assert(is_Block(bl) && "There is no block to work on");
-
- foreach_border_head(head, b) /* follow the borders of each block */
- {
- if (b->is_def)
- {
- create_node(ifg, b->irn); /* add the node to the array of all nodes of this ifg implementation */
- ir_nodeset_insert(&live, b->irn);
- if (b->is_real) /* this is a new node */
- {
- ir_nodeset_iterator_t iter;
-
- foreach_ir_nodeset(&live, live_irn, iter)
- {
- if (b->irn != live_irn) /* add a as a neighbour to b and vice versa */
- add_edge(ifg, b->irn, live_irn);
- }
- }
- }
- else /* b->irn is now dead */
- {
- ir_nodeset_remove(&live, b->irn);
- }
- }
-
- ir_nodeset_destroy(&live);
-}
-
-static ir_node *get_first_node(const ifg_list_t *ifg, nodes_iter_t *it)
-{
- ir_node *res = NULL;
- adj_head_t *adj_head = NULL;
- int curr_idx = -1;
-
- it->ifg = ifg;
- it->curr_node_idx = 0;
-
- while (adj_head == NULL)
- {
- curr_idx++;
- adj_head = ifg->adj_heads[curr_idx];
- }
-
- if (adj_head == NULL) /* there are no nodes in this ifg */
- return NULL;
- else
- {
- res = adj_head->irn;
- it->curr_node_idx = curr_idx;
- }
-
- return res;
-}
-
-static ir_node *get_next_node(nodes_iter_t *it)
-{
- const ifg_list_t *ifg = it->ifg;
- ir_node *res = NULL;
- adj_head_t *adj_head = NULL;
- unsigned int curr_idx = it->curr_node_idx;
-
- while (adj_head == NULL && curr_idx < it->ifg->env->irg->last_node_idx - 1)
- {
- curr_idx++;
- adj_head = ifg->adj_heads[curr_idx];
- }
-
- if (adj_head == NULL) /* there are no more nodes in this ifg */
- return NULL;
- else
- {
- res = adj_head->irn;
- it->curr_node_idx = curr_idx;
- }
-
- return res;
-}
-
-static ir_node *get_first_neighbour(const ifg_list_t *ifg, adj_iter_t *it, const ir_node *curr_irn)
-{
- ir_node *res = NULL;
- adj_head_t *adj_head = NULL;
-
- adj_head = ifg->adj_heads[curr_irn->node_idx];
- assert(adj_head && "There is no entry for this node");
-
- it->curr_adj_element = NULL;
- it->ifg = ifg;
-
- if (adj_head->first_adj_element) /* return first neighbour */
- {
- res = adj_head->first_adj_element->neighbour;
- it->curr_adj_element = adj_head->first_adj_element;
- }
- else /* node has no neighbours */
- return NULL;
-
- return res;
-}
-
-static ir_node *get_next_neighbour(adj_iter_t *it)
-{
- ir_node *res = NULL;
- adj_element_t *element = it->curr_adj_element;
-
- if (element->next_adj_element) /* return next neighbour */
- {
- res = element->next_adj_element->neighbour;
- it->curr_adj_element = element->next_adj_element;
- }
- else /* was last neighbour */
- return NULL;
-
- return res;
-}
-
-/* PUBLIC FUNCTIONS */
-
-static void ifg_list_free(void *self)
-{
- ifg_list_t *ifg = self;
- obstack_free(&ifg->obst, NULL);
- free(ifg->adj_heads);
- free(ifg);
-}
-
-static int ifg_list_connected(const void *self, const ir_node *a, const ir_node *b)
-{
- const ifg_list_t *ifg = self;
- int res = -1;
- adj_head_t *adj_head = NULL;
- adj_element_t *curr_element = NULL;
-
- /* first try: find b in the neigbours of a */
- adj_head = ifg->adj_heads[a->node_idx];
-
- assert(adj_head && "There is no entry for the node a");
- curr_element = adj_head->first_adj_element;
-
- if (curr_element)
- {
- while (curr_element->neighbour != b && curr_element->next_adj_element)
- {
- curr_element = curr_element->next_adj_element;
- }
- if (curr_element->neighbour == b)
- return 1;
- else
- res = 0;
- }
- else /* node a has no neighbours */
- res = 0;
-
- /* second try, this should not be necessary... only to check the solution */
- adj_head = ifg->adj_heads[b->node_idx];
-
- assert(adj_head && "There is no entry for the node b");
- curr_element = adj_head->first_adj_element;
-
- if (curr_element)
- {
- while (curr_element->neighbour != a && curr_element->next_adj_element)
- {
- curr_element = curr_element->next_adj_element;
- }
- if (curr_element->neighbour == a)
- {
- assert ("Found the neighbour only in the second try.");
- return 1;
- }
- else
- res = 0;
- }
- else /* node b has no neighbours */
- res = 0;
-
- return res;
-}
-
-static ir_node *ifg_list_nodes_begin(const void *self, void *iter)
-{
- nodes_iter_t *it = iter;
- return get_first_node(self, it);
-}
-
-static ir_node *ifg_list_nodes_next(const void *self, void *iter)
-{
- (void) self;
- return get_next_node(iter);
-}
-
-static void ifg_list_nodes_break(const void *self, void *iter)
-{
- nodes_iter_t *it = iter;
- (void) self;
- it->curr_node_idx = 0;
- it->ifg = NULL;
-}
-
-static ir_node *ifg_list_neighbours_begin(const void *self, void *iter,const ir_node *irn)
-{
- adj_iter_t *it = iter;
- return get_first_neighbour(self, it, irn);
-}
-
-static ir_node *ifg_list_neighbours_next(const void *self, void *iter)
-{
- (void) self;
- return get_next_neighbour(iter);
-}
-
-static void ifg_list_neighbours_break(const void *self, void *iter)
-{
- adj_iter_t *it= iter;
- (void) self;
- it->curr_adj_element = NULL;
- it->ifg = NULL;
-}
-
-static int ifg_list_degree(const void *self, const ir_node *irn)
-{
- const ifg_list_t *ifg = self;
- adj_head_t *adj_head = NULL;
-
- adj_head = ifg->adj_heads[irn->node_idx];
-
- assert (adj_head && "There is no entry for this node");
-
- return adj_head->degree;
-}
-
-static const be_ifg_impl_t ifg_list_impl = {
- sizeof(nodes_iter_t),
- sizeof(adj_iter_t),
- 0,
- ifg_list_free,
- ifg_list_connected,
- ifg_list_neighbours_begin,
- ifg_list_neighbours_next,
- ifg_list_neighbours_break,
- ifg_list_nodes_begin,
- ifg_list_nodes_next,
- ifg_list_nodes_break,
- NULL,
- NULL,
- NULL,
- ifg_list_degree
-};
-
-be_ifg_t *be_ifg_list_new(const be_chordal_env_t *env)
-{
- ifg_list_t *ifg = XMALLOC(ifg_list_t);
- adj_head_t **adj_heads_array = XMALLOCNZ(adj_head_t*, env->irg->last_node_idx);
-
- ifg->impl = &ifg_list_impl;
- ifg->env = env;
-
- ifg->adj_heads = adj_heads_array;
-
- obstack_init(&ifg->obst);
- dom_tree_walk_irg(env->irg, find_neighbour_walker, NULL, ifg);
- obstack_finish(&ifg->obst);
-
- return (be_ifg_t *) ifg;
-}
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief Pointer based implementation of chordal interference graphs.
- * @author Sebastian Hack
- * @date 18.11.2005
- * @version $Id$
- */
-#include "config.h"
-
-#include <stdlib.h>
-
-#include "belive_t.h"
-#include "list.h"
-#include "irphase_t.h"
-
-#include "irnode_t.h"
-#include "irgraph_t.h"
-#include "irgwalk.h"
-#include "irbitset.h"
-
-#include "be_t.h"
-#include "bera.h"
-#include "beifg_t.h"
-#include "beifg_impl.h"
-#include "bechordal_t.h"
-
-typedef struct _ptr_element_t ptr_element_t;
-
-typedef union element_content {
- ir_node *irn;
- ptr_element_t *element;
-} element_content;
-
-struct _ptr_element_t {
- int kind; /* kind = 8888 ..> both are ir_nodes, = 3101 ..> first is another element, second an ir_node */
- element_content content_first; /* could be a ptr_element or ir_node */
- element_content content_second; /* could be a ptr_element or ir_node */
-};
-
-typedef struct _ptr_head_t {
- struct list_head list;
- ptr_element_t *element;
-} ptr_head_t;
-
-typedef struct _ifg_pointer_t {
- const be_ifg_impl_t *impl;
- const be_chordal_env_t *env;
- ir_phase ph;
- struct obstack obst;
- ptr_head_t *curr_ptr_head;
- ptr_element_t *curr_element;
-} ifg_pointer_t;
-
-typedef struct _ptr_iter_t {
- const ifg_pointer_t *ifg;
- const ir_node *irn;
- ptr_head_t *curr_ptr_head;
- ptr_head_t *first_head;
- ptr_element_t *curr_element_t;
- ir_node *curr_irn;
- int get_first;
- int sub_call;
- bitset_t *visited_neighbours;
-} ptr_iter_t;
-
-/* PRIVATE FUNCTIONS */
-
-static void *ptr_irn_data_init(ir_phase *ph, const ir_node *irn, void *data)
-{
- ptr_head_t *head = phase_alloc(ph, sizeof(*head));
- (void) irn;
- (void) data;
- INIT_LIST_HEAD(&head->list);
- return head;
-}
-
-static ptr_element_t *ptr_get_new_element(ifg_pointer_t *ifg)
-{
- ptr_element_t *new_element = OALLOCZ(&ifg->obst, ptr_element_t);
- return new_element;
-}
-
-static ptr_head_t *ptr_get_new_head(ifg_pointer_t *ifg)
-{
- ptr_head_t *new_element = OALLOC(&ifg->obst, ptr_head_t);
- INIT_LIST_HEAD(&new_element->list);
- return new_element;
-}
-
-static void write_pointers(bitset_t *live, ifg_pointer_t *ifg)
-{
- ir_node *live_irn;
- unsigned elm;
-
- bitset_foreach_irn(ifg->env->irg, live, elm, live_irn) {
- ptr_head_t *head = phase_get_or_set_irn_data(&ifg->ph, live_irn);
- ptr_head_t *element = ptr_get_new_head(ifg);
-
- element->element = ifg->curr_element; /* write current highest sub-clique for each node */
- list_add(&element->list, &head->list);
- }
-}
-
-static ptr_element_t *get_last_sub_clique(ifg_pointer_t *ifg, bitset_t *live, bitset_t *my_live, ir_node *irn)
-{
- ptr_element_t *element = ifg->curr_element;
- ptr_element_t *res = NULL;
-
- /* search the last sub-clique before the sub-clique that contains the node irn */
- if (element && element->kind == 8888
- && (element->content_first.irn == irn
- || element->content_second.irn == irn)) /* contains the node we search and there is no other sub-clique before */
- {
- if (bitset_is_set(live, get_irn_idx(element->content_first.irn)) && element->content_first.irn != irn) /* irn is still alive and not the node we search a sub-clique for */
- {
- bitset_set(my_live, get_irn_idx(element->content_first.irn));
- }
-
- if (bitset_is_set(live, get_irn_idx(element->content_second.irn))&& element->content_second.irn != irn) /* irn is still alive and not the node we search a sub-clique for */
- {
- bitset_set(my_live, get_irn_idx(element->content_second.irn));
- }
- res = NULL;
- }
- else
- {
- if (element && element->kind == 8889)
- { /* this was a "single-node-clique" */
- res = NULL;
- }
-
- if (element && (element->kind == 3101)
- && (element->content_second.irn == irn)) /* sub-clique contains node, return previous sub-clique */
- {
- res = element->content_first.element;
- }
- else
- {
- if (element && element->kind == 3101) /* look at previous sub-cliques if the contain the node you are searching for*/
- {
- if (bitset_is_set(live, get_irn_idx(element->content_second.irn))) /* irn is still alive */
- {
- bitset_set(my_live, get_irn_idx(element->content_second.irn));
- }
- ifg->curr_element = element->content_first.element;
- res = get_last_sub_clique(ifg, live, my_live, irn);
- }
- else
- {
- res = NULL;
- }
- }
- }
- return res;
-}
-
-static void find_neighbour_walker(ir_node *bl, void *data)
-{
- ifg_pointer_t *ifg = data;
- struct list_head *head = get_block_border_head(ifg->env, bl);
- int was_def = 0;
- int was_first = 0;
- ir_node *first = NULL;
- bitset_t *live = bitset_malloc(get_irg_last_idx(ifg->env->irg));
- bitset_t *my_live;
- unsigned my_elm;
- border_t *b;
- ir_node *my_irn;
- element_content last_irn;
- element_content last_element;
-
- last_irn.irn = NULL;
- last_element.element = NULL;
-
- assert(is_Block(bl) && "There is no block to work on.");
-
- foreach_border_head(head, b) /* follow the borders of the block */
- {
- ir_node *irn = b->irn;
- ptr_element_t *element = NULL;
-
- if (b->is_def) /* b is a new node */
- {
- bitset_set(live, get_irn_idx(irn));
- if (last_element.element)
- {
- element = ptr_get_new_element(ifg);
- element->content_first.element = last_element.element;
- element->content_second.irn = b->irn;
- element->kind = 3101; /* first is an element, second an ir_node */
-
- last_element.element = element;
- ifg->curr_element = element;
- }
- else
- {
- if (last_irn.irn) /* create new sub-clique */
- {
- element = ptr_get_new_element(ifg);
- element->content_first.irn = last_irn.irn;
- element->content_second.irn = b->irn;
- element->kind = 8888; /* both are ir_nodes */
-
- last_element.element = element;
- ifg->curr_element = element;
- last_irn.irn = NULL;
- }
- else
- {
- last_irn.irn = b->irn; /* needed to create first sub-clique */
- last_element.element = NULL;
- }
- }
-
- was_def = 1;
- }
- else
- {
- if (was_def == 1) /* if there is a USE after a DEF... */
- {
- if (!last_element.element)
- { /* there was only one element in the clique */
- element = ptr_get_new_element(ifg);
- element->kind = 8889; /* first is a node, second is NULL, because this is a "single-node-clique" */
- element->content_first.irn = last_irn.irn;
- last_irn.irn = NULL;
- element = NULL;
- ifg->curr_element = NULL;
- }
-
-
- write_pointers(live, ifg); /* ...write a pointer to the highest sub-clique for each living node. */
- was_def = 0;
- }
-
- my_live = bitset_malloc(get_irg_last_idx(ifg->env->irg));
- last_element.element = get_last_sub_clique(ifg, live, my_live, irn);
-
- /* check and add still living nodes */
- if (bitset_popcount(my_live) > 1)
- {
- if (last_element.element)
- {
- bitset_foreach_irn(ifg->env->irg, my_live, my_elm, my_irn)
- {
- ptr_element_t *my_element = ptr_get_new_element(ifg);
- my_element->content_first.element = last_element.element;
- my_element->content_second.irn = my_irn;
- my_element->kind = 3101; /* first is an element, second an ir_node */
-
- last_element.element = my_element;
- ifg->curr_element = my_element;
- }
- }
- else
- {
- bitset_foreach_irn(ifg->env->irg, my_live, my_elm, my_irn)
- {
- ptr_element_t *my_element = NULL;
- if (!first && !was_first)
- {
- first = my_irn;
- was_first = 1;
- }
- else
- {
- if (first && was_first)
- {
- my_element = ptr_get_new_element(ifg);
- my_element->content_first.irn = first;
- my_element->content_second.irn = my_irn;
- my_element->kind = 8888; /* both are ir_nodes */
- last_element.element = my_element;
- ifg->curr_element = my_element;
- first = NULL;
- }
- else
- {
- my_element = ptr_get_new_element(ifg);
- my_element->content_first.element = last_element.element;
- my_element->content_second.irn = my_irn;
- my_element->kind = 3101; /* first is an element, second an ir_node */
- last_element.element = my_element;
- ifg->curr_element = my_element;
- }
- }
- }
- was_first = 0;
- }
- }
- else
- {
- if (bitset_popcount(my_live) == 1) /* there is only one node left */
- {
- if (last_element.element)
- {
- bitset_foreach_irn(ifg->env->irg, my_live, my_elm, my_irn)
- {
- ptr_element_t *my_element = ptr_get_new_element(ifg);
- my_element->content_first.element = last_element.element;
- my_element->content_second.irn = my_irn;
- my_element->kind = 3101; /* first is an element, second an ir_node */
-
- last_element.element = my_element;
- ifg->curr_element = my_element;
- }
- }
- else
- {
- bitset_foreach_irn(ifg->env->irg, my_live, my_elm, my_irn);
- {
- ptr_element_t *my_element = ptr_get_new_element(ifg);
- my_element->content_first.irn = my_irn;
- my_element->content_second.irn = NULL;
- my_element->kind = 8889;
- last_element.element = my_element;
- ifg->curr_element = my_element;
- }
- }
- }
- }
- bitset_free(my_live);
- bitset_remv_irn(live, irn);
- }
- }
- bitset_free(live);
-}
-
-static ir_node *get_first_irn(const ifg_pointer_t *ifg, ptr_iter_t *it)
-{
- ir_node *irn = phase_get_first_node(&ifg->ph);
-
- if (! irn)
- return NULL;
-
- it->curr_irn = irn;
-
- return irn;
-}
-
-static ir_node *get_next_irn(ptr_iter_t *it)
-{
- ir_node *irn = phase_get_next_node(&it->ifg->ph, it->curr_irn);
-
- if (! irn)
- return NULL;
-
- it->curr_irn = irn;
-
- return irn;
-}
-
-static ir_node *get_next_neighbour(ptr_iter_t *it)
-{
- ir_node *res;
- ptr_head_t *head;
- ptr_element_t *element;
-
- element = it->curr_element_t;
-
- if (element == NULL)
- {
- if (it->curr_ptr_head->list.next != &it->first_head->list)
- {
- head = list_entry(it->curr_ptr_head->list.next, ptr_head_t, list);
- it->curr_ptr_head = head;
- element = head->element;
- }
- else
- return NULL; /* there are no more neighbours */
- }
-
- if (element && element->kind == 8889) /* node has no neighbours */
- {
- res = element->content_first.irn;
- it->curr_element_t = NULL;
- }
- else
- {
- if (element && element->kind == 8888) /* node has only one more neighbour */
- {
- if (it->get_first)
- {
- if (element->content_first.irn != it->irn)
- {
- res = element->content_first.irn;
- it->get_first = 0;
- it->curr_element_t = NULL;
- }
- else
- {
- it->get_first = 0;
- it->curr_element_t = NULL;
- it->sub_call++;
- res = get_next_neighbour(it);
- it->sub_call--;
- }
- }
- else
- {
- if (element->content_second.irn != it->irn)
- {
- res = element->content_second.irn;
- it->get_first = 1;
- it->curr_element_t = element;
- }
- else
- {
- it->get_first = 1;
- it->curr_element_t = element;
- it->sub_call++;
- res = get_next_neighbour(it);
- it->sub_call--;
- }
- }
- }
- else
- {
- if (element && element->kind == 3101)
- {
- it->curr_element_t = element->content_first.element;
- res = element->content_second.irn;
- }
- else
- { /* element is only an ir_node */// TODO
- it->curr_element_t = NULL;
- return NULL;
- }
- }
- }
-
- if (res && !it->sub_call)
- {
- if (bitset_contains_irn(it->visited_neighbours, res) || res == it->irn)
- {
- res = get_next_neighbour(it);
- }
- else
- {
- bitset_set(it->visited_neighbours, get_irn_idx(res));
- }
- }
-
- return res;
-}
-
-static ir_node *get_first_neighbour(const ifg_pointer_t *ifg, ptr_iter_t *it, const ir_node *irn)
-{
- ir_node *res;
- ptr_head_t *head;
- ptr_element_t *element;
- bitset_t *bitsetvisited_neighbours = bitset_malloc(get_irg_last_idx(ifg->env->irg));
-
- it->ifg = ifg;
- it->irn = irn;
- it->get_first = 0;
- it->sub_call = 0;
-
- it->visited_neighbours = bitsetvisited_neighbours;
-
- head = phase_get_irn_data(&ifg->ph, irn);
- if (! head)
- return NULL;
- else
- {
- it->first_head = head;
- head = list_entry(it->first_head->list.next, ptr_head_t, list); /* because first element is NULL */
- it->curr_ptr_head = head;
- element = head->element;
- }
-
- if (element && element->kind == 8889) /* node has no neighbours */
- {
- res = element->content_first.irn;
- it->curr_element_t = NULL;
- }
- else
- {
- if (element && element->kind == 8888) /* node has only one neighbour */
- {
- if (it->get_first)
- {
- if (element->content_first.irn != it->irn)
- {
- res = element->content_first.irn;
- it->get_first = 0;
- it->curr_element_t = NULL;
- }
- else
- {
- it->get_first = 0;
- it->curr_element_t = NULL;
- it->sub_call++;
- res = get_next_neighbour(it);
- it->sub_call--;
- }
- }
- else
- {
- if (element->content_second.irn != it->irn)
- {
- res = element->content_second.irn;
- it->curr_element_t = element;
- it->get_first = 1;
- }
- else
- {
- it->get_first = 1;
- it->curr_element_t = element;
- it->sub_call++;
- res = get_next_neighbour(it);
- it->sub_call--;
- }
- }
- }
- else
- if (element && element->kind == 3101)
- {
- it->curr_element_t = element->content_first.element;
- res = element->content_second.irn;
- }
- else
- { /* element is only an ir_node */
- it->curr_element_t = NULL;
- return NULL;
- }
- }
-
- if (res && !it->sub_call)
- {
- if (bitset_contains_irn(it->visited_neighbours, res) || res == it->irn)
- {
- res = get_next_neighbour(it);
- }
- else
- {
- bitset_set(it->visited_neighbours, get_irn_idx(res));
- }
- }
-
- return res;
-}
-
-
-
-/* PUBLIC FUNCTIONS */
-
-static void ifg_pointer_free(void *self)
-{
- ifg_pointer_t *ifg = self;
- obstack_free(&ifg->obst, NULL);
- phase_deinit(&ifg->ph);
-
- free(self);
-}
-
-static int ifg_pointer_connected(const void *self, const ir_node *a, const ir_node *b)
-{
- const ifg_pointer_t *ifg = self;
- int connected = -1;
- ptr_iter_t it;
- ir_node *irn = NULL;
-
- irn = get_first_neighbour(ifg, &it, a);
- connected = 0;
- while (irn != NULL)
- {
- if (irn == b)
- {
- connected = 1;
- break;
- }
- irn = get_next_neighbour(&it);
- }
-
- return connected;
-}
-
-static ir_node *ifg_pointer_neighbours_begin(const void *self, void *iter, const ir_node *irn)
-{
- return get_first_neighbour(self, iter, irn);
-}
-
-static ir_node *ifg_pointer_neighbours_next(const void *self, void *iter)
-{
- (void) self;
- return get_next_neighbour(iter);
-}
-
-static void ifg_pointer_neighbours_break(const void *self, void *iter)
-{
- ptr_iter_t *it = iter;
- (void) self;
-
- bitset_free(it->visited_neighbours);
-}
-
-static ir_node *ifg_pointer_nodes_begin(const void *self, void *iter)
-{
- return get_first_irn(self, iter);
-}
-
-static ir_node *ifg_pointer_nodes_next(const void *self, void *iter)
-{
- (void) self;
- return get_next_irn(iter);
-}
-
-static void ifg_pointer_nodes_break(const void *self, void *iter)
-{
- (void) self;
- (void) iter;
- return;
-}
-
-static int ifg_pointer_degree(const void *self, const ir_node *irn)
-{
- int degree = -1;
- ptr_iter_t it;
-
- irn = get_first_neighbour(self, &it, irn);
- degree = 0;
- while (irn != NULL)
- {
- degree++;
- irn = get_next_neighbour(&it);
- }
-
- return degree;
-}
-
-static const be_ifg_impl_t ifg_pointer_impl = {
- sizeof(ptr_iter_t),
- sizeof(ptr_iter_t),
- 0,
- ifg_pointer_free,
- ifg_pointer_connected,
- ifg_pointer_neighbours_begin,
- ifg_pointer_neighbours_next,
- ifg_pointer_neighbours_break,
- ifg_pointer_nodes_begin,
- ifg_pointer_nodes_next,
- ifg_pointer_nodes_break,
- NULL,
- NULL,
- NULL,
- ifg_pointer_degree
-};
-
-be_ifg_t *be_ifg_pointer_new(const be_chordal_env_t *env)
-{
- ifg_pointer_t *ifg = XMALLOC(ifg_pointer_t);
- ifg->impl = &ifg_pointer_impl;
- ifg->env = env;
-
- phase_init(&ifg->ph, env->irg, ptr_irn_data_init);
- obstack_init(&ifg->obst);
-
- dom_tree_walk_irg(env->irg, find_neighbour_walker, NULL, ifg);
-
- obstack_finish(&ifg->obst);
- return (be_ifg_t *) ifg;
-}
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief Default ifg implementation.
- * @author Sebastian Hack
- * @date 18.11.2005
- * @version $Id$
- */
-#include "config.h"
-
-#include <stdlib.h>
-
-#include "list.h"
-
-#include "irnode_t.h"
-#include "irnodeset.h"
-#include "irgraph_t.h"
-#include "irgwalk.h"
-#include "irtools.h"
-
-#include "bearch.h"
-#include "be_t.h"
-#include "belive_t.h"
-#include "bera.h"
-#include "beifg_t.h"
-#include "beifg_impl.h"
-#include "bechordal_t.h"
-#include "beirg.h"
-#include "beintlive_t.h"
-
-typedef struct _ifg_std_t ifg_std_t;
-
-struct _ifg_std_t {
- const be_ifg_impl_t *impl;
- const be_chordal_env_t *env;
-};
-
-static void ifg_std_free(void *self)
-{
- free(self);
-}
-
-static int ifg_std_connected(const void *self, const ir_node *a, const ir_node *b)
-{
- const ifg_std_t *ifg = self;
- return be_values_interfere(ifg->env->birg->lv, a, b);
-}
-
-typedef struct _nodes_iter_t {
- const be_chordal_env_t *env;
- struct obstack obst;
- int n;
- int curr;
- ir_node **nodes;
-} nodes_iter_t;
-
-static void nodes_walker(ir_node *bl, void *data)
-{
- nodes_iter_t *it = data;
- struct list_head *head = get_block_border_head(it->env, bl);
- border_t *b;
-
- foreach_border_head(head, b) {
- if (b->is_def && b->is_real) {
- obstack_ptr_grow(&it->obst, b->irn);
- it->n++;
- }
- }
-}
-
-static void find_nodes(const void *self, void *iter)
-{
- const ifg_std_t *ifg = self;
- nodes_iter_t *it = iter;
-
- obstack_init(&it->obst);
- it->n = 0;
- it->curr = 0;
- it->env = ifg->env;
-
- irg_block_walk_graph(ifg->env->irg, nodes_walker, NULL, iter);
- obstack_ptr_grow(&it->obst, NULL);
- it->nodes = obstack_finish(&it->obst);
-}
-
-static inline void node_break(nodes_iter_t *it, int force)
-{
- if ((it->curr >= it->n || force) && it->nodes) {
- obstack_free(&it->obst, NULL);
- it->nodes = NULL;
- }
-}
-
-static ir_node *get_next_node(void *iter)
-{
- nodes_iter_t *it = iter;
- ir_node *res = NULL;
-
- if (it->curr < it->n)
- res = it->nodes[it->curr++];
-
- node_break(it, 0);
-
- return res;
-}
-
-static ir_node *ifg_std_nodes_begin(const void *self, void *iter)
-{
- find_nodes(self, iter);
- return get_next_node(iter);
-}
-
-static ir_node *ifg_std_nodes_next(const void *self, void *iter)
-{
- (void) self;
- return get_next_node(iter);
-}
-
-static void ifg_std_nodes_break(const void *self, void *iter)
-{
- (void) self;
- node_break(iter, 1);
-}
-
-typedef struct _adj_iter_t {
- const be_chordal_env_t *env;
- const ir_node *irn;
- int valid;
- ir_nodeset_t neighbours;
- ir_nodeset_iterator_t iter;
-} adj_iter_t;
-
-static void find_neighbour_walker(ir_node *block, void *data)
-{
- adj_iter_t *it = data;
- struct list_head *head = get_block_border_head(it->env, block);
-
- border_t *b;
- int has_started = 0;
-
- if (!be_is_live_in(it->env->birg->lv, block, it->irn) && block != get_nodes_block(it->irn))
- return;
-
- foreach_border_head(head, b) {
- ir_node *irn = b->irn;
-
- if (irn == it->irn) {
- if (b->is_def)
- has_started = 1;
- else
- break; /* if we reached the end of the node's lifetime we can safely break */
- }
- else if (b->is_def) {
- /* if any other node than the one in question starts living, add it to the set */
- ir_nodeset_insert(&it->neighbours, irn);
- }
- else if (!has_started) {
- /* we only delete, if the live range in question has not yet started */
- ir_nodeset_remove(&it->neighbours, irn);
- }
-
- }
-}
-
-static void find_neighbours(const ifg_std_t *ifg, adj_iter_t *it, const ir_node *irn)
-{
- it->env = ifg->env;
- it->irn = irn;
- it->valid = 1;
- ir_nodeset_init(&it->neighbours);
-
- dom_tree_walk(get_nodes_block(irn), find_neighbour_walker, NULL, it);
-
- ir_nodeset_iterator_init(&it->iter, &it->neighbours);
-}
-
-static inline void neighbours_break(adj_iter_t *it, int force)
-{
- (void) force;
- assert(it->valid == 1);
- ir_nodeset_destroy(&it->neighbours);
- it->valid = 0;
-}
-
-static ir_node *get_next_neighbour(adj_iter_t *it)
-{
- ir_node *res = ir_nodeset_iterator_next(&it->iter);
-
- if (res == NULL) {
- ir_nodeset_destroy(&it->neighbours);
- }
- return res;
-}
-
-static ir_node *ifg_std_neighbours_begin(const void *self, void *iter, const ir_node *irn)
-{
- adj_iter_t *it = iter;
- find_neighbours(self, iter, irn);
- return ir_nodeset_iterator_next(&it->iter);
-}
-
-static ir_node *ifg_std_neighbours_next(const void *self, void *iter)
-{
- (void) self;
- return get_next_neighbour(iter);
-}
-
-static void ifg_std_neighbours_break(const void *self, void *iter)
-{
- (void) self;
- neighbours_break(iter, 1);
-}
-
-typedef struct _cliques_iter_t {
- struct obstack ob;
- const be_chordal_env_t *cenv;
- ir_node **buf;
- ir_node **blocks;
- int n_blocks, blk;
- struct list_head *bor;
- pset *living;
-} cliques_iter_t;
-
-static inline void free_clique_iter(cliques_iter_t *it)
-{
- it->n_blocks = -1;
- obstack_free(&it->ob, NULL);
- del_pset(it->living);
-}
-
-static void get_blocks_dom_order(ir_node *blk, void *env)
-{
- cliques_iter_t *it = env;
- obstack_ptr_grow(&it->ob, blk);
-}
-
-#define pset_foreach(pset, irn) for (irn=pset_first(pset); irn; irn=pset_next(pset))
-
-
-/**
- * NOTE: Be careful when changing this function!
- * First understand the control flow of consecutive calls.
- */
-static inline int get_next_clique(cliques_iter_t *it)
-{
-
- /* continue in the block we left the last time */
- for (; it->blk < it->n_blocks; it->blk++) {
- int output_on_shrink = 0;
- struct list_head *head = get_block_border_head(it->cenv, it->blocks[it->blk]);
-
- /* on entry to a new block set the first border ... */
- if (!it->bor)
- it->bor = head->prev;
-
- /* ... otherwise continue with the border we left the last time */
- for (; it->bor != head; it->bor = it->bor->prev) {
- border_t *b = list_entry(it->bor, border_t, list);
-
- /* if its a definition irn starts living */
- if (b->is_def) {
- pset_insert_ptr(it->living, b->irn);
- if (b->is_real)
- output_on_shrink = 1;
- } else
-
- /* if its the last usage the irn dies */
- {
- /* before shrinking the set, return the current maximal clique */
- if (output_on_shrink) {
- int count = 0;
- ir_node *irn;
-
- /* fill the output buffer */
- pset_foreach(it->living, irn)
- it->buf[count++] = irn;
-
- assert(count > 0 && "We have a 'last usage', so there must be sth. in it->living");
-
- return count;
- }
-
- pset_remove_ptr(it->living, b->irn);
- }
- }
-
- it->bor = NULL;
- assert(0 == pset_count(it->living) && "Something has survived! (At the end of the block it->living must be empty)");
- }
-
- if (it->n_blocks != -1)
- free_clique_iter(it);
-
- return -1;
-}
-
-static int ifg_std_cliques_begin(const void *self, void *iter, ir_node **buf)
-{
- const ifg_std_t *ifg = self;
- cliques_iter_t *it = iter;
- ir_node *start_bl = get_irg_start_block(ifg->env->irg);
-
- obstack_init(&it->ob);
- dom_tree_walk(start_bl, get_blocks_dom_order, NULL, it);
-
- it->cenv = ifg->env;
- it->buf = buf;
- it->n_blocks = obstack_object_size(&it->ob) / sizeof(void *);
- it->blocks = obstack_finish(&it->ob);
- it->blk = 0;
- it->bor = NULL;
- it->living = pset_new_ptr(2 * arch_register_class_n_regs(it->cenv->cls));
-
- return get_next_clique(it);
-}
-
-static int ifg_std_cliques_next(const void *self, void *iter)
-{
- (void) self;
- return get_next_clique(iter);
-}
-
-static void ifg_std_cliques_break(const void *self, void *iter)
-{
- (void) self;
- free_clique_iter(iter);
-}
-
-
-static int ifg_std_degree(const void *self, const ir_node *irn)
-{
- adj_iter_t it;
- int degree;
- find_neighbours(self, &it, irn);
- degree = ir_nodeset_size(&it.neighbours);
- neighbours_break(&it, 1);
- return degree;
-}
-
-static const be_ifg_impl_t ifg_std_impl = {
- sizeof(nodes_iter_t),
- sizeof(adj_iter_t),
- sizeof(cliques_iter_t),
-
- ifg_std_free,
- ifg_std_connected,
- ifg_std_neighbours_begin,
- ifg_std_neighbours_next,
- ifg_std_neighbours_break,
- ifg_std_nodes_begin,
- ifg_std_nodes_next,
- ifg_std_nodes_break,
- ifg_std_cliques_begin,
- ifg_std_cliques_next,
- ifg_std_cliques_break,
- ifg_std_degree
-};
-
-be_ifg_t *be_ifg_std_new(const be_chordal_env_t *env)
-{
- ifg_std_t *ifg = XMALLOC(ifg_std_t);
-
- ifg->impl = &ifg_std_impl;
- ifg->env = env;
-
- return (be_ifg_t *) ifg;
-}
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief Common use interference graph.
- * @author Sebastian Hack
- * @date 27.06.2005
- * @version $Id$
- *
- * Originally written by Sebastian Hack. Refactored into a seperate
- * source file and header by Kimon Hoffmann.
- */
-#ifndef FIRM_BE_BEIFG_T_H
-#define FIRM_BE_BEIFG_T_H
-
-#include "beifg.h"
-
-struct _be_ifg_impl_t {
- size_t nodes_iter_size;
- size_t neighbours_iter_size;
- size_t cliques_iter_size;
-
- void (*free)(void *self);
- int (*connected)(const void *self, const ir_node *a, const ir_node *b);
-
- ir_node *(*neighbours_begin)(const void *self, void *iter, const ir_node *irn);
- ir_node *(*neighbours_next)(const void *self, void *iter);
- void (*neighbours_break)(const void *self, void *iter);
-
- ir_node *(*nodes_begin)(const void *self, void *iter);
- ir_node *(*nodes_next)(const void *self, void *iter);
- void (*nodes_break)(const void *self, void *iter);
-
- int (*cliques_begin)(const void *self, void *iter, ir_node **buf);
- int (*cliques_next)(const void *self, void *iter);
- void (*cliques_break)(const void *self, void *iter);
-
- int (*degree)(const void *self, const ir_node *irn);
-};
-
-struct _be_ifg_t {
- const be_ifg_impl_t *impl;
- const be_chordal_env_t *env;
-};
-
-#ifdef _BE_IFG_USE_MACROS
-
-#define be_ifg_nodes_iter_size(self) ((self)->impl->nodes_iter_size)
-#define be_ifg_neighbours_iter_size(self) ((self)->impl->neighbours_iter_size)
-#define be_ifg_cliques_iter_size(self) ((self)->impl->cliques_iter_size)
-
-#define be_ifg_free(self) ((self)->impl->free(self))
-#define be_ifg_connected(self,a,b) ((self)->impl->connected(self, a, b))
-#define be_ifg_neighbours_begin(self, iter, irn) ((self)->impl->neighbours_begin(self, iter, irn))
-#define be_ifg_neighbours_next(self, iter) ((self)->impl->neighbours_next(self, iter))
-#define be_ifg_neighbours_break(self, iter) ((self)->impl->neighbours_break(self, iter))
-#define be_ifg_nodes_begin(self, iter) ((self)->impl->nodes_begin(self, iter))
-#define be_ifg_nodes_next(self, iter) ((self)->impl->nodes_next(self, iter))
-#define be_ifg_nodes_break(self, iter) ((self)->impl->nodes_break(self, iter))
-#define be_ifg_cliques_begin(self, iter, buf) ((self)->impl->cliques_begin(self, iter, buf))
-#define be_ifg_cliques_next(self, iter) ((self)->impl->cliques_next(self, iter))
-#define be_ifg_cliques_break(self, iter) ((self)->impl->cliques_break(self, iter))
-#define be_ifg_degree(self,irn) ((self)->impl->degree(self, irn))
-
-#endif /* _BE_IFG_USE_MACROS */
-
-void be_ifg_check(const be_ifg_t *ifg);
-
-#endif /* FIRM_BE_BEIFG_T_H */
#include "bera.h"
#include "bechordal_t.h"
#include "beifg.h"
-#include "beifg_impl.h"
#include "becopyopt.h"
#include "becopystat.h"
#include "bessadestr.h"
void be_init_ssaconstr(void);
void be_init_stabs(void);
void be_init_pref_alloc(void);
-void be_init_ifg(void);
void be_init_irgmod(void);
void be_init_loopana(void);
void be_init_spillslots(void);
be_init_ssaconstr();
be_init_pref_alloc();
be_init_state();
- be_init_ifg();
be_init_stabs();
be_init_arch_ia32();
}
}
- strncat(buf, ent->name, len);
+ strncat(buf, ent->name, len-1);
}
static char *lc_opt_print_grp_path(char *buf, size_t len, const lc_opt_entry_t *ent, char separator, lc_opt_entry_t *stop_ent)
/* <cmnt>.ini */
strncpy(local_ini_file, ini_name, sizeof(local_ini_file));
- strncat(local_ini_file, ".ini", sizeof(local_ini_file));
+ strncat(local_ini_file, ".ini", sizeof(local_ini_file)-1);
local_ini_file[sizeof(local_ini_file) - 1] = '\0';
path[0] = '\0';
#if _MSC_VER > 1200
/* ARG: need newer SDK to compile this */
SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, path);
- strncat(path, "\\", sizeof(path));
+ strncat(path, "\\", sizeof(path)-1);
#endif
strncpy(home_dir_ini_file, local_ini_file, sizeof(home_dir_ini_file));
home_dir_ini_file[sizeof(home_dir_ini_file) - 1] = '\0';
struct passwd *entry = getpwuid(getuid());
if (entry != NULL) {
strcpy(path, entry->pw_dir);
- strncat(path, "/", sizeof(path));
+ strncat(path, "/", sizeof(path)-1);
/* .<cmnt>rc */
snprintf(home_dir_ini_file, sizeof(home_dir_ini_file), ".%src", ini_name);
home_dir_ini_file[sizeof(home_dir_ini_file) - 1] = '\0';
}
#endif
- strncat(path, home_dir_ini_file, sizeof(path));
+ strncat(path, home_dir_ini_file, sizeof(path)-1);
path[sizeof(path) - 1] = '\0';
/* Process ini file in user's home. */