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