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