cc67a354fe71bc7fad869ffb83d6656ce08fb44d
[libfirm] / ir / ir / irgopt.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Author: Christian Schaefer
5 **
6 ** Optimizations for a whole ir graph, i.e., a procedure.
7 */
8
9 # include <assert.h>
10
11 # include "irgopt.h"
12 # include "irnode_t.h"
13 # include "irgraph_t.h"
14 # include "iropt.h"
15 # include "irgwalk.h"
16 # include "ircons.h"
17 # include "misc.h"
18 # include "irgmod.h"
19
20 /********************************************************************/
21 /* apply optimizations of iropt to all nodes.                       */
22 /********************************************************************/
23
24 void
25 optimize_in_place_wrapper (ir_node *n, void *env) {
26   int i;
27   ir_node *optimized;
28
29   /* optimize all sons after recursion, i.e., the sons' sons are
30      optimized already. */
31   for (i = -1; i < get_irn_arity(n); i++) {
32     optimized = optimize_in_place(get_irn_n(n, i));
33     set_irn_n(n, i, optimized);
34   }
35 }
36
37 void
38 local_optimize_graph (ir_graph *irg) {
39   ir_graph *rem = current_ir_graph;
40   current_ir_graph = irg;
41
42   /* walk over the graph */
43   irg_walk(irg->end, NULL, optimize_in_place_wrapper, NULL);
44
45   current_ir_graph = rem;
46 }
47
48 /********************************************************************/
49 /* Routines for dead node elimination / copying garbage collection  */
50 /* of the obstack.                                                  */
51 /********************************************************************/
52
53 /* Remeber the new node in the old node by using a field all nodes have. */
54 inline void
55 set_new_node (ir_node *old, ir_node *new)
56 {
57   old->link = new;
58 }
59
60 /* Get this new node, before the old node is forgotton.*/
61 inline ir_node *
62 get_new_node (ir_node * n)
63 {
64   return n->link;
65 }
66
67
68 /* We use the block_visited flag to mark that we have computed the
69    number of useful predecessors for this block.
70    Further we encode the new arity in this flag.  Remembering the arity is
71    useful, as it saves a lot of pointer accesses.  This function is called
72    for all Phi and Block nodes in a Block. */
73 inline int
74 compute_new_arity(ir_node *b) {
75   int i, res;
76   int irg_v, block_v;
77
78   irg_v = get_irg_block_visited(current_ir_graph);
79   block_v = get_Block_block_visited(b);
80   if (block_v >= irg_v) {
81     /* we computed the number of preds for this block and saved it in the
82        block_v flag */
83     return block_v - irg_v;
84   } else {
85     /* compute the number of good predecessors */
86     res = get_irn_arity(b);
87     for (i = 0; i < get_irn_arity(b); i++)
88       if (get_irn_opcode(get_irn_n(b, i)) == iro_Bad) res--;
89     /* save it in the flag. */
90     set_Block_block_visited(b, irg_v + res);
91     return res;
92   }
93 }
94
95 /* Copies the node to the new obstack. The Ins of the new node point to
96    the predecessors on the old obstack.  n->link points to the new node.
97    For Phi and Block nodes the function allocate in arrays with an arity
98    only for useful predecessors.  The arity is determined by counting
99    the non-bad predecessors of the block. */
100 inline void
101 copy_node (ir_node *n, void *env) {
102   ir_node *nn, *block;
103   int new_arity;
104
105   if (get_irn_opcode(n) == iro_Block) {
106     block = NULL;
107     new_arity = compute_new_arity(n);
108   } else {
109     block = get_nodes_Block(n);
110     if (get_irn_opcode(n) == iro_Phi) {
111       new_arity = compute_new_arity(block);
112     } else {
113       new_arity = get_irn_arity(n);
114     }
115   }
116   nn = new_ir_node(current_ir_graph,
117                    block,
118                    get_irn_op(n),
119                    get_irn_mode(n),
120                    new_arity,
121                    get_irn_in(n));
122   copy_attrs(n, nn);
123   set_new_node(n, nn);
124 }
125
126 /* Copies new predecessors of old node to new node remembered in link.
127    Spare the Bad predecessors of Phi and Block nodes. */
128 inline void
129 copy_preds (ir_node *n, void *env) {
130   ir_node *nn, *block, *on;
131   int i, j;
132
133   nn = get_new_node(n);
134
135   if (get_irn_opcode(n) == iro_Block) {
136     /* Don't copy Bad nodes. */
137     j = 0;
138     for (i = 0; i < get_irn_arity(n); i++)
139       if (get_irn_opcode(get_irn_n(n, i)) != iro_Bad) {
140         set_irn_n (nn, j, get_new_node(get_irn_n(n, i)));
141         j++;
142       }
143     /* repair the block visited flag from above misuse */
144     set_Block_block_visited(nn, 0);
145     /* Local optimization could not merge two subsequent blocks if
146        in array contained Bads.  Now it's possible.  *
147     on = optimize_in_place(nn);
148     if (nn != on) exchange(nn, on);*/
149   } else if (get_irn_opcode(n) == iro_Phi) {
150     /* Don't copy node if corresponding predecessor in block is Bad.
151        The Block itself should not be Bad. */
152     block = get_nodes_Block(n);
153     set_irn_n (nn, -1, get_new_node(block));
154     j = 0;
155     for (i = 0; i < get_irn_arity(n); i++)
156       if (get_irn_opcode(get_irn_n(block, i)) != iro_Bad) {
157         set_irn_n (nn, j, get_new_node(get_irn_n(n, i)));
158         j++;
159       }
160     /* Compacting the Phi's ins might generate Phis with only one
161        predecessor. *
162     if (get_irn_arity(n) == 1)
163     exchange(n, get_irn_n(n, 0)); */
164   } else {
165     for (i = -1; i < get_irn_arity(n); i++)
166       set_irn_n (nn, i, get_new_node(get_irn_n(n, i)));
167   }
168 }
169
170 /* Copies the graph reachable from current_ir_graph->end to the obstack
171    in current_ir_graph.
172    Then fixes the fields in current_ir_graph containing nodes of the
173    graph.  */
174 void
175 copy_graph () {
176   /* Not all nodes remembered in current_ir_graph might be reachable
177      from the end node.  Assure their link is set to NULL so that
178      we can test whether new nodes have been computed. */
179   set_irn_link(get_irg_frame  (current_ir_graph), NULL);
180   set_irn_link(get_irg_globals(current_ir_graph), NULL);
181   set_irn_link(get_irg_args   (current_ir_graph), NULL);
182
183   /* we use the block walk flag for removing Bads from Blocks ins. */
184   inc_irg_block_visited(current_ir_graph);
185
186   /* copy the graph */
187   irg_walk(get_irg_end(current_ir_graph), copy_node, copy_preds, NULL);
188
189   /* fix the fields in current_ir_graph */
190   set_irg_end        (current_ir_graph, get_new_node(get_irg_end(current_ir_graph)));
191   set_irg_end_block  (current_ir_graph, get_new_node(get_irg_end_block(current_ir_graph)));
192   if (get_irn_link(get_irg_frame(current_ir_graph)) == NULL)
193     irg_walk(get_irg_frame(current_ir_graph), copy_node, copy_preds, NULL);
194   if (get_irn_link(get_irg_globals(current_ir_graph)) == NULL)
195     irg_walk(get_irg_globals(current_ir_graph), copy_node, copy_preds, NULL);
196   if (get_irn_link(get_irg_args(current_ir_graph)) == NULL)
197     irg_walk(get_irg_args(current_ir_graph), copy_node, copy_preds, NULL);
198   set_irg_start  (current_ir_graph, get_new_node(get_irg_start(current_ir_graph)));
199   set_irg_start_block(current_ir_graph,
200                       get_new_node(get_irg_start_block(current_ir_graph)));
201   set_irg_frame  (current_ir_graph, get_new_node(get_irg_frame(current_ir_graph)));
202   set_irg_globals(current_ir_graph, get_new_node(get_irg_globals(current_ir_graph)));
203   set_irg_args   (current_ir_graph, get_new_node(get_irg_args(current_ir_graph)));
204   if (get_irn_link(get_irg_bad(current_ir_graph)) == NULL) {
205     copy_node(get_irg_bad(current_ir_graph), NULL);
206     copy_preds(get_irg_bad(current_ir_graph), NULL);
207   }
208   set_irg_bad(current_ir_graph, get_new_node(get_irg_bad(current_ir_graph)));
209 }
210
211
212 /* Amroq call this emigrate() */
213 void
214 dead_node_elimination(ir_graph *irg) {
215   ir_graph *rem;
216   struct obstack *graveyard_obst = NULL;
217   struct obstack *rebirth_obst   = NULL;
218
219   /* Remember external state of current_ir_graph. */
220   rem = current_ir_graph;
221   current_ir_graph = irg;
222
223   if (get_optimize() && get_opt_dead_node_elimination()) {
224
225     /* A quiet place, where the old obstack can rest in peace,
226        until it will be cremated. */
227     graveyard_obst = irg->obst;
228
229     /* A new obstack, where the reachable nodes will be copied to. */
230     rebirth_obst = (struct obstack *) xmalloc (sizeof (struct obstack));
231     current_ir_graph->obst = rebirth_obst;
232     obstack_init (current_ir_graph->obst);
233
234     /* Copy the graph from the old to the new obstack */
235     copy_graph();
236
237     /* Free memory from old unoptimized obstack */
238     obstack_free(graveyard_obst, 0);  /* First empty the obstack ... */
239     xfree (graveyard_obst);           /* ... then free it.           */
240   }
241
242   current_ir_graph = rem;
243 }
244
245
246
247
248
249 #if 0  /* An old implementation */
250
251 /* To break the recursion of the graph walk if there are loops in
252    the graph we have to allocate new nodes for Phis and blocks
253    before descending.  Here we use the old predecessors for the
254    new nodes.  These are replaced by the proper predecessors in
255    copy_node.
256    It turned out that it is not sufficient to just break loops
257    for Phi and Block nodes, as the walker can hit visited but
258    not copied nodes at any point in the graph.
259    A simple fix would be allocating Id's for every node and then
260    exchanging them, but this will cause new dead nodes on the new
261    obstack.
262    So now there is a different implementation more based on the
263    view on the graph as a graph than as a represented program. */
264 void
265 create_dummy (ir_node *n, void *env) {
266   assert (n);
267
268   /* Assure link is set to NULL so we can test whether there is a
269      new node by checking link.
270      set_irn_link(n, NULL); */
271
272   switch (get_irn_opcode(n)) {
273   case iro_Block:
274       set_new_node(n, new_ir_node(current_ir_graph, NULL, op_Block, mode_R,
275                                   get_irn_arity(n), get_irn_in(n)));
276     break;
277   case iro_Phi:
278       set_new_node(n, new_ir_node(current_ir_graph, NULL, op_Phi,
279                                   get_irn_mode(n),
280                                   get_irn_arity(n), get_irn_in(n)));
281     break;
282   default: {}
283   } /* end switch (get_irn_opcode(n)) */
284 }
285
286 /* Create a copy of this node on a new obstack. */
287 void
288 copy_node2 (ir_node *n, void *env) {
289   ir_node *res = NULL;
290   ir_node *a = NULL;
291   ir_node *b = NULL;
292   int i = 0;
293
294   assert (n);
295   DDMSG2(n);
296
297   if (is_binop(n)) {
298     a = get_binop_left(n);
299     b = get_binop_right(n);
300   } else if (is_unop(n)) {
301     a = get_unop_op(n);
302   }
303
304   switch (get_irn_opcode(n)) {
305   case iro_Block:
306     {
307       res = get_new_node(n);
308       assert(res);
309       for (i = 0; i < get_Block_n_cfgpreds(n); i++)
310         set_Block_cfgpred(res, i, get_new_node(get_Block_cfgpred(n, i)));
311       set_Block_matured(res, 1);
312     }
313     break;
314   case iro_Start:
315     res = new_r_Start (current_ir_graph, get_new_node(get_nodes_Block(n)));
316     break;
317   case iro_End:
318     res = new_r_End (current_ir_graph, get_new_node(get_nodes_Block(n)));
319     current_ir_graph -> end = res;
320     current_ir_graph -> end_block = get_nodes_Block(res);
321     break;
322   case iro_Jmp:
323     res = new_r_Jmp (current_ir_graph, get_new_node(get_nodes_Block(n)));
324     break;
325   case iro_Cond:
326     res = new_r_Cond (current_ir_graph, get_new_node(get_nodes_Block(n)),
327                       get_new_node(get_Cond_selector(n)));
328     break;
329   case iro_Return:
330     {
331       ir_node **in;
332       in = get_Return_res_arr(n);
333       for (i = 0; i < get_Return_n_res(n); i++)
334         set_Return_res(n, i, get_new_node(get_Return_res(n, i)));
335       res = new_r_Return (current_ir_graph,
336                           get_new_node(get_nodes_Block(n)),
337                           get_new_node(get_Return_mem(n)),
338                           get_Return_n_res(n), in);
339     }
340     break;
341   case iro_Raise:
342     res = new_r_Raise (current_ir_graph,
343                        get_new_node(get_nodes_Block(n)),
344                        get_new_node(get_Raise_mem(n)),
345                        get_new_node(get_Raise_exo_ptr(n)));
346     break;
347   case iro_Const:
348     res = new_r_Const (current_ir_graph, get_new_node(get_nodes_Block(n)),
349                        get_irn_mode(n), get_Const_tarval(n));
350     break;
351   case iro_SymConst:
352     {
353       type_or_id_p value = NULL;
354
355       if ((get_SymConst_kind(n)==type_tag) || (get_SymConst_kind(n)==size))
356         {
357
358            value = (type_or_id_p) get_SymConst_type(n);
359         }
360       else
361         {
362           if (get_SymConst_kind(n)==linkage_ptr_info)
363           {
364             value = (type_or_id_p) get_SymConst_ptrinfo(n);
365           }
366         }
367     res = new_r_SymConst (current_ir_graph, get_new_node(get_nodes_Block(n)),
368                           value, get_SymConst_kind (n));
369     }
370     break;
371   case iro_Sel:
372     {
373       ir_node **in = get_Sel_index_arr(n);
374       for (i = 0; i < get_Sel_n_index(n); i++)
375         set_Sel_index(n, i, get_new_node(get_Sel_index(n, i)));
376       res = new_r_Sel (current_ir_graph, get_new_node(get_nodes_Block(n)),
377                        get_new_node(get_Sel_mem(n)),
378                        get_new_node(get_Sel_ptr(n)), get_Sel_n_index(n),
379                        in, get_Sel_entity(n));
380     }
381     break;
382   case  iro_Call:
383     {
384       ir_node **in;
385       in = get_Call_param_arr(n);
386
387       for (i = 0; i < get_Call_arity(n); i++)
388         set_Call_param(n, i, get_new_node(get_Call_param(n, i)));
389       res = new_r_Call (current_ir_graph,
390                         get_new_node(get_nodes_Block(n)),
391                         get_new_node(get_Call_mem(n)),
392                         get_new_node(get_Call_ptr(n)),
393                         get_Call_arity(n), in,
394                         get_Call_type (n));
395     }
396     break;
397   case iro_Add:
398     res = new_r_Add (current_ir_graph, get_new_node(get_nodes_Block(n)),
399                      get_new_node(a), get_new_node(b), get_irn_mode(n));
400     break;
401   case iro_Sub:
402     {
403       res = new_r_Sub (current_ir_graph, get_new_node(get_nodes_Block(n)),
404                        get_new_node(a), get_new_node(b), get_irn_mode(n));
405     }
406     break;
407   case iro_Minus:
408     res = new_r_Minus (current_ir_graph, get_new_node(get_nodes_Block(n)),
409                        get_new_node(a), get_irn_mode(n));
410     break;
411   case iro_Mul:
412     res = new_r_Mul (current_ir_graph, get_new_node(get_nodes_Block(n)),
413                      get_new_node(a), get_new_node(b), get_irn_mode(n));
414     break;
415   case iro_Quot:
416     res = new_r_Quot (current_ir_graph, get_new_node(get_nodes_Block(n)),
417                       get_new_node(get_Quot_mem(n)), get_new_node(a),
418                       get_new_node(b));
419     break;
420   case iro_DivMod:
421     res = new_r_DivMod (current_ir_graph, get_new_node(get_nodes_Block(n)),
422                         get_new_node(get_DivMod_mem(n)), get_new_node(a),
423                         get_new_node(b));
424     break;
425   case iro_Div:
426     res = new_r_Div (current_ir_graph, get_new_node(get_nodes_Block(n)),
427                      get_new_node(get_Div_mem(n)), get_new_node(a),
428                      get_new_node(b));
429     break;
430   case iro_Mod:
431     res = new_r_Mod (current_ir_graph, get_new_node(get_nodes_Block(n)),
432                      get_new_node(get_Mod_mem(n)), get_new_node(a),
433                      get_new_node(b));
434     break;
435   case iro_Abs:
436     res = new_r_Abs (current_ir_graph, get_new_node(get_nodes_Block(n)),
437                      get_new_node(get_Abs_op(n)), get_irn_mode(n));
438     break;
439   case iro_And:
440     res = new_r_And (current_ir_graph, get_new_node(get_nodes_Block(n)),
441                      get_new_node(a), get_new_node(b), get_irn_mode(n));
442     break;
443   case iro_Or:
444     res = new_r_Or (current_ir_graph, get_new_node(get_nodes_Block(n)),
445                     get_new_node(a), get_new_node(b), get_irn_mode(n));
446     break;
447   case iro_Eor:
448     res = new_r_Eor (current_ir_graph, get_new_node(get_nodes_Block(n)),
449                      get_new_node(a), get_new_node(b), get_irn_mode(n));
450     break;
451   case iro_Not:
452     res = new_r_Not (current_ir_graph, get_new_node(get_nodes_Block(n)),
453                      get_new_node(get_Not_op(n)), get_irn_mode(n));
454     break;
455   case iro_Cmp:
456     res = new_r_Cmp (current_ir_graph,
457                      get_new_node(get_nodes_Block(n)),
458                      get_new_node(get_Cmp_left(n)),
459                      get_new_node(get_Cmp_right(n)));
460     break;
461   case iro_Shl:
462     res = new_r_Shl (current_ir_graph, get_new_node(get_nodes_Block(n)),
463                      get_new_node(get_Shl_left(n)),
464                      get_new_node(get_Shl_right(n)), get_irn_mode(n));
465     break;
466   case iro_Shr:
467     res = new_r_Shr (current_ir_graph, get_new_node(get_nodes_Block(n)),
468                      get_new_node(get_Shr_left(n)),
469                      get_new_node(get_Shr_right(n)), get_irn_mode(n));
470     break;
471   case iro_Shrs:
472     res = new_r_Shrs (current_ir_graph, get_new_node(get_nodes_Block(n)),
473                       get_new_node(get_Shrs_left(n)),
474                       get_new_node(get_Shrs_right(n)), get_irn_mode(n));
475     break;
476   case iro_Rot:
477     res = new_r_Rot (current_ir_graph, get_new_node(get_nodes_Block(n)),
478                      get_new_node(get_Rot_left(n)),
479                      get_new_node(get_Rot_right(n)), get_irn_mode(n));
480     break;
481   case iro_Conv:
482     res = new_r_Conv (current_ir_graph, get_new_node(get_nodes_Block(n)),
483                       get_new_node(get_Conv_op(n)),
484                       get_irn_mode(n));
485     break;
486   case iro_Phi:
487     {
488       res = get_new_node(n);
489       for (i = 0; i < get_Phi_n_preds(n); i++)
490         set_Phi_pred(res, i, get_new_node(get_Phi_pred(n, i)));
491       set_nodes_Block(res, get_new_node(get_nodes_Block(n)));
492     }
493     break;
494   case iro_Load:
495     res = new_r_Load (current_ir_graph, get_new_node(get_nodes_Block(n)),
496                       get_new_node(get_Load_mem(n)),
497                       get_new_node(get_Load_ptr(n)));
498     break;
499   case iro_Store:
500     res = new_r_Store (current_ir_graph, get_new_node(get_nodes_Block(n)),
501                        get_new_node(get_Store_mem(n)),
502                        get_new_node(get_Store_ptr(n)),
503                        get_new_node(get_Store_value(n)));
504     break;
505   case iro_Alloc:
506     res = new_r_Alloc (current_ir_graph, get_new_node(get_nodes_Block(n)),
507                        get_new_node(get_Alloc_mem(n)),
508                        get_new_node(get_Alloc_size(n)),
509                        get_Alloc_type(n), get_Alloc_where(n));
510
511     break;
512   case iro_Free:
513     res = new_r_Free (current_ir_graph, get_new_node(get_nodes_Block(n)),
514                       get_new_node(get_Free_mem(n)),
515                       get_new_node(get_Free_ptr(n)),
516                       get_new_node(get_Free_size(n)), get_Free_type(n));
517     break;
518   case iro_Sync:
519     {
520       ir_node **in = get_Sync_preds_arr(n);
521       for (i = 0; i < get_Sync_n_preds(n); i++)
522         set_Sync_pred(n, i, get_new_node(get_Sync_pred(n, i)));
523       res = new_r_Sync (current_ir_graph, get_new_node(get_nodes_Block(n)),
524                         get_Sync_n_preds(n), in);
525     }
526     break;
527   case iro_Proj: {
528     res = new_r_Proj (current_ir_graph, get_new_node(get_nodes_Block(n)),
529                       get_new_node(get_Proj_pred(n)), get_irn_mode(n),
530                       get_Proj_proj(n));
531   }
532     break;
533   case iro_Tuple:
534     {
535       ir_node **in = get_Tuple_preds_arr(n);
536       for (i = 0; i < get_Tuple_n_preds(n); i++)
537         set_Tuple_pred(n, i, get_new_node(get_Tuple_pred(n, i)));
538       res = new_r_Tuple (current_ir_graph, get_new_node(get_nodes_Block(n)),
539                          get_Tuple_n_preds(n), in);
540     }
541     break;
542   case iro_Id:
543     res = get_new_node(get_Id_pred(n));
544     break;
545   case iro_Bad:
546     res = new_r_Bad ();
547     break;
548   }
549   /* @@@ Here we could call optimize()!! Not necessary, called in constructor anyways. */
550   set_new_node(n, res);
551   printf(" "); DDMSG2(res);
552 }
553
554 void
555 copy_graph2 () {
556   ir_node *old_node, *new_node, *projX;
557   ir_graph *irg = current_ir_graph;
558
559   /*CS*/
560   printf("Before starting the DEAD NODE ELIMINATION !\n");
561
562   /* Copy nodes remembered in irg fields first.
563      The optimization contains tests against these fields, e.g., not
564      to optimize the start block away.  Therefore these fields have to
565      be fixed first.
566      Further setting these fields in copy_node would impose additional
567      tests for all nodes of a kind.
568      Predict the visited flag the walker will use! */
569   /* Copy the start Block node.  Get the ProjX of the Start node, that is
570      predecessor of the start Block.  We have to break the cycle and fix it
571      later.  We use the old in array as placeholder. */
572   old_node = irg->start_block;
573   new_node = new_r_Block (current_ir_graph, get_Block_n_cfgpreds(old_node),
574                           get_Block_cfgpred_arr(old_node));
575   /* new_r_Block calls no optimization --> save */
576   projX = get_Block_cfgpred(old_node, 0);
577   irg->start_block = new_node;
578   set_new_node (old_node, new_node);
579   set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
580   /* Copy the Start node */
581   old_node = irg->start;
582   new_node = new_r_Start (current_ir_graph, irg->start_block);
583   irg->start = new_node;
584   set_new_node (old_node, new_node);
585   set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
586   /* Copy the Bad node */
587   old_node = irg->bad;
588   new_node = new_ir_node (irg, irg->start_block, op_Bad, mode_T, 0, NULL);
589   irg->bad = new_node;
590   set_new_node (old_node, new_node);
591   set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
592   /* Copy the Projs for the Start's results. */
593   old_node = projX;
594   new_node = new_r_Proj (irg, irg->start_block, irg->start, mode_X, pns_initial_exec);
595   set_Block_cfgpred(irg->start_block, 0, new_node);
596   set_new_node (old_node, new_node);
597   set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
598
599   old_node = irg->frame;
600   new_node = new_r_Proj (irg, irg->start_block, irg->start, mode_p, pns_frame_base);
601   irg->frame = new_node;
602   set_new_node (old_node, new_node);
603   set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
604
605   old_node = irg->globals;
606   new_node = new_r_Proj (irg, irg->start_block, irg->start, mode_p, pns_globals);
607   irg->globals = new_node;
608   set_new_node (old_node, new_node);
609   set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
610
611   old_node = irg->args;
612   new_node = new_r_Proj (irg, irg->start_block, irg->start, mode_T, pns_args);
613   irg->args = new_node;
614   set_new_node (old_node, new_node);
615   set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
616
617   /* Walks the graph once, and at the recursive way do the copy thing.
618      all reachable nodes will be copied to a new obstack. */
619   irg_walk(irg->end, create_dummy, copy_node2, NULL);
620
621   /*CS*/
622   printf("After DEAD NODE ELIMINATION !\n");
623 }
624 #endif