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