f8833515cf48bd65f70a0ce9e0bc0ff0014d0cb4
[libfirm] / ir / ir / irgopt.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Author: Christian Schaefer
5 **
6 **  dead node elemination
7 **  walks one time through the whole graph and copies it into another graph,
8 **  so unreachable nodes will be lost.
9 */
10
11 # include "irgopt.h"
12 # include "irnode.h"
13 # include "iropt.h"
14 # include "irgwalk.h"
15 # include "irgraph.h"
16 # include "ircons.h"
17
18 void
19 optimize_in_place_wrapper (ir_node *n, void *env) {
20   int i;
21   ir_node *optimized;
22
23   /* optimize all sons after recursion, i.e., the sons' sons are
24      optimized already. */
25   for (i = -1; i < get_irn_arity(n); i++) {
26     optimized = optimize_in_place(get_irn_n(n, i));
27     set_irn_n(n, i, optimized);
28   }
29 }
30
31
32 void
33 local_optimize_graph (ir_graph *irg) {
34   ir_graph *rem = current_ir_graph;
35   current_ir_graph = irg;
36
37   /* walk over the graph */
38   irg_walk(irg->end, NULL, optimize_in_place_wrapper, NULL);
39
40   current_ir_graph = rem;
41 }
42
43 /* Remeber the new node in the old node,
44    by using a field that all nodes have. */
45 void *
46 set_new_node (ir_node *old, ir_node *new)
47 {
48   old->in[0] = new;
49   return old;
50 }
51
52 /* Get this new node, before the old node is forgotton.*/
53 ir_node *
54 get_new_node (ir_node * n)
55 {
56   return n->in[0];
57 }
58
59
60
61 /* Create this node on a new obstack. */
62 void
63 copy_node (ir_node *n, void *env) {
64   ir_node * res, a, b;
65
66   if (is_binop(n)) {
67     a = get_binop_left(n);
68     b = get_binop_right(n);
69   } else if (is_unop(n)) {
70     a = get_unop_op(n);
71   }
72
73   switch (get_irn_opcode(n)) {
74   case iro_Block:
75       int i;
76       ir_node **in [get_Block_n_cfgpreds(n)];
77       for (i=0; i <(get_Return_n_res(n)); i++) {
78         in[i] = get_Block_cfgpred (n, i);
79       }
80       res = new_r_Block (current_ir_graph, get_Block_n_cfgpreds(n), in);
81       set_new_node(n, res);
82     break;
83   case iro_Start:
84     res = new_r_Start (current_ir_graph, get_new_node(n));
85     set_new_node(n, res);
86     break;
87   case iro_End:
88     res = new_r_End (current_ir_graph, get_new_node(n));
89     set_new_node(n, res);
90     break;
91   case iro_Jmp:
92     res = new_r_Jmp (current_ir_graph, get_new_node(n));
93     set_new_node(n, res);
94     break;
95   case iro_Cond:
96     res = new_r_Cond (current_ir_graph, get_new_node(n),
97                       get_Cond_selector(n));
98     set_new_node(n, res);
99     break;
100   case iro_Return:
101     {
102       /*CS malloc*/
103       int i;
104       ir_node **in [get_Return_n_res(n)];
105       for (i=0; i <(get_Return_n_res(n)); i++) {
106         in[i] = get_Return_res (n, i);
107       }
108       res = new_r_Return (current_ir_graph, get_new_node(n),
109                           get_Return_mem (n), get_Return_n_res(n), in);
110       set_new_node(n, res);
111     }
112     break;
113   case iro_Raise:
114     res = new_r_Raise (current_ir_graph, get_new_node(n),
115                        get_Raise_mem(n), get_Raise_exoptr(n));
116     set_new_node(n, res);
117     break;
118   case iro_Const:
119     res = new_r_Const (current_ir_graph, get_new_node(n),
120                        get_irn_mode(n), get_Const_tarval(n));
121     set_new_node(n, res);
122     break;
123   case iro_SymConst:
124     {
125       if (get_SymConst_kind(n) == type_tag || get_SymConst_kind(n) == size)
126         {
127           res = new_r_Raise (current_ir_graph, get_new_node(n),
128                              get_SymConst_type(n), get_SymConst_kind (n));
129         }
130       else
131         /* if get_SymConst_kind(n) == linkage_ptr_info */
132         {
133           res = new_r_Raise (current_ir_graph, get_new_node(n),
134                              get_SymConst_ptrinfo(n), get_SymConst_kind (n));
135         }
136     set_new_node(n, res);
137     }
138     break;
139   case iro_Sel:
140     {
141       int i;
142       ir_node **in [get_Sel_n_index(n)];
143       for (i=0; i <(get_Sel_n_index(n)); i++) {
144         in[i] = get_Sel_index (n, i);
145       }
146       res = new_r_Sel (current_ir_graph, get_new_node(n),
147                        get_Sel_mem(n), get_Sel_ptr(n), get_Sel_n_index(n),
148                        in, get_Sel_entity(n));
149       set_new_node(n, res);
150     }
151     break;
152   case  iro_Call:
153     {
154       int i;
155       ir_node **in [get_Call_arity(n)];
156       for (i=0; i <(get_Call_arity(n)); i++) {
157         in[i] = get_Call_param (n, i);
158       }
159       res = new_r_Call (current_ir_graph, get_new_node(n), get_Call_mem(n),
160                         get_Call_ptr(n), get_Call_arity(n),
161                         in, get_Call_type (n));
162       set_new_node(n, res);
163     }
164     break;
165   case iro_Add:
166     res = new_r_Add (current_ir_graph, get_new_node(n),
167                      get_new_node(a),
168                      get_new_node(b), get_irn_mode(n));
169     set_new_node(n, res);
170     break;
171   case iro_Sub:
172     res = new_r_Sub (current_ir_graph, get_new_node(get_nodes_block(n)),
173                      get_new_node(a),
174                      get_new_node(b), get_irn_mode(n));
175     set_new_node(n, res);
176     break;
177   case iro_Minus:
178     res = new_r_Minus (current_ir_graph, get_new_node(n), get_new_node(a),
179                        get_irn_mode(n));
180     set_new_node(n, res);
181     break;
182   case iro_Mul:
183     break;
184   case iro_Quot:
185     break;
186   case iro_DivMod:
187     break;
188   case iro_Div:
189     break;
190   case iro_Mod:
191     break;
192   case iro_Abs:
193     break;
194   case iro_And:
195     break;
196   case iro_Or:
197     break;
198   case iro_Eor:
199     break;
200   case iro_Not:
201     break;
202   case iro_Cmp:
203     break;
204   case iro_Shl:
205     break;
206   case iro_Shr:
207     break;
208   case iro_Shrs:
209     break;
210   case iro_Rot:
211     break;
212   case iro_Conv:
213     break;
214   case iro_Phi:
215     break;
216   case iro_Load:
217     break;
218   case iro_Store:
219     break;
220   case iro_Alloc:
221     break;
222   case iro_Free:
223     break;
224   case iro_Sync:
225     break;
226   case iro_Proj:
227     break;
228   case iro_Tuple:
229     break;
230   case iro_Id:
231     break;
232   case iro_Bad:
233     break;
234   }
235
236 }
237
238
239 void
240 dead_node_elemination(ir_graph *irg) {
241   struct obstack *graveyard_obst;
242   struct obstack *rebirth_obst;
243
244   /* A quiet place, where the old obstack can rest in peace,
245      until it will be cremated. */
246   graveyard_obst = irg->obst;
247
248   /* A new obstack, where the reachable nodes will be copied to. */
249   rebirth_obst = (struct obstack *) xmalloc (sizeof (struct obstack));
250   current_ir_graph->obst = rebirth_obst;
251   obstack_init (current_ir_graph->obst);
252
253   /* Walks the graph once, and at the recursive way do the copy thing.
254      all reachable nodes will be copied to a new obstack. */
255   irg_walk(irg->end, NULL, copy_node, NULL);
256
257   /* Free memory from old unoptimized obstack */
258   xfree (graveyard_obst);
259
260 }