-/* Resets block mark for given node. For use with walker */
-static void reset_block_mark(ir_node *node, void * env)
-{
- (void) env;
-
- if (is_Block(node))
- set_Block_mark(node, 0);
-}
-
-static unsigned is_nodes_block_marked(ir_node* node)
-{
- if (is_Block(node))
- return get_Block_mark(node);
- else
- return get_Block_mark(get_block(node));
-}
-
-/* Returns the number of blocks in a loop. */
-static int get_loop_n_blocks(ir_loop *loop)
-{
- int elements, e;
- int blocks = 0;
- elements = get_loop_n_elements(loop);
-
- for (e=0; e<elements; e++) {
- loop_element elem = get_loop_element(loop, e);
- if (is_ir_node(elem.kind) && is_Block(elem.node))
- ++blocks;
- }
- return blocks;
-}
-
-/**/
-static int extend_irn(ir_node *n, ir_node *new)
-{
- ir_node **ins;
- int i;
- int arity = get_irn_arity(n);
- int new_arity = arity + 1;
-
- NEW_ARR_A(ir_node *, ins, new_arity);
-
- for(i = 0; i < arity; ++i) {
- ins[i] = get_irn_n(n, i);
- }
- ins[i] = new;
-
- set_irn_in(n, new_arity, ins);
- /* arity equals the position of the new node */
- return arity;
-}
-
-/* */
-static void extend_ins_by_copy(ir_node *block, int pos)
-{
- ir_node *new_in;
- ir_node *phi;
- ir_node *pred;
- assert(is_Block(block));
-
- /* Extend block by copy of definition at pos */
- pred = get_irn_n(block, pos);
- new_in = get_inversion_copy(pred);
- DB((dbg, LEVEL_5, "Extend block %N by %N cp of %N\n", block, new_in, pred));
- extend_irn(block, new_in);
-
- /* Extend block phis by copy of definition at pos */
- for_each_phi(block, phi) {
- ir_node *pred, *cp;
-
- pred = get_irn_n(phi, pos);
- cp = get_inversion_copy(pred);
- /* If the phis in is not in the condition chain (eg. a constant),
- * there is no copy. */
- if (cp == NULL)
- new_in = pred;
- else
- new_in = cp;
-
- DB((dbg, LEVEL_5, "Extend phi %N by %N cp of %N\n", phi, new_in, pred));
- extend_irn(phi, new_in);
- }
-}
-
-/*
- * Extends all blocks which succeed the loop with the copied loops outs.
- * Also extends the blocks phis. Requires block phi list.
- * Returns an updated list of loop outs of the original loop outs.
- */
-static out_edge *extend_ins(out_edge *outs, int copies)
-{
- ir_node **ins;
- ir_node **phi_ins;
- int *bes, *phi_bes;
- ir_node *phi, *next_phi, *new_phi, *head, *new_block;
- int old_arity, new_arity;
- int i, c, p;
- out_edge *new_outs;
-
- inc_irg_visited(current_ir_graph);
-
- new_outs = NEW_ARR_F(out_edge, 0);
-
-#if 0
- for (i = 0; i < ARR_LEN(outs); ++i) {
- out_edge edge = outs[i];
- ir_node *node = edge.node;
- DB((dbg, LEVEL_5, "outs %N %d\n", node, edge.pos));
- }
-#endif
-
- for (i = 0; i < ARR_LEN(outs); ++i) {
- out_edge edge = outs[i];
- ir_node *node = edge.node;
- int in_c, positions_n;
- int *positions;
-
- if (!is_Block(node) && !is_Bad(node)) {
-#if 0
- if (is_Phi(node)) {
- int c;
- unsigned b = 0;
- ir_node *p = get_nodes_block(node);
- for(c = 0; c < get_irn_arity(p); ++c) {
- if (is_in_loop(get_irn_n(p, c))) {
- b=1;
- break;
- }
- }
- if (!b) {
- ARR_APP1(out_edge, new_outs, edge);
- DB((dbg, LEVEL_5, "new out %N\n", node));
- }
-
- } else {
-#endif
- ARR_APP1(out_edge, new_outs, edge);
- DB((dbg, LEVEL_5, "new out %N\n", node));
-
- }
-
- /* CONTINUE if node already processed. */
- if (irn_visited(node))
- continue;
-
- if (!is_Block(node))
- continue;
-
- positions = NEW_ARR_F(int, 0);
- positions_n = 0;
-
- /* Search for all occurences of the current node, and save the in positions. */
- for (p = 0; p < ARR_LEN(outs); ++p) {
- ir_node *cur = outs[p].node;
- int d_pos = outs[p].pos;
-
- if (node==cur) {
- DB((dbg, LEVEL_5, "Loop successor %N with pred @%d in loop\n",
- node, d_pos));
- ARR_APP1(int, positions, d_pos);
- mark_irn_visited(cur);
- ++positions_n;
- }
- }
-
- old_arity = get_irn_arity(node);
- new_arity = old_arity + (positions_n * copies);
-
- ins = NEW_ARR_F(ir_node*, new_arity);
- bes = NEW_ARR_F(int, new_arity);
-
- /* extend block ins */
- for (in_c = 0; in_c < old_arity; ++in_c) {
- ins[in_c] = get_irn_n(node, in_c);
- bes[in_c] = is_backedge(node, in_c);
- }
- for (p = 0; p < positions_n; ++p) {
- for (c = 0; c < copies; ++c) {
- ir_node *cp = get_copy_safe(get_irn_n(node, positions[p]), c);
- DB((dbg, LEVEL_5, "%N (new_arity %d) @%d = %N\n",
- node, new_arity, in_c, cp));
- ins[in_c] = cp;
- bes[in_c] = is_backedge(node, positions[p]);
- ++in_c;
- }
- }
-
- assert(new_arity == in_c);
-
- head = get_Block_phis(node);
- new_block = new_r_Block(get_irn_irg(node), new_arity, ins);
- set_irn_loop(new_block, get_irn_loop(node));
-
- for (in_c = 0; in_c < new_arity; ++in_c) {
- if (bes[in_c])
- set_backedge(new_block, in_c);
- }
- DEL_ARR_F(ins);
- DEL_ARR_F(bes);
-
-#if 1
- set_Block_phis(node, NULL);
-
- phi_ins = NEW_ARR_F(ir_node *, new_arity);
- phi_bes = NEW_ARR_F(int, new_arity);
-
- for_each_phi_safe(head, phi, next_phi) {
- for (in_c = 0; in_c < old_arity; ++in_c) {
- phi_ins[in_c] = get_irn_n(phi, in_c);
- phi_bes[in_c] = is_backedge(phi, in_c);
- }
-
- for (p = 0; p < positions_n; ++p) {
- for(c = 0; c < copies; ++c) {
- ir_node *cp, *pred;
- pred = get_irn_n(phi, positions[p]);
- DB((dbg, LEVEL_5, "Phi %N pred @%d is %N\n",
- phi, positions[p], pred));
- cp = get_copy_safe(pred, c);
- phi_ins[in_c] = cp;
- DB((dbg, LEVEL_5, "Phi %N in %d is %N\n",
- phi, in_c, cp));
- phi_bes[in_c] = is_backedge(phi, positions[p]);
- ++in_c;
- }
- }
-
- new_phi = new_r_Phi(new_block, new_arity, phi_ins, get_irn_mode(phi));
-
- for (in_c = 0; in_c < new_arity; ++in_c) {
- if (phi_bes[in_c])
- set_backedge(new_phi, in_c);
- }
- DB((dbg, LEVEL_5, "extend ins exch phi %N %N\n", phi, new_phi));
- exchange(phi, new_phi);
- DB((dbg, LEVEL_5, "exch Phi %N %N\n",phi, new_phi));
-
- add_Block_phi(new_block, new_phi);
- }
-
- DEL_ARR_F(phi_ins);
- DEL_ARR_F(phi_bes);
-#endif
- DB((dbg, LEVEL_5, "extend ins exch block %N %N\n", node, new_block));
- exchange(node, new_block);
- set_Block_MacroBlock(new_block, new_block);
- DB((dbg, LEVEL_5, "exch block %N %N\n", node, new_block));
-
- DEL_ARR_F(positions);
- }
- return new_outs;
-}
-
-/**
- * Finds loop head and some loop_info as calls or else if necessary.
- */