4b17a3450bbaab80760527b81831b0b5ec3fe450
[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
37 /* the famous clear_link implementation. */
38 void firm_clear_link(ir_node *n, void *env)
39 {
40         (void) env;
41         set_irn_link(n, NULL);
42 }
43
44 /* the famous clear_node_and_phi_links() implementation. */
45 void firm_clear_node_and_phi_links(ir_node *n, void *env)
46 {
47         (void) env;
48         set_irn_link(n, NULL);
49         if (is_Block(n))
50                 set_Block_phis(n, NULL);
51         else if (is_Phi(n))
52                 set_Phi_next(n, NULL);
53 }
54
55 /*
56  * Copies a node to a new irg. The Ins of the new node point to
57  * the predecessors on the old irg.  n->link points to the new node.
58  *
59  * Does NOT copy standard nodes like Start, End etc that are fixed
60  * in an irg. Instead, the corresponding nodes of the new irg are returned.
61  * Note further, that the new nodes have no block.
62  */
63 void copy_irn_to_irg(ir_node *n, ir_graph *irg)
64 {
65         ir_op *op = get_irn_op(n);
66         ir_graph *old_irg;
67         ir_node *nn = NULL;
68
69         /* do not copy standard nodes */
70         if (op == op_Bad)
71                 nn = get_irg_bad(irg);
72         else if (op == op_NoMem)
73                 n = get_irg_no_mem(irg);
74         else if (op == op_Block) {
75                 old_irg = get_irn_irg(n);
76
77                 if (n == get_irg_start_block(old_irg))
78                         nn = get_irg_start_block(irg);
79                 else if (n == get_irg_end_block(old_irg))
80                         nn = get_irg_end_block(irg);
81         }
82         else if (op == op_Start)
83                 nn = get_irg_start(irg);
84         else if (op == op_End)
85                 nn = get_irg_end(irg);
86         else if (op == op_Proj) {
87                 old_irg = get_irn_irg(n);
88
89                 if (n == get_irg_initial_exec(old_irg))
90                         nn = get_irg_initial_exec(irg);
91                 else if (n == get_irg_frame(old_irg))
92                         nn = get_irg_frame(irg);
93                 else if (n == get_irg_initial_mem(old_irg))
94                         nn = get_irg_initial_mem(irg);
95                 else if (n == get_irg_args(old_irg))
96                         nn = get_irg_args(irg);
97         }
98
99         if (nn) {
100                 set_irn_link(n, nn);
101                 return;
102         }
103
104         nn = new_ir_node(get_irn_dbg_info(n),
105                          irg,
106                          NULL,            /* no block yet, will be set later */
107                          op,
108                          get_irn_mode(n),
109                          get_irn_arity(n),
110                          get_irn_in(n) + 1);
111
112
113         /* Copy the attributes.  These might point to additional data.  If this
114            was allocated on the old obstack the pointers now are dangling.  This
115            frees e.g. the memory of the graph_arr allocated in new_immBlock. */
116         copy_node_attr(irg, n, nn);
117         set_irn_link(n, nn);
118
119         /* fix the irg for blocks */
120         if (is_Block(nn)) {
121                 nn->attr.block.irg.irg = irg;
122
123                 /* we cannot allow blocks WITHOUT macroblock input */
124                 set_Block_MacroBlock(nn, get_Block_MacroBlock(n));
125         }
126 }
127
128 /*
129  * Creates an exact copy of a node.
130  * The copy resides in the same graph in the same block.
131  */
132 ir_node *exact_copy(const ir_node *n)
133 {
134         ir_graph *irg = get_irn_irg(n);
135         ir_node *res, *block = NULL;
136
137         if (is_no_Block(n))
138                 block = get_nodes_block(n);
139
140         res = new_ir_node(get_irn_dbg_info(n),
141                 irg,
142                 block,
143                 get_irn_op(n),
144                 get_irn_mode(n),
145                 get_irn_arity(n),
146                 get_irn_in(n) + 1);
147
148
149         /* Copy the attributes.  These might point to additional data.  If this
150            was allocated on the old obstack the pointers now are dangling.  This
151            frees e.g. the memory of the graph_arr allocated in new_immBlock. */
152         copy_node_attr(irg, n, res);
153
154         if (is_Block(n)) {
155                 set_Block_MacroBlock(res, get_Block_MacroBlock(n));
156         }
157         return res;
158 }
159
160 /*
161  * Dump a pset containing Firm objects.
162  */
163 void firm_pset_dump(pset *set)
164 {
165         void *obj;
166
167         foreach_pset(set, obj) {
168                 ir_fprintf(stderr, "%+F\n", obj);
169         }
170 }