Now bipartite matching can be used for pre-coloring restricted cliques after a perm.
[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 blocks */
111         if (is_Block(nn)) {
112                 nn->attr.block.irg.irg = irg;
113
114                 /* we cannot allow blocks WITHOUT macroblock input */
115                 set_Block_MacroBlock(nn, get_Block_MacroBlock(n));
116         }
117 }
118
119 ir_node *irn_copy_into_irg(const ir_node *node, ir_graph *irg)
120 {
121         ir_node  *block = NULL;
122         ir_op    *op    = get_irn_op(node);
123         int       arity = get_irn_arity(node);
124         dbg_info *dbgi  = get_irn_dbg_info(node);
125         ir_mode  *mode  = get_irn_mode(node);
126         ir_node  *res;
127         int       n_deps;
128         int       i;
129
130         if (op != op_Block)
131                 block = get_nodes_block(node);
132
133         if (op->opar == oparity_dynamic) {
134                 int i;
135                 res = new_ir_node(dbgi, irg, block, op, mode, -1, NULL);
136                 for (i = 0; i < arity; ++i) {
137                         ir_node *in = get_irn_n(node, i);
138                         add_irn_n(res, in);
139                 }
140         } else {
141                 ir_node **ins = get_irn_in(node)+1;
142                 res = new_ir_node(dbgi, irg, block, op, mode, arity, ins);
143         }
144
145         /* copy the attributes */
146         copy_node_attr(irg, node, res);
147         if (op == op_Block) {
148                 set_Block_MacroBlock(res, get_Block_MacroBlock(node));
149         }
150
151         /* duplicate dependency edges */
152         n_deps = get_irn_deps(node);
153         for (i = 0; i < n_deps; ++i) {
154                 ir_node *dep = get_irn_dep(node, i);
155                 add_irn_dep(res, dep);
156         }
157
158         return res;
159 }
160
161 ir_node *exact_copy(const ir_node *node)
162 {
163         return irn_copy_into_irg(node, get_irn_irg(node));
164 }
165
166 static ir_node *get_new_node(const ir_node *old_node)
167 {
168         return (ir_node*) get_irn_link(old_node);
169 }
170
171 void irn_rewire_inputs(ir_node *node)
172 {
173         ir_graph *new_irg;
174         ir_node  *new_node;
175         int       arity;
176         int       i;
177
178         new_node = get_new_node(node);
179
180         if (is_Block(node)) {
181                 /* copy the macro block header */
182                 ir_node *mbh = get_Block_MacroBlock(node);
183
184                 /* get the macro block header */
185                 ir_node *nmbh = get_new_node(mbh);
186                 assert(nmbh != NULL);
187                 set_Block_MacroBlock(new_node, nmbh);
188         } else {
189                 ir_node *block     = get_nodes_block(node);
190                 ir_node *new_block = get_new_node(block);
191                 set_nodes_block(new_node, new_block);
192         }
193
194         arity = get_irn_arity(new_node);
195         for (i = 0; i < arity; ++i) {
196                 ir_node *in     = get_irn_n(node, i);
197                 ir_node *new_in = get_new_node(in);
198                 set_irn_n(new_node, i, new_in);
199         }
200
201         /* Now the new node is complete. We can add it to the hash table for CSE. */
202         new_irg = get_irn_irg(new_node);
203         add_identities(new_irg->value_table, new_node);
204 }
205
206 void firm_pset_dump(pset *set)
207 {
208         void *obj;
209
210         foreach_pset(set, obj) {
211                 ir_fprintf(stderr, "%+F\n", obj);
212         }
213 }