+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 be_ifg_t *ifg, nodes_iter_t *iter)
+{
+ obstack_init(&iter->obst);
+ iter->n = 0;
+ iter->curr = 0;
+ iter->env = ifg->env;
+
+ irg_block_walk_graph(ifg->env->irg, nodes_walker, NULL, iter);
+ obstack_ptr_grow(&iter->obst, NULL);
+ iter->nodes = obstack_finish(&iter->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(nodes_iter_t *it)
+{
+ ir_node *res = NULL;
+
+ if (it->curr < it->n)
+ res = it->nodes[it->curr++];
+
+ node_break(it, 0);
+
+ return res;
+}
+
+ir_node *be_ifg_nodes_begin(const be_ifg_t *ifg, nodes_iter_t *iter)
+{
+ find_nodes(ifg, iter);
+ return get_next_node(iter);
+}
+
+ir_node *be_ifg_nodes_next(nodes_iter_t *iter)
+{
+ return get_next_node(iter);
+}
+
+void be_ifg_nodes_break(nodes_iter_t *iter)
+{
+ node_break(iter, 1);
+}
+
+static void find_neighbour_walker(ir_node *block, void *data)
+{
+ neighbours_iter_t *it = data;
+ struct list_head *head = get_block_border_head(it->env, block);
+ be_lv_t *lv = be_get_irg_liveness(it->env->irg);
+
+ border_t *b;
+ int has_started = 0;
+
+ if (!be_is_live_in(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 be_ifg_t *ifg, neighbours_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(neighbours_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(neighbours_iter_t *it)
+{
+ ir_node *res = ir_nodeset_iterator_next(&it->iter);
+
+ if (res == NULL) {
+ ir_nodeset_destroy(&it->neighbours);
+ }
+ return res;
+}
+
+ir_node *be_ifg_neighbours_begin(const be_ifg_t *ifg, neighbours_iter_t *iter,
+ const ir_node *irn)
+{
+ find_neighbours(ifg, iter, irn);
+ return ir_nodeset_iterator_next(&iter->iter);
+}
+
+ir_node *be_ifg_neighbours_next(neighbours_iter_t *iter)
+{
+ return get_next_neighbour(iter);
+}