+#include "beifg_impl.h"
+#include "irphase.h"
+#include "irphase_t.h"
+#include "bechordal.h"
+
+#include "becopystat.h"
+#include "becopyopt.h"
+#include "beirg_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 {
+ phase_t ph;
+ const arch_env_t *arch_env;
+ ir_graph *irg;
+};
+
+size_t (be_ifg_nodes_iter_size)(const void *self)
+{
+ const be_ifg_t *ifg = self;
+ return ifg->impl->nodes_iter_size;
+}
+
+size_t (be_ifg_neighbours_iter_size)(const void *self)
+{
+ const be_ifg_t *ifg = self;
+ return ifg->impl->neighbours_iter_size;
+}
+
+size_t (be_ifg_cliques_iter_size)(const void *self)
+{
+ const be_ifg_t *ifg = self;
+ return ifg->impl->cliques_iter_size;
+}
+
+static void *regs_irn_data_init(phase_t *ph, ir_node *irn, void *data)
+{
+ coloring_t *coloring = (coloring_t *) ph;
+ return (void *) arch_get_irn_register(coloring->arch_env, irn);
+}
+
+coloring_t *coloring_init(coloring_t *c, ir_graph *irg, const arch_env_t *aenv)
+{
+ phase_init(&c->ph, "regs_map", irg, PHASE_DEFAULT_GROWTH, regs_irn_data_init);
+ c->arch_env = aenv;
+ c->irg = irg;
+ return c;
+}
+
+static void get_irn_color(ir_node *irn, void *c)
+{
+ coloring_t *coloring = c;
+ phase_get_or_set_irn_data(&coloring->ph, irn);
+}
+
+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(coloring->arch_env, irn, reg);
+}
+
+void coloring_save(coloring_t *c)
+{
+ irg_walk_graph(c->irg, NULL, get_irn_color, c);
+}
+
+void coloring_restore(coloring_t *c)
+{
+ irg_walk_graph(c->irg, NULL, restore_irn_color, c);
+}
+
+void (be_ifg_free)(void *self)
+{
+ be_ifg_t *ifg = self;
+ ifg->impl->free(self);
+}
+
+int (be_ifg_connected)(const void *self, const ir_node *a, const ir_node *b)
+{
+ const be_ifg_t *ifg = self;
+ return ifg->impl->connected(self, a, b);
+}
+
+ir_node *(be_ifg_neighbours_begin)(const void *self, void *iter, const ir_node *irn)
+{
+ const be_ifg_t *ifg = self;
+ return ifg->impl->neighbours_begin(self, iter, irn);
+}
+
+ir_node *(be_ifg_neighbours_next)(const void *self, void *iter)
+{
+ const be_ifg_t *ifg = self;
+ return ifg->impl->neighbours_next(self, iter);
+}
+
+void (be_ifg_neighbours_break)(const void *self, void *iter)
+{
+ const be_ifg_t *ifg = self;
+ ifg->impl->neighbours_break(self, iter);
+}
+
+ir_node *(be_ifg_nodes_begin)(const void *self, void *iter)
+{
+ const be_ifg_t *ifg = self;
+ return ifg->impl->nodes_begin(self, iter);
+}
+
+ir_node *(be_ifg_nodes_next)(const void *self, void *iter)
+{
+ const be_ifg_t *ifg = self;
+ return ifg->impl->nodes_next(self, iter);
+}
+
+void (be_ifg_nodes_break)(const void *self, void *iter)
+{
+ const be_ifg_t *ifg = self;
+ ifg->impl->nodes_break(self, iter);
+}
+
+int (be_ifg_cliques_begin)(const void *self, void *iter, ir_node **buf)
+{
+ const be_ifg_t *ifg = self;
+ return ifg->impl->cliques_begin(self, iter, buf);
+}
+
+int (be_ifg_cliques_next)(const void *self, void *iter)
+{
+ const be_ifg_t *ifg = self;
+ return ifg->impl->cliques_next(self, iter);
+}
+
+void (be_ifg_cliques_break)(const void *self, void *iter)
+{
+ const be_ifg_t *ifg = self;
+ ifg->impl->cliques_break(self, iter);
+}
+
+int (be_ifg_degree)(const void *self, const ir_node *irn)
+{
+ const be_ifg_t *ifg = self;
+ return ifg->impl->degree(self, irn);
+}
+
+
+int be_ifg_is_simplicial(const be_ifg_t *ifg, const ir_node *irn)
+{
+ int degree = be_ifg_degree(ifg, irn);
+ void *iter = be_ifg_neighbours_iter_alloca(ifg);
+
+ ir_node **neighbours = xmalloc(degree * sizeof(neighbours[0]));
+
+ ir_node *curr;
+ int i, j;
+
+ i = 0;
+ be_ifg_foreach_neighbour(ifg, iter, irn, curr)
+ neighbours[i++] = curr;
+
+ for(i = 0; i < degree; ++i) {
+ for(j = 0; j < i; ++j)
+ if(!be_ifg_connected(ifg, neighbours[i], neighbours[j])) {
+ free(neighbours);
+ return 0;
+ }
+ }
+
+
+ free(neighbours);
+ return 1;
+}
+
+void be_ifg_check(const be_ifg_t *ifg)
+{
+ 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);
+}
+
+int be_ifg_check_get_node_count(const be_ifg_t *ifg)
+{
+ void *iter = be_ifg_nodes_iter_alloca(ifg);
+ int node_count = 0;
+ ir_node *n;
+
+ be_ifg_foreach_node(ifg, iter, n)
+ {
+ node_count++;
+ }