move backend into libfirm
[libfirm] / ir / common / irtools.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/irtools.c
4  * Purpose:     Some often needed tool-functions
5  * Author:      Michael Beck
6  * Modified by:
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1999-2005 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12 #ifdef HAVE_CONFIG_H
13 # include "config.h"
14 #endif
15
16 #include "pset.h"
17
18 #include <stdlib.h>
19 #include "irnode_t.h"
20 #include "irbackedge_t.h"
21 #include "irtools.h"
22 #include "irprintf.h"
23
24 /* the famous clear_link implementation. */
25 void firm_clear_link(ir_node *n, void *env) {
26   set_irn_link(n, NULL);
27 }
28
29 /*
30  * Copies a node to a new irg. The Ins of the new node point to
31  * the predecessors on the old irg.  n->link points to the new node.
32  *
33  * Does NOT copy standard nodes like Start, End etc that are fixed
34  * in an irg. Instead, the corresponding nodes of the new irg are returned.
35  * Note further, that the new nodes have no block.
36  */
37 void
38 copy_irn_to_irg(ir_node *n, ir_graph *irg)
39 {
40   ir_op *op = get_irn_op(n);
41   ir_graph *old_irg;
42   ir_node *nn = NULL;
43
44   /* do not copy standard nodes */
45   if (op == op_Bad)
46     nn = get_irg_bad(irg);
47   else if (op == op_NoMem)
48     n = get_irg_no_mem(irg);
49   else if (op == op_Block) {
50     old_irg = get_irn_irg(n);
51
52     if (n == get_irg_start_block(old_irg))
53       nn = get_irg_start_block(irg);
54     else if (n == get_irg_end_block(old_irg))
55       nn = get_irg_end_block(irg);
56   }
57   else if (op == op_Start)
58     nn = get_irg_start(irg);
59   else if (op == op_End)
60     nn = get_irg_end(irg);
61   else if (op == op_Proj) {
62     old_irg = get_irn_irg(n);
63
64     if (n == get_irg_frame(old_irg))
65       nn = get_irg_frame(irg);
66     else if (n == get_irg_globals(old_irg))
67       nn = get_irg_globals(irg);
68     else if (n == get_irg_initial_mem(old_irg))
69       nn = get_irg_initial_mem(irg);
70     else if (n == get_irg_args(old_irg))
71       nn = get_irg_args(irg);
72   }
73
74   if (nn) {
75     set_irn_link(n, nn);
76     return;
77   }
78
79   nn = new_ir_node(get_irn_dbg_info(n),
80          irg,
81          NULL,            /* no block yet, will be set later */
82          op,
83          get_irn_mode(n),
84          get_irn_arity(n),
85          get_irn_in(n) + 1);
86
87
88   /* Copy the attributes.  These might point to additional data.  If this
89      was allocated on the old obstack the pointers now are dangling.  This
90      frees e.g. the memory of the graph_arr allocated in new_immBlock. */
91   copy_node_attr(n, nn);
92   new_backedge_info(nn);
93   set_irn_link(n, nn);
94
95   /* fix the irg for blocks */
96   if (is_Block(nn))
97     nn->attr.block.irg = irg;
98 }
99
100 /*
101  * Creates an exact copy of a node.
102  * The copy resides in the same graph in the same block.
103  */
104 ir_node *exact_copy(const ir_node *n) {
105   ir_graph *irg = get_irn_irg(n);
106   ir_node *res, *block = NULL;
107
108   if (is_no_Block(n))
109                 block = get_nodes_block(n);
110
111   res = new_ir_node(get_irn_dbg_info(n),
112                     irg,
113                     block,
114                     get_irn_op(n),
115                     get_irn_mode(n),
116                     get_irn_arity(n),
117                     get_irn_in(n) + 1);
118
119
120   /* Copy the attributes.  These might point to additional data.  If this
121      was allocated on the old obstack the pointers now are dangling.  This
122      frees e.g. the memory of the graph_arr allocated in new_immBlock. */
123   copy_node_attr(n, res);
124   new_backedge_info(res);
125   return res;
126 }
127
128 void firm_pset_dump(pset *set)
129 {
130         void *obj;
131
132         foreach_pset(set, obj) {
133                 ir_fprintf(stderr, "%+F\n", obj);
134         }
135 }