+ copies_t key, *value;
+ int set_el, new_preds, all_new_preds, i, q;
+ int old_preds = get_Block_n_cfgpreds(end_block); /* All old predecessors of the end block. */
+ ir_node **all_in;
+
+ for (i = 0; i < old_preds; i++) {
+ ir_node *pred = get_Block_cfgpred(end_block, i);
+ key.irn = pred;
+ value = NULL;
+ value = set_find( l_n, &key, sizeof(key), HASH_PTR(key.irn));
+
+ /* If a predecessor of the end block is a Proj from the unrolling loop (for function calls) .*/
+ if (get_irn_op(pred) == op_Proj && is_exception_possible(pred) && value != NULL &&
+ !(!copy_loop_head && get_nodes_block(pred) == loop_head))
+ value = set_insert(loop_endblock_outs, &key, sizeof(key), HASH_PTR(key.irn));
+ }
+
+ /* The set loop_endblock_outs contains all predecessors of the end block from the unrolling loop,
+ * set_el the amount of such nodes.
+ */
+ set_el = set_count (loop_endblock_outs);
+
+ /* If the end block haven't such predecessors, we are finished. */
+ if (!set_el) return;
+
+ new_preds = (unroll_factor - 1) * set_el; /* All new predecessors of the end block */
+ all_new_preds = old_preds + new_preds; /* All predecessors of this block. */
+ all_in = alloca(sizeof(*all_in) * all_new_preds); /* A array with size for all predecessors of this block. */
+
+ for (i = 0; i < old_preds; i++)
+ all_in[i] = get_Block_cfgpred(end_block, i); /* The old predecessors. */
+
+ value = set_first(loop_endblock_outs);
+
+ for (; value != NULL; value = set_next(loop_endblock_outs)) {
+ key.irn = value->irn;
+ value = set_find( l_n, &key, sizeof(key), HASH_PTR(key.irn));
+ for (q = 0; q < unroll_factor - 1 ; q++) {
+ all_in[i++] = value->copy[q]; /* The new predecessors. */
+ }
+
+ }
+
+ /* Replace the old predecessors of the end block wit´h the new ones. */
+ set_irn_in(end_block, all_new_preds, all_in);
+}
+
+/** new_after_loop_block
+ *
+ * The after loop block must examine the possible exceptions in the loop.
+ * If a (Proj) node from the loop is predecessor of this block, then the
+ * after loop block must have as well all copies of this node as predecessors.
+ *
+ * @param l_n Contains all nodes of the loop.
+ * @block block A block after the loop.
+ * @param loop_in A node from the loop, that is predecessor of the end block.
+ * @param unroll_factor An integer 2 <= unroll_factor <= 4.
+ */
+static void
+new_after_loop_block (set *l_n, ir_node* block, copies_t *loop_in, int unroll_factor)
+{
+ copies_t key, *value;
+ int i, p, q, s, old_preds, new_preds, all_new_preds ;
+ ir_node **all_in;
+
+ /* The node from the unrolling loop must be a Proj. */
+ if (loop_in->irn->op != op_Proj) return;
+
+ old_preds = get_Block_n_cfgpreds(block); /* All old predecessors of this block. */
+ new_preds = old_preds * (unroll_factor - 1); /* All new predecessors of this block. */
+ all_new_preds = old_preds + new_preds; /* All predecessors of this block. */
+
+ all_in = alloca(sizeof(*all_in) * all_new_preds); /* An array with size for all predecessors of this block. */
+
+ for (i = 0 ; i < old_preds; i++)
+ all_in[i] = get_Block_cfgpred(block, i); /* The old predecessors. */
+
+ q = old_preds;
+ for (i = 0; i < old_preds; i++){
+ key.irn = all_in[i];
+ value = set_find( l_n, &key, sizeof(key), HASH_PTR(key.irn));
+ p = 0;
+ for (s = 0; s < (unroll_factor - 1); s++) {
+ all_in[q++] = value->copy[p++]; /* The new predecessors. */
+ }
+ }
+ /* Replace the old predecessors of the end block whit the new one. */
+ set_irn_in(block, all_new_preds, all_in);
+}
+
+/** new_after_loop_node
+ *
+ * An after loop node (phi or call) must examine the possible exceptions in the loop.
+ * If a (Proj) node from the loop is predecessor of this node, then the after loop
+ * node must have as well all copies of this node as predecessors.
+ *
+ * @param l_n Contains all nodes of the loop.
+ * @param loop_outs Contains nodes after the loop,that have as predecessor a node from the loop.
+ * @block node A node after the loop.
+ * @param loop_in A node (Proj) from the loop, that is predecessor of *node.
+ * @param unroll_factor An integer 2 <= unroll_factor <= 4.
+ */
+static void
+new_after_loop_node(set *l_n, set *loop_outs, ir_node *node, copies_t *loop_in, int unroll_factor)
+{
+ ir_node *pred, *block_pred = NULL, *node_block, *new_phi;
+ int phi = 0, old_preds, new_preds, all_new_preds, p, q, i, s;
+ copies_t key, *value = NULL;
+ ir_node **all_in;
+
+ old_preds = get_irn_arity(node); /* All old predecessors of this node. */
+ new_preds =old_preds * (unroll_factor - 1); /* All new predecessors of this block. */
+ all_new_preds = old_preds + new_preds; /* All predecessors of this block. */
+
+ all_in = alloca(sizeof(*all_in) * all_new_preds); /* An array with size for all predecessors of this block. */
+
+ /* Verification Predecessors, successors and operation of node and loop_in.
+ * loop_in must be a Proj node.
+ */
+ if (loop_in->irn->op != op_Proj) return;
+ /* Node must be operation Phi with mode memory or a Call node. */
+ if (get_irn_op(node) == op_Phi &&
+ get_irn_mode(node) == mode_M){
+ /* If node is a Phi node,then must have a Call node as successor. */
+ for (i = 0; i < get_irn_n_outs(node); i++)
+ if (get_irn_op(get_irn_out(node, i)) == op_Call) {
+ phi = 1;
+ break;
+ }
+
+ if (!phi) return;
+ }
+
+ /* The predecessor of loop_in must not be a loop invariant. */
+ pred = get_Proj_pred(loop_in->irn);
+ key.irn = pred;
+ value = set_find( l_n, &key, sizeof(key), HASH_PTR(key.irn));
+ if (! value) return;