1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
4 ** Author: Christian Schaefer
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.
18 /********************************************************************/
19 /* apply optimizations of iropt to all nodes. */
21 optimize_in_place_wrapper (ir_node *n, void *env) {
25 /* optimize all sons after recursion, i.e., the sons' sons are
27 for (i = -1; i < get_irn_arity(n); i++) {
28 optimized = optimize_in_place(get_irn_n(n, i));
29 set_irn_n(n, i, optimized);
35 local_optimize_graph (ir_graph *irg) {
36 ir_graph *rem = current_ir_graph;
37 current_ir_graph = irg;
39 /* walk over the graph */
40 irg_walk(irg->end, NULL, optimize_in_place_wrapper, NULL);
42 current_ir_graph = rem;
45 /********************************************************************/
46 /* Routines for dead node elimination / copying garbage collection */
49 /* Remeber the new node in the old node,
50 by using a field that all nodes have. */
52 set_new_node (ir_node *old, ir_node *new)
58 /* Get this new node, before the old node is forgotton.*/
60 get_new_node (ir_node * n)
70 /* Create this node on a new obstack. */
72 copy_node (ir_node *n, void *env) {
81 a = get_binop_left(n);
82 b = get_binop_right(n);
83 } else if (is_unop(n)) {
87 switch (get_irn_opcode(n)) {
90 ir_node **in = get_Block_cfgpred_arr(n);
91 for (i = 0; i < get_Block_n_cfgpreds(n); i++)
92 set_Block_cfgpred(n, i, get_new_node(get_Block_cfgpred(n, i)));
93 res = new_r_Block (current_ir_graph, get_Block_n_cfgpreds(n), in);
97 res = new_r_Start (current_ir_graph, get_new_node(get_nodes_Block(n)));
100 res = new_r_End (current_ir_graph, get_new_node(get_nodes_Block(n)));
101 current_ir_graph -> end = res;
102 current_ir_graph -> end_block = get_new_node(get_nodes_Block(n));
105 res = new_r_Jmp (current_ir_graph, get_new_node(get_nodes_Block(n)));
108 res = new_r_Cond (current_ir_graph, get_new_node(get_nodes_Block(n)),
109 get_new_node(get_Cond_selector(n)));
114 in = get_Return_res_arr(n);
115 for (i = 0; i < get_Return_n_res(n); i++)
116 set_Return_res(n, i, get_new_node(get_Return_res(n, i)));
117 res = new_r_Return (current_ir_graph, get_new_node(get_nodes_Block(n)),
118 get_new_node(get_Return_mem(n)),
119 get_Return_n_res(n), in);
123 res = new_r_Raise (current_ir_graph, get_new_node(get_nodes_Block(n)),
124 get_new_node(get_Raise_mem(n)),
125 get_new_node(get_Raise_exo_ptr(n)));
128 res = new_r_Const (current_ir_graph, get_new_node(get_nodes_Block(n)),
129 get_irn_mode(n), get_Const_tarval(n));
133 type_or_id *value = NULL;
135 if ((get_SymConst_kind(n)==type_tag) || (get_SymConst_kind(n)==size))
138 value = (type_or_id *) get_SymConst_type(n);
142 if (get_SymConst_kind(n)==linkage_ptr_info)
144 value = (type_or_id *) get_SymConst_ptrinfo(n);
147 res = new_r_SymConst (current_ir_graph, get_new_node(get_nodes_Block(n)),
148 value, get_SymConst_kind (n));
153 ir_node **in = get_Sel_index_arr(n);
154 res = new_r_Sel (current_ir_graph, get_new_node(get_nodes_Block(n)),
155 get_new_node(get_Sel_mem(n)),
156 get_new_node(get_Sel_ptr(n)), get_Sel_n_index(n),
157 in, get_Sel_entity(n));
162 ir_node **in = get_Call_param_arr(n);
163 res = new_r_Call (current_ir_graph, get_new_node(get_nodes_Block(n)),
164 get_new_node(get_Call_mem(n)),
165 get_new_node(get_Call_ptr(n)), get_Call_arity(n),
166 in, get_Call_type (n));
170 res = new_r_Add (current_ir_graph, get_new_node(get_nodes_Block(n)),
171 get_new_node(a), get_new_node(b), get_irn_mode(n));
175 res = new_r_Sub (current_ir_graph, get_new_node(get_nodes_Block(n)),
176 get_new_node(a), get_new_node(b), get_irn_mode(n));
180 res = new_r_Minus (current_ir_graph, get_new_node(get_nodes_Block(n)),
181 get_new_node(a), get_irn_mode(n));
184 res = new_r_Mul (current_ir_graph, get_new_node(get_nodes_Block(n)),
185 get_new_node(a), get_new_node(b), get_irn_mode(n));
188 res = new_r_Quot (current_ir_graph, get_new_node(get_nodes_Block(n)),
189 get_new_node(get_Quot_mem(n)), get_new_node(a),
193 res = new_r_DivMod (current_ir_graph, get_new_node(get_nodes_Block(n)),
194 get_new_node(get_DivMod_mem(n)), get_new_node(a),
198 res = new_r_Div (current_ir_graph, get_new_node(get_nodes_Block(n)),
199 get_new_node(get_Div_mem(n)), get_new_node(a),
203 res = new_r_Mod (current_ir_graph, get_new_node(get_nodes_Block(n)),
204 get_new_node(get_Mod_mem(n)), get_new_node(a),
208 res = new_r_Abs (current_ir_graph, get_new_node(get_nodes_Block(n)),
209 get_new_node(get_Abs_op(n)), get_irn_mode(n));
212 res = new_r_And (current_ir_graph, get_new_node(get_nodes_Block(n)),
213 get_new_node(a), get_new_node(b), get_irn_mode(n));
216 res = new_r_Or (current_ir_graph, get_new_node(get_nodes_Block(n)),
217 get_new_node(a), get_new_node(b), get_irn_mode(n));
220 res = new_r_Eor (current_ir_graph, get_new_node(get_nodes_Block(n)),
221 get_new_node(a), get_new_node(b), get_irn_mode(n));
224 res = new_r_Not (current_ir_graph, get_new_node(get_nodes_Block(n)),
225 get_new_node(get_Not_op(n)), get_irn_mode(n));
228 res = new_r_Cmp (current_ir_graph, get_new_node(get_nodes_Block(n)),
229 get_new_node(get_Cmp_left(n)),
230 get_new_node(get_Cmp_right(n)));
233 res = new_r_Shl (current_ir_graph, get_new_node(get_nodes_Block(n)),
234 get_new_node(get_Shl_left(n)),
235 get_new_node(get_Shl_right(n)), get_irn_mode(n));
238 res = new_r_Shr (current_ir_graph, get_new_node(get_nodes_Block(n)),
239 get_new_node(get_Shr_left(n)),
240 get_new_node(get_Shr_right(n)), get_irn_mode(n));
243 res = new_r_Shrs (current_ir_graph, get_new_node(get_nodes_Block(n)),
244 get_new_node(get_Shrs_left(n)),
245 get_new_node(get_Shrs_right(n)), get_irn_mode(n));
248 res = new_r_Rot (current_ir_graph, get_new_node(get_nodes_Block(n)),
249 get_new_node(get_Rot_left(n)),
250 get_new_node(get_Rot_right(n)), get_irn_mode(n));
253 res = new_r_Conv (current_ir_graph, get_new_node(get_nodes_Block(n)),
254 get_new_node(get_Conv_op(n)),
259 ir_node **in = get_Phi_preds_arr(n);
260 res = new_r_Phi (current_ir_graph, get_new_node(get_nodes_Block(n)),
261 get_Phi_n_preds(n), in, get_irn_mode(n));
265 res = new_r_Load (current_ir_graph, get_new_node(get_nodes_Block(n)),
266 get_new_node(get_Load_mem(n)),
267 get_new_node(get_Load_ptr(n)));
270 res = new_r_Store (current_ir_graph, get_new_node(get_nodes_Block(n)),
271 get_new_node(get_Store_mem(n)),
272 get_new_node(get_Store_ptr(n)),
273 get_new_node(get_Store_value(n)));
276 res = new_r_Alloc (current_ir_graph, get_new_node(get_nodes_Block(n)),
277 get_new_node(get_Alloc_mem(n)),
278 get_new_node(get_Alloc_size(n)),
279 get_Alloc_type(n), get_Alloc_where(n));
283 res = new_r_Free (current_ir_graph, get_new_node(get_nodes_Block(n)),
284 get_new_node(get_Free_mem(n)),
285 get_new_node(get_Free_ptr(n)),
286 get_new_node(get_Free_size(n)), get_Free_type(n));
290 ir_node **in = get_Sync_preds_arr(n);
291 res = new_r_Sync (current_ir_graph, get_new_node(get_nodes_Block(n)),
292 get_Sync_n_preds(n), in);
296 res = new_r_Proj (current_ir_graph, get_new_node(get_nodes_Block(n)),
297 get_new_node(get_Proj_pred(n)), get_irn_mode(n),
302 ir_node **in = get_Tuple_preds_arr(n);
303 res = new_r_Tuple (current_ir_graph, get_new_node(get_nodes_Block(n)),
304 get_Tuple_n_preds(n), in);
308 res = new_r_Id (current_ir_graph, get_new_node(get_nodes_Block(n)),
309 get_new_node(get_Id_pred(n)), get_irn_mode(n));
312 res = new_r_Bad (get_new_node(get_nodes_Block(n)));
315 set_new_node(n, res);
320 dead_node_elimination(ir_graph *irg) {
321 struct obstack *graveyard_obst=NULL;
322 struct obstack *rebirth_obst;
324 ir_node *old_node, *new_node;
325 ir_graph *rem = current_ir_graph;
326 current_ir_graph = irg;
328 if (get_opt_dead_node_elimination()) {
330 /* A quiet place, where the old obstack can rest in peace,
331 until it will be cremated. */
332 graveyard_obst = irg->obst;
334 /* A new obstack, where the reachable nodes will be copied to. */
335 rebirth_obst = (struct obstack *) xmalloc (sizeof (struct obstack));
336 current_ir_graph->obst = rebirth_obst;
337 obstack_init (current_ir_graph->obst);
339 /* Walks the graph once, and at the recursive way do the copy thing.
340 all reachable nodes will be copied to a new obstack. */
343 printf("Before starting the DEAD NODE ELIMINATION !\n");
345 old_node = irg->start_block;
346 new_node = new_r_Block (current_ir_graph, 0, NULL);
347 irg->start_block = new_node; ;
348 set_new_node (old_node, new_node);
349 set_irn_visited (new_node, get_irg_visited(current_ir_graph)+1);
350 /*CS Start node und alle Proj nodes muessen hier per hand eingetragen
353 irg_walk(irg->end, NULL, copy_node, NULL);
355 printf("After the DEAD NODE ELIMINATION !\n");
357 /* Free memory from old unoptimized obstack */
358 xfree (graveyard_obst);
361 /* Free memory from old unoptimized obstack */
362 xfree (graveyard_obst);
364 current_ir_graph = rem;