remove MacroBlock concept
[libfirm] / ir / common / irtools.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief     Some often needed tool-functions
23  * @author    Michael Beck
24  * @version   $Id$
25  */
26 #include "config.h"
27
28 #include "pset.h"
29
30 #include <stdlib.h>
31 #include "irnode_t.h"
32 #include "irbackedge_t.h"
33 #include "irtools.h"
34 #include "irprintf.h"
35 #include "irpass_t.h"
36 #include "iropt_t.h"
37
38 void firm_clear_link(ir_node *n, void *env)
39 {
40         (void) env;
41         set_irn_link(n, NULL);
42 }
43
44 void firm_clear_node_and_phi_links(ir_node *n, void *env)
45 {
46         (void) env;
47         set_irn_link(n, NULL);
48         if (is_Block(n))
49                 set_Block_phis(n, NULL);
50         else if (is_Phi(n))
51                 set_Phi_next(n, NULL);
52 }
53
54 void copy_irn_to_irg(ir_node *n, ir_graph *irg)
55 {
56         ir_op *op = get_irn_op(n);
57         ir_graph *old_irg;
58         ir_node *nn = NULL;
59
60         /* do not copy standard nodes */
61         if (op == op_Bad)
62                 nn = get_irg_bad(irg);
63         else if (op == op_NoMem)
64                 n = get_irg_no_mem(irg);
65         else if (op == op_Block) {
66                 old_irg = get_irn_irg(n);
67
68                 if (n == get_irg_start_block(old_irg))
69                         nn = get_irg_start_block(irg);
70                 else if (n == get_irg_end_block(old_irg))
71                         nn = get_irg_end_block(irg);
72         }
73         else if (op == op_Start)
74                 nn = get_irg_start(irg);
75         else if (op == op_End)
76                 nn = get_irg_end(irg);
77         else if (op == op_Proj) {
78                 old_irg = get_irn_irg(n);
79
80                 if (n == get_irg_initial_exec(old_irg))
81                         nn = get_irg_initial_exec(irg);
82                 else if (n == get_irg_frame(old_irg))
83                         nn = get_irg_frame(irg);
84                 else if (n == get_irg_initial_mem(old_irg))
85                         nn = get_irg_initial_mem(irg);
86                 else if (n == get_irg_args(old_irg))
87                         nn = get_irg_args(irg);
88         }
89
90         if (nn) {
91                 set_irn_link(n, nn);
92                 return;
93         }
94
95         nn = new_ir_node(get_irn_dbg_info(n),
96                          irg,
97                          NULL,            /* no block yet, will be set later */
98                          op,
99                          get_irn_mode(n),
100                          get_irn_arity(n),
101                          get_irn_in(n) + 1);
102
103
104         /* Copy the attributes.  These might point to additional data.  If this
105            was allocated on the old obstack the pointers now are dangling.  This
106            frees e.g. the memory of the graph_arr allocated in new_immBlock. */
107         copy_node_attr(irg, n, nn);
108         set_irn_link(n, nn);
109
110         /* fix the irg for nodes containing a reference to it */
111         if (ir_has_irg_ref(nn)) {
112                 nn->attr.block.irg.irg = irg;
113         }
114 }
115
116 ir_node *irn_copy_into_irg(const ir_node *node, ir_graph *irg)
117 {
118         ir_node  *block = NULL;
119         ir_op    *op    = get_irn_op(node);
120         int       arity = get_irn_arity(node);
121         dbg_info *dbgi  = get_irn_dbg_info(node);
122         ir_mode  *mode  = get_irn_mode(node);
123         ir_node  *res;
124         int       n_deps;
125         int       i;
126
127         if (op != op_Block)
128                 block = get_nodes_block(node);
129
130         if (op->opar == oparity_dynamic) {
131                 int i;
132                 res = new_ir_node(dbgi, irg, block, op, mode, -1, NULL);
133                 for (i = 0; i < arity; ++i) {
134                         ir_node *in = get_irn_n(node, i);
135                         add_irn_n(res, in);
136                 }
137         } else {
138                 ir_node **ins = get_irn_in(node)+1;
139                 res = new_ir_node(dbgi, irg, block, op, mode, arity, ins);
140         }
141
142         /* copy the attributes */
143         copy_node_attr(irg, node, res);
144
145         /* duplicate dependency edges */
146         n_deps = get_irn_deps(node);
147         for (i = 0; i < n_deps; ++i) {
148                 ir_node *dep = get_irn_dep(node, i);
149                 add_irn_dep(res, dep);
150         }
151
152         return res;
153 }
154
155 ir_node *exact_copy(const ir_node *node)
156 {
157         return irn_copy_into_irg(node, get_irn_irg(node));
158 }
159
160 static ir_node *get_new_node(const ir_node *old_node)
161 {
162         return (ir_node*) get_irn_link(old_node);
163 }
164
165 void irn_rewire_inputs(ir_node *node)
166 {
167         ir_node *new_node;
168         int      arity;
169         int      i;
170
171         new_node = get_new_node(node);
172
173         if (!is_Block(node)) {
174                 ir_node *block     = get_nodes_block(node);
175                 ir_node *new_block = get_new_node(block);
176                 set_nodes_block(new_node, new_block);
177         }
178
179         arity = get_irn_arity(new_node);
180         for (i = 0; i < arity; ++i) {
181                 ir_node *in     = get_irn_n(node, i);
182                 ir_node *new_in = get_new_node(in);
183                 set_irn_n(new_node, i, new_in);
184         }
185
186         /* Now the new node is complete. We can add it to the hash table for CSE. */
187         add_identities(new_node);
188 }
189
190 void firm_pset_dump(pset *set)
191 {
192         void *obj;
193
194         foreach_pset(set, obj) {
195                 ir_fprintf(stderr, "%+F\n", obj);
196         }
197 }