exact_copy() added
[libfirm] / ir / common / irtools.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/irtools.c
4  * Purpose:     Some often needed tool-functions
5  * Author:      Michael Beck
6  * Modified by:
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1999-2005 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12 #ifdef HAVE_CONFIG_H
13 # include "config.h"
14 #endif
15
16 #include <stdlib.h>
17 #include "irnode_t.h"
18 #include "irbackedge_t.h"
19 #include "irtools.h"
20
21 /* the famous clear_link implementation. */
22 void firm_clear_link(ir_node *n, void *env) {
23   set_irn_link(n, NULL);
24 }
25
26 /*
27  * Copies a node to a new irg. The Ins of the new node point to
28  * the predecessors on the old irg.  n->link points to the new node.
29  *
30  * Does NOT copy standard nodes like Start, End etc that are fixed
31  * in an irg. Instead, the corresponding nodes of the new irg are returned.
32  * Note further, that the new nodes have no block.
33  */
34 void
35 copy_irn_to_irg(ir_node *n, ir_graph *irg)
36 {
37   ir_op *op = get_irn_op(n);
38   ir_graph *old_irg;
39   ir_node *nn = NULL;
40
41   /* do not copy standard nodes */
42   if (op == op_Bad)
43     nn = get_irg_bad(irg);
44   else if (op == op_NoMem)
45     n = get_irg_no_mem(irg);
46   else if (op == op_Block) {
47     old_irg = get_irn_irg(n);
48
49     if (n == get_irg_start_block(old_irg))
50       nn = get_irg_start_block(irg);
51     else if (n == get_irg_end_block(old_irg))
52       nn = get_irg_end_block(irg);
53   }
54   else if (op == op_Start)
55     nn = get_irg_start(irg);
56   else if (op == op_End)
57     nn = get_irg_end(irg);
58   else if (op == op_Proj) {
59     old_irg = get_irn_irg(n);
60
61     if (n == get_irg_frame(old_irg))
62       nn = get_irg_frame(irg);
63     else if (n == get_irg_globals(old_irg))
64       nn = get_irg_globals(irg);
65     else if (n == get_irg_initial_mem(old_irg))
66       nn = get_irg_initial_mem(irg);
67     else if (n == get_irg_args(old_irg))
68       nn = get_irg_args(irg);
69   }
70
71   if (nn) {
72     set_irn_link(n, nn);
73     return;
74   }
75
76   nn = new_ir_node(get_irn_dbg_info(n),
77          irg,
78          NULL,            /* no block yet, will be set later */
79          op,
80          get_irn_mode(n),
81          get_irn_arity(n),
82          get_irn_in(n) + 1);
83
84
85   /* Copy the attributes.  These might point to additional data.  If this
86      was allocated on the old obstack the pointers now are dangling.  This
87      frees e.g. the memory of the graph_arr allocated in new_immBlock. */
88   copy_node_attr(n, nn);
89   new_backedge_info(nn);
90   set_irn_link(n, nn);
91
92   /* fix the irg for blocks */
93   if (is_Block(nn))
94     nn->attr.block.irg = irg;
95 }
96
97 /*
98  * Creates an exact copy of a node.
99  * The copy resists on the sane graph in the same block.
100  */
101 ir_node *exact_copy(ir_node *n) {
102   ir_graph *irg = get_irn_irg(n);
103   ir_node *res, *block = NULL;
104
105   if (is_no_Block(n))
106     block = get_irn_n(n, -1);
107
108   res = new_ir_node(get_irn_dbg_info(n),
109                     irg,
110                     block,
111                     get_irn_op(n),
112                     get_irn_mode(n),
113                     get_irn_arity(n),
114                     get_irn_in(n) + 1);
115
116
117   /* Copy the attributes.  These might point to additional data.  If this
118      was allocated on the old obstack the pointers now are dangling.  This
119      frees e.g. the memory of the graph_arr allocated in new_immBlock. */
120   copy_node_attr(n, res);
121   new_backedge_info(res);
122   return res;
123 }