*** empty log message ***
[libfirm] / ir / ir / ircons.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Authors: Martin Trapp, Christian Schaefer
5 **
6 ** ircons.c: basic and more detailed irnode constructors
7 **           store, block and parameter administration.
8 ** Adapted to extended FIRM nodes (exceptions...) and commented
9 **   by Goetz Lindenmaier
10 */
11
12 #ifdef HAVE_CONFIG_H
13 # include <config.h>
14 #endif
15
16 # include "irgraph_t.h"
17 # include "irnode_t.h"
18 # include "irmode_t.h"
19 # include "ircons.h"
20 # include "common.h"
21 # include "irvrfy.h"
22 # include "irop.h"
23 # include "iropt.h"
24 # include "irgmod.h"
25 # include "array.h"
26 /* memset belongs to string.h */
27 # include "string.h"
28
29 #if USE_EXPICIT_PHI_IN_STACK
30 /* A stack needed for the automatic Phi node construction in constructor
31    Phi_in. Redefinition in irgraph.c!! */
32 struct Phi_in_stack {
33   ir_node **stack;
34   int       pos;
35 };
36 typedef struct Phi_in_stack Phi_in_stack;
37 #endif
38
39 /*** ******************************************** */
40 /** privat interfaces, for professional use only */
41
42 /* Constructs a Block with a fixed number of predecessors.
43    Does not set current_block.  Can not be used with automatic
44    Phi node construction. */
45 inline ir_node *
46 new_r_Block (ir_graph *irg,  int arity, ir_node **in)
47 {
48   ir_node *res;
49
50   res = new_ir_node (irg, NULL, op_Block, mode_R, arity, in);
51   set_Block_matured(res, 1);
52   set_Block_block_visited(res, 0);
53
54   irn_vrfy (res);
55   return res;
56 }
57
58 ir_node *
59 new_r_Start (ir_graph *irg, ir_node *block)
60 {
61   ir_node *res;
62
63   res = new_ir_node (irg, block, op_Start, mode_T, 0, NULL);
64
65   irn_vrfy (res);
66   return res;
67 }
68
69 ir_node *
70 new_r_End (ir_graph *irg, ir_node *block)
71 {
72   ir_node *res;
73
74   res = new_ir_node (irg, block, op_End, mode_X, -1, NULL);
75
76   irn_vrfy (res);
77   return res;
78 }
79
80 /* Creates a Phi node with all predecessors.  Calling this constructor
81    is only allowed if the corresponding block is mature.  */
82 ir_node *
83 new_r_Phi (ir_graph *irg, ir_node *block, int arity, ir_node **in, ir_mode *mode)
84 {
85   ir_node *res;
86
87   assert( get_Block_matured(block) );
88   assert( get_irn_arity(block) == arity );
89
90   res = new_ir_node (irg, block, op_Phi, mode, arity, in);
91
92   res = optimize (res);
93   irn_vrfy (res);
94   return res;
95 }
96
97 ir_node *
98 new_r_Const (ir_graph *irg, ir_node *block, ir_mode *mode, tarval *con)
99 {
100   ir_node *res;
101   res = new_ir_node (irg, block, op_Const, mode, 0, NULL);
102   res->attr.con = con;
103   res = optimize (res);
104   irn_vrfy (res);
105
106 #if 0
107   res = local_optimize_newby (res);
108 # endif
109
110   return res;
111 }
112
113 ir_node *
114 new_r_Id (ir_graph *irg, ir_node *block, ir_node *val, ir_mode *mode)
115 {
116   ir_node *in[1] = {val};
117   ir_node *res;
118   res = new_ir_node (irg, block, op_Id, mode, 1, in);
119   res = optimize (res);
120   irn_vrfy (res);
121   return res;
122 }
123
124 ir_node *
125 new_r_Proj (ir_graph *irg, ir_node *block, ir_node *arg, ir_mode *mode,
126             long proj)
127 {
128   ir_node *in[1] = {arg};
129   ir_node *res;
130   res = new_ir_node (irg, block, op_Proj, mode, 1, in);
131   res->attr.proj = proj;
132
133   assert(res);
134   assert(get_Proj_pred(res));
135   assert(get_nodes_Block(get_Proj_pred(res)));
136
137   res = optimize (res);
138
139   irn_vrfy (res);
140   return res;
141
142 }
143
144 ir_node *
145 new_r_defaultProj (ir_graph *irg, ir_node *block, ir_node *arg,
146                    long max_proj)
147 {
148   ir_node *res;
149   assert((arg->op==op_Cond) && (get_irn_mode(arg->in[1]) == mode_I));
150   arg->attr.c.kind = fragmentary;
151   arg->attr.c.default_proj = max_proj;
152   res = new_r_Proj (irg, block, arg, mode_X, max_proj);
153   return res;
154 }
155
156 ir_node *
157 new_r_Conv (ir_graph *irg, ir_node *block, ir_node *op, ir_mode *mode)
158 {
159   ir_node *in[1] = {op};
160   ir_node *res;
161   res = new_ir_node (irg, block, op_Conv, mode, 1, in);
162   res = optimize (res);
163   irn_vrfy (res);
164   return res;
165
166 }
167
168 ir_node *
169 new_r_Tuple (ir_graph *irg, ir_node *block, int arity, ir_node **in)
170 {
171   ir_node *res;
172
173   res = new_ir_node (irg, block, op_Tuple, mode_T, arity, in);
174   res = optimize (res);
175   irn_vrfy (res);
176   return res;
177 }
178
179 inline ir_node *
180 new_r_Add (ir_graph *irg, ir_node *block,
181            ir_node *op1, ir_node *op2, ir_mode *mode)
182 {
183   ir_node *in[2] = {op1, op2};
184   ir_node *res;
185   res = new_ir_node (irg, block, op_Add, mode, 2, in);
186   res = optimize (res);
187   irn_vrfy (res);
188   return res;
189 }
190
191 inline ir_node *
192 new_r_Sub (ir_graph *irg, ir_node *block,
193            ir_node *op1, ir_node *op2, ir_mode *mode)
194 {
195   ir_node *in[2] = {op1, op2};
196   ir_node *res;
197   res = new_ir_node (irg, block, op_Sub, mode, 2, in);
198   res = optimize (res);
199   irn_vrfy (res);
200   return res;
201 }
202
203 inline ir_node *
204 new_r_Minus (ir_graph *irg, ir_node *block,
205              ir_node *op,  ir_mode *mode)
206 {
207   ir_node *in[1] = {op};
208   ir_node *res;
209   res = new_ir_node (irg, block, op_Minus, mode, 1, in);
210   res = optimize (res);
211   irn_vrfy (res);
212   return res;
213 }
214
215 inline ir_node *
216 new_r_Mul (ir_graph *irg, ir_node *block,
217            ir_node *op1, ir_node *op2, ir_mode *mode)
218 {
219   ir_node *in[2] = {op1, op2};
220   ir_node *res;
221   res = new_ir_node (irg, block, op_Mul, mode, 2, in);
222   res = optimize (res);
223   irn_vrfy (res);
224   return res;
225 }
226
227 inline ir_node *
228 new_r_Quot (ir_graph *irg, ir_node *block,
229             ir_node *memop, ir_node *op1, ir_node *op2)
230 {
231   ir_node *in[3] = {memop, op1, op2};
232   ir_node *res;
233   res = new_ir_node (irg, block, op_Quot, mode_T, 3, in);
234   res = optimize (res);
235   irn_vrfy (res);
236   return res;
237 }
238
239 inline ir_node *
240 new_r_DivMod (ir_graph *irg, ir_node *block,
241               ir_node *memop, ir_node *op1, ir_node *op2)
242 {
243   ir_node *in[3] = {memop, op1, op2};
244   ir_node *res;
245   res = new_ir_node (irg, block, op_DivMod, mode_T, 3, in);
246   res = optimize (res);
247   irn_vrfy (res);
248   return res;
249 }
250
251 inline ir_node *
252 new_r_Div (ir_graph *irg, ir_node *block,
253            ir_node *memop, ir_node *op1, ir_node *op2)
254 {
255   ir_node *in[3] = {memop, op1, op2};
256   ir_node *res;
257   res = new_ir_node (irg, block, op_Div, mode_T, 3, in);
258   res = optimize (res);
259   irn_vrfy (res);
260   return res;
261 }
262
263 inline ir_node *
264 new_r_Mod (ir_graph *irg, ir_node *block,
265            ir_node *memop, ir_node *op1, ir_node *op2)
266 {
267   ir_node *in[3] = {memop, op1, op2};
268   ir_node *res;
269   res = new_ir_node (irg, block, op_Mod, mode_T, 3, in);
270   res = optimize (res);
271   irn_vrfy (res);
272   return res;
273 }
274
275 inline ir_node *
276 new_r_And (ir_graph *irg, ir_node *block,
277            ir_node *op1, ir_node *op2, ir_mode *mode)
278 {
279   ir_node *in[2] = {op1, op2};
280   ir_node *res;
281   res = new_ir_node (irg, block, op_And, mode, 2, in);
282   res = optimize (res);
283   irn_vrfy (res);
284   return res;
285 }
286
287 inline ir_node *
288 new_r_Or (ir_graph *irg, ir_node *block,
289           ir_node *op1, ir_node *op2, ir_mode *mode)
290 {
291   ir_node *in[2] = {op1, op2};
292   ir_node *res;
293   res = new_ir_node (irg, block, op_Or, mode, 2, in);
294   res = optimize (res);
295   irn_vrfy (res);
296   return res;
297 }
298
299 inline ir_node *
300 new_r_Eor (ir_graph *irg, ir_node *block,
301           ir_node *op1, ir_node *op2, ir_mode *mode)
302 {
303   ir_node *in[2] = {op1, op2};
304   ir_node *res;
305   res = new_ir_node (irg, block, op_Eor, mode, 2, in);
306   res = optimize (res);
307   irn_vrfy (res);
308   return res;
309 }
310
311 inline ir_node *
312 new_r_Not    (ir_graph *irg, ir_node *block,
313               ir_node *op, ir_mode *mode)
314 {
315   ir_node *in[1] = {op};
316   ir_node *res;
317   res = new_ir_node (irg, block, op_Not, mode, 1, in);
318   res = optimize (res);
319   irn_vrfy (res);
320   return res;
321 }
322
323 inline ir_node *
324 new_r_Shl (ir_graph *irg, ir_node *block,
325           ir_node *op, ir_node *k, ir_mode *mode)
326 {
327   ir_node *in[2] = {op, k};
328   ir_node *res;
329   res = new_ir_node (irg, block, op_Shl, mode, 2, in);
330   res = optimize (res);
331   irn_vrfy (res);
332   return res;
333 }
334
335 inline ir_node *
336 new_r_Shr (ir_graph *irg, ir_node *block,
337            ir_node *op, ir_node *k, ir_mode *mode)
338 {
339   ir_node *in[2] = {op, k};
340   ir_node *res;
341   res = new_ir_node (irg, block, op_Shr, mode, 2, in);
342   res = optimize (res);
343   irn_vrfy (res);
344   return res;
345 }
346
347 inline ir_node *
348 new_r_Shrs (ir_graph *irg, ir_node *block,
349            ir_node *op, ir_node *k, ir_mode *mode)
350 {
351   ir_node *in[2] = {op, k};
352   ir_node *res;
353   res = new_ir_node (irg, block, op_Shrs, mode, 2, in);
354   res = optimize (res);
355   irn_vrfy (res);
356   return res;
357 }
358
359 inline ir_node *
360 new_r_Rot (ir_graph *irg, ir_node *block,
361            ir_node *op, ir_node *k, ir_mode *mode)
362 {
363   ir_node *in[2] = {op, k};
364   ir_node *res;
365   res = new_ir_node (irg, block, op_Rot, mode, 2, in);
366   res = optimize (res);
367   irn_vrfy (res);
368   return res;
369 }
370
371 inline ir_node *
372 new_r_Abs (ir_graph *irg, ir_node *block,
373            ir_node *op, ir_mode *mode)
374 {
375   ir_node *in[1] = {op};
376   ir_node *res;
377   res = new_ir_node (irg, block, op_Abs, mode, 1, in);
378   res = optimize (res);
379   irn_vrfy (res);
380   return res;
381 }
382
383 inline ir_node *
384 new_r_Cmp (ir_graph *irg, ir_node *block,
385            ir_node *op1, ir_node *op2)
386 {
387   ir_node *in[2] = {op1, op2};
388   ir_node *res;
389   res = new_ir_node (irg, block, op_Cmp, mode_T, 2, in);
390   res = optimize (res);
391   irn_vrfy (res);
392   return res;
393 }
394
395 inline ir_node *
396 new_r_Jmp (ir_graph *irg, ir_node *block)
397 {
398   ir_node *in[0] = {};
399   ir_node *res;
400   res = new_ir_node (irg, block, op_Jmp, mode_X, 0, in);
401   res = optimize (res);
402   irn_vrfy (res);
403   return res;
404 }
405
406 inline ir_node *
407 new_r_Cond (ir_graph *irg, ir_node *block, ir_node *c)
408 {
409   ir_node *in[1] = {c};
410   ir_node *res;
411   res = new_ir_node (irg, block, op_Cond, mode_T, 1, in);
412   res->attr.c.kind = dense;
413   res->attr.c.default_proj = 0;
414   res = optimize (res);
415   irn_vrfy (res);
416   return res;
417 }
418
419 ir_node *
420 new_r_Call (ir_graph *irg, ir_node *block, ir_node *store,
421             ir_node *callee, int arity, ir_node **in, type *type)
422 {
423   ir_node **r_in;
424   ir_node *res;
425   int r_arity;
426
427   r_arity = arity+2;
428   NEW_ARR_A (ir_node *, r_in, r_arity);
429   r_in[0] = store;
430   r_in[1] = callee;
431   memcpy (&r_in[2], in, sizeof (ir_node *) * arity);
432
433   res = new_ir_node (irg, block, op_Call, mode_T, r_arity, r_in);
434
435   assert(is_method_type(type));
436   set_Call_type(res, type);
437   res = optimize (res);
438   irn_vrfy (res);
439   return res;
440 }
441
442 ir_node *
443 new_r_Return (ir_graph *irg, ir_node *block,
444               ir_node *store, int arity, ir_node **in)
445 {
446   ir_node **r_in;
447   ir_node *res;
448   int r_arity;
449
450   r_arity = arity+1;
451   NEW_ARR_A (ir_node *, r_in, r_arity);
452   r_in[0] = store;
453   memcpy (&r_in[1], in, sizeof (ir_node *) * arity);
454   res = new_ir_node (irg, block, op_Return, mode_X, r_arity, r_in);
455   res = optimize (res);
456   irn_vrfy (res);
457   return res;
458 }
459
460 inline ir_node *
461 new_r_Raise (ir_graph *irg, ir_node *block, ir_node *store, ir_node *obj)
462 {
463   ir_node *in[2] = {store, obj};
464   ir_node *res;
465   res = new_ir_node (irg, block, op_Raise, mode_X, 2, in);
466
467   res = optimize (res);
468   irn_vrfy (res);
469   return res;
470 }
471
472 inline ir_node *
473 new_r_Load (ir_graph *irg, ir_node *block,
474             ir_node *store, ir_node *adr)
475 {
476   ir_node *in[2] = {store, adr};
477   ir_node *res;
478   res = new_ir_node (irg, block, op_Load, mode_T, 2, in);
479
480   res = optimize (res);
481   irn_vrfy (res);
482   return res;
483 }
484
485 inline ir_node *
486 new_r_Store (ir_graph *irg, ir_node *block,
487              ir_node *store, ir_node *adr, ir_node *val)
488 {
489   ir_node *in[3] = {store, adr, val};
490   ir_node *res;
491   res = new_ir_node (irg, block, op_Store, mode_T, 3, in);
492
493   res = optimize (res);
494   irn_vrfy (res);
495   return res;
496 }
497
498 inline ir_node *
499 new_r_Alloc (ir_graph *irg, ir_node *block, ir_node *store,
500             ir_node *size, type *alloc_type, where_alloc where)
501 {
502   ir_node *in[2] = {store, size};
503   ir_node *res;
504   res = new_ir_node (irg, block, op_Alloc, mode_T, 2, in);
505
506   res->attr.a.where = where;
507   res->attr.a.type = alloc_type;
508
509   res = optimize (res);
510   irn_vrfy (res);
511   return res;
512 }
513
514 inline ir_node *
515 new_r_Free (ir_graph *irg, ir_node *block, ir_node *store,
516             ir_node *ptr, ir_node *size, type *free_type)
517 {
518   ir_node *in[3] = {store, ptr, size};
519   ir_node *res;
520   res = new_ir_node (irg, block, op_Free, mode_T, 3, in);
521
522   res->attr.f = free_type;
523
524   res = optimize (res);
525   irn_vrfy (res);
526   return res;
527 }
528
529 inline ir_node *
530 new_r_Sel (ir_graph *irg, ir_node *block, ir_node *store, ir_node *objptr,
531            int arity, ir_node **in, entity *ent)
532 {
533   ir_node **r_in;
534   ir_node *res;
535   int r_arity;
536
537   r_arity = arity + 2;
538   NEW_ARR_A (ir_node *, r_in, r_arity);
539   r_in[0] = store;
540   r_in[1] = objptr;
541   memcpy (&r_in[2], in, sizeof (ir_node *) * arity);
542   res = new_ir_node (irg, block, op_Sel, mode_p, r_arity, r_in);
543
544   res->attr.s.ltyp = static_linkage;
545   res->attr.s.ent = ent;
546
547   res = optimize (res);
548   irn_vrfy (res);
549   return res;
550 }
551
552 inline ir_node *
553 new_r_SymConst (ir_graph *irg, ir_node *block, type_or_id_p value,
554                 symconst_kind symkind)
555 {
556   ir_node *in[0] = {};
557   ir_node *res;
558   ir_mode *mode;
559   if (symkind == linkage_ptr_info)
560     mode = mode_p;
561   else
562     mode = mode_I;
563   res = new_ir_node (irg, block, op_SymConst, mode, 0, in);
564
565   res->attr.i.num = symkind;
566   if (symkind == linkage_ptr_info) {
567     res->attr.i.tori.ptrinfo = (ident *)value;
568   } else {
569     assert (   (   (symkind == type_tag)
570                 || (symkind == size))
571             && (is_type(value)));
572     res->attr.i.tori.typ = (type *)value;
573   }
574   res = optimize (res);
575   irn_vrfy (res);
576   return res;
577 }
578
579 ir_node *
580 new_r_Sync (ir_graph *irg, ir_node *block, int arity, ir_node **in)
581 {
582   ir_node *res;
583
584   res = new_ir_node (irg, block, op_Sync, mode_M, arity, in);
585
586   res = optimize (res);
587   irn_vrfy (res);
588   return res;
589 }
590
591 ir_node *
592 new_r_Bad ()
593 {
594   return current_ir_graph->bad;
595 }
596
597 /** ********************/
598 /** public interfaces  */
599 /** construction tools */
600
601 /****f* ircons/new_Start
602  *
603  * NAME
604  *   new_Start -- create a new Start node in the current block
605  *
606  * SYNOPSIS
607  *   s = new_Start(void);
608  *   ir_node* new_Start(void);
609  *
610  * RESULT
611  *   s - pointer to the created Start node
612  *
613  ****
614  */
615 ir_node *
616 new_Start (void)
617 {
618   ir_node *res;
619
620   res = new_ir_node (current_ir_graph, current_ir_graph->current_block,
621                      op_Start, mode_T, 0, NULL);
622
623   res = optimize (res);
624   irn_vrfy (res);
625   return res;
626 }
627
628 ir_node *
629 new_End (void)
630 {
631   ir_node *res;
632
633   res = new_ir_node (current_ir_graph,  current_ir_graph->current_block,
634                      op_End, mode_X, -1, NULL);
635
636   res = optimize (res);
637   irn_vrfy (res);
638
639   return res;
640 }
641
642 /* Constructs a Block with a fixed number of predecessors.
643    Does set current_block.  Can be used with automatic Phi
644    node construction. */
645 ir_node *
646 new_Block (int arity, ir_node **in)
647 {
648   ir_node *res;
649
650   res = new_r_Block (current_ir_graph, arity, in);
651   current_ir_graph->current_block = res;
652
653   /* Create and initialize array for Phi-node construction. */
654   res->attr.block.graph_arr = NEW_ARR_D (ir_node *, current_ir_graph->obst,
655                                          current_ir_graph->n_loc);
656   memset(res->attr.block.graph_arr, 0, sizeof(ir_node *)*current_ir_graph->n_loc);
657
658   res = optimize (res);
659   irn_vrfy (res);
660
661   return res;
662 }
663
664 /* ***********************************************************************/
665 /* Methods necessary for automatic Phi node creation                     */
666 /*
667   ir_node *phi_merge            (ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins)
668   ir_node *get_r_value_internal (ir_node *block, int pos, ir_mode *mode);
669   ir_node *new_r_Phi0           (ir_graph *irg, ir_node *block, ir_mode *mode)
670   ir_node *new_r_Phi_in         (ir_graph *irg, ir_node *block, ir_mode *mode,  ir_node **in, int ins)
671
672   Call Graph:   ( A ---> B == A "calls" B)
673
674        get_value         mature_block
675           |                   |
676           |                   |
677           |                   |
678           |          ---> phi_merge
679           |         /       /   \
680           |        /       /     \
681          \|/      /      |/_      \
682        get_r_value_internal        |
683                 |                  |
684                 |                  |
685                \|/                \|/
686             new_r_Phi0          new_r_Phi_in
687
688 * *************************************************************************** */
689
690 /* Creates a Phi node with 0 predecessors */
691 inline ir_node *
692 new_r_Phi0 (ir_graph *irg, ir_node *block, ir_mode *mode)
693 {
694   ir_node *res;
695   res = new_ir_node (irg, block, op_Phi, mode, 0, NULL);
696   irn_vrfy (res);
697   return res;
698 }
699
700 /* There are two implementations of the Phi node construction.  The first
701    is faster, but does not work for blocks with more than 2 predecessors.
702    The second works always but is slower and causes more unnecessary Phi
703    nodes.
704    Select the implementations by the following preprocessor flag set in
705    common/common.h: */
706 #if USE_FAST_PHI_CONSTRUCTION
707
708 /* This is a stack used for allocating and deallocating nodes in
709    new_r_Phi_in.  The original implementation used the obstack
710    to model this stack, now it is explicit.  This reduces side effects.
711 */
712 #if USE_EXPICIT_PHI_IN_STACK
713 Phi_in_stack *
714 new_Phi_in_stack() {
715   Phi_in_stack *res;
716
717   res = (Phi_in_stack *) malloc ( sizeof (Phi_in_stack));
718
719   res->stack = NEW_ARR_F (ir_node *, 1);
720   res->pos = 0;
721
722   return res;
723 }
724
725 void free_to_Phi_in_stack(ir_node *phi) {
726   assert(get_irn_opcode(phi) == iro_Phi);
727
728   if (ARR_LEN(current_ir_graph->Phi_in_stack->stack) ==
729       current_ir_graph->Phi_in_stack->pos)
730     ARR_APP1 (ir_node *, current_ir_graph->Phi_in_stack->stack, phi);
731   else
732     current_ir_graph->Phi_in_stack->stack[current_ir_graph->Phi_in_stack->pos] = phi;
733
734   (current_ir_graph->Phi_in_stack->pos)++;
735 }
736
737 ir_node *
738 alloc_or_pop_from_Phi_in_stack(ir_graph *irg, ir_node *block, ir_mode *mode,
739              int arity, ir_node **in) {
740   ir_node *res;
741   ir_node **stack = current_ir_graph->Phi_in_stack->stack;
742   int pos = current_ir_graph->Phi_in_stack->pos;
743
744
745   if (pos == 0) {
746     /* We need to allocate a new node */
747     res = new_ir_node (irg, block, op_Phi, mode, arity, in);
748   } else {
749     /* reuse the old node and initialize it again. */
750     res = stack[pos-1];
751
752     assert (res->kind == k_ir_node);
753     assert (res->op == op_Phi);
754     res->mode = mode;
755     res->visited = 0;
756     res->link = NULL;
757     assert (arity >= 0);
758     /* ???!!! How to free the old in array??  */
759     res->in = NEW_ARR_D (ir_node *, irg->obst, (arity+1));
760     res->in[0] = block;
761     memcpy (&res->in[1], in, sizeof (ir_node *) * arity);
762
763     (current_ir_graph->Phi_in_stack->pos)--;
764   }
765   return res;
766 }
767 #endif /* USE_EXPICIT_PHI_IN_STACK */
768
769 /* Creates a Phi node with a given, fixed array **in of predecessors.
770    If the Phi node is unnecessary, as the same value reaches the block
771    through all control flow paths, it is eliminated and the value
772    returned directly.  This constructor is only intended for use in
773    the automatic Phi node generation triggered by get_value or mature.
774    The implementation is quite tricky and depends on the fact, that
775    the nodes are allocated on a stack:
776    The in array contains predecessors and NULLs.  The NULLs appear,
777    if get_r_value_internal, that computed the predecessors, reached
778    the same block on two paths.  In this case the same value reaches
779    this block on both paths, there is no definition in between.  We need
780    not allocate a Phi where these path's merge, but we have to communicate
781    this fact to the caller.  This happens by returning a pointer to the
782    node the caller _will_ allocate.  (Yes, we predict the address. We can
783    do so because the nodes are allocated on the obstack.)  The caller then
784    finds a pointer to itself and, when this routine is called again,
785    eliminates itself.
786    */
787 inline ir_node *
788 new_r_Phi_in (ir_graph *irg, ir_node *block, ir_mode *mode,
789               ir_node **in, int ins)
790 {
791   int i;
792   ir_node *res, *known;
793
794   /* allocate a new node on the obstack.
795      This can return a node to which some of the pointers in the in-array
796      already point.
797      Attention: the constructor copies the in array, i.e., the later changes
798      to the array in this routine do not affect the constructed node!  If
799      the in array contains NULLs, there will be missing predecessors in the
800      returned node.
801      Is this a possible internal state of the Phi node generation? */
802 #if USE_EXPICIT_PHI_IN_STACK
803   res = known = alloc_or_pop_from_Phi_in_stack(irg, block, mode, ins, in);
804 #else
805   res = known = new_ir_node (irg, block, op_Phi, mode, ins, in);
806 #endif
807   /* The in-array can contain NULLs.  These were returned by
808      get_r_value_internal if it reached the same block/definition on a
809      second path.
810      The NULLs are replaced by the node itself to simplify the test in the
811      next loop. */
812   for (i=0;  i < ins;  ++i)
813     if (in[i] == NULL) in[i] = res;
814
815   /* This loop checks whether the Phi has more than one predecessor.
816      If so, it is a real Phi node and we break the loop.  Else the
817      Phi node merges the same definition on several paths and therefore
818      is not needed. */
819   for (i=0;  i < ins;  ++i)
820   {
821     if (in[i]==res || in[i]==known) continue;
822
823     if (known==res)
824       known = in[i];
825     else
826       break;
827   }
828
829   /* i==ins: there is at most one predecessor, we don't need a phi node. */
830   if (i==ins) {
831 #if USE_EXPICIT_PHI_IN_STACK
832     free_to_Phi_in_stack(res);
833 #else
834     obstack_free (current_ir_graph->obst, res);
835 #endif
836     res = known;
837   } else {
838     res = optimize (res);
839     irn_vrfy (res);
840   }
841
842   /* return the pointer to the Phi node.  This node might be deallocated! */
843   return res;
844 }
845
846 inline ir_node *
847 get_r_value_internal (ir_node *block, int pos, ir_mode *mode);
848
849 /** This function computes the predecessors for a real Phi node, and then
850     allocates and returns this node.  The routine called to allocate the
851     node might optimize it away and return a real value, or even a pointer
852     to a deallocated Phi node on top of the obstack!
853     This function is called with an in-array of proper size. **/
854 static inline ir_node *
855 phi_merge (ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins)
856 {
857   ir_node *prevBlock, *res;
858   int i;
859
860   /* This loop goes to all predecessor blocks of the block the Phi node is in
861      and there finds the operands of the Phi node by calling
862      get_r_value_internal. */
863   for (i = 1;  i <= ins;  ++i) {
864     assert (block->in[i]);
865     prevBlock = block->in[i]->in[0]; /* go past control flow op to prev block */
866     assert (prevBlock);
867     nin[i-1] = get_r_value_internal (prevBlock, pos, mode);
868   }
869
870   /* After collecting all predecessors into the array nin a new Phi node
871      with these predecessors is created.  This constructor contains an
872      optimization: If all predecessors of the Phi node are identical it
873      returns the only operand instead of a new Phi node.  If the value
874      passes two different control flow edges without being defined, and
875      this is the second path treated, a pointer to the node that will be
876      allocated for the first path (recursion) is returned.  We already
877      know the address of this node, as it is the next node to be allocated
878      and will be placed on top of the obstack. (The obstack is a _stack_!) */
879   res = new_r_Phi_in (current_ir_graph, block, mode, nin, ins);
880
881   /* Now we now the value for "pos" and can enter it in the array with
882      all known local variables.  Attention: this might be a pointer to
883      a node, that later will be allocated!!! See new_r_Phi_in.
884      If this is called in mature, after some set_value in the same block,
885      the proper value must not be overwritten:
886      The call order
887        get_value    (makes Phi0, put's it into graph_arr)
888        set_value    (overwrites Phi0 in graph_arr)
889        mature_block (upgrades Phi0, puts it again into graph_arr, overwriting
890                      the proper value.)
891      fails. */
892   if (!block->attr.block.graph_arr[pos]) {
893     block->attr.block.graph_arr[pos] = res;
894   } else {
895     /*  printf(" value already computed by %s\n",
896         id_to_str(block->attr.block.graph_arr[pos]->op->name));  */
897   }
898
899   return res;
900 }
901
902 /* This function returns the last definition of a variable.  In case
903    this variable was last defined in a previous block, Phi nodes are
904    inserted.  If the part of the firm graph containing the definition
905    is not yet constructed, a dummy Phi node is returned. */
906 inline ir_node *
907 get_r_value_internal (ir_node *block, int pos, ir_mode *mode)
908 {
909   ir_node *res;
910   /* There are 4 cases to treat.
911
912      1. The block is not mature and we visit it the first time.  We can not
913         create a proper Phi node, therefore a Phi0, i.e., a Phi without
914         predecessors is returned.  This node is added to the linked list (field
915         "link") of the containing block to be completed when this block is
916         matured. (Comlpletion will add a new Phi and turn the Phi0 into an Id
917         node.)
918
919      2. The value is already known in this block, graph_arr[pos] is set and we
920         visit the block the first time.  We can return the value without
921         creating any new nodes.
922
923      3. The block is mature and we visit it the first time.  A Phi node needs
924         to be created (phi_merge).  If the Phi is not needed, as all it's
925         operands are the same value reaching the block through different
926         paths, it's optimized away and the value itself is returned.
927
928      4. The block is mature, and we visit it the second time.  Now two
929         subcases are possible:
930         * The value was computed completely the last time we were here. This
931           is the case if there is no loop.  We can return the proper value.
932         * The recursion that visited this node and set the flag did not
933           return yet.  We are computing a value in a loop and need to
934           break the recursion without knowing the result yet.
935           @@@ strange case.  Straight forward we would create a Phi before
936           starting the computation of it's predecessors.  In this case we will
937           find a Phi here in any case.  The problem is that this implementation
938           only creates a Phi after computing the predecessors, so that it is
939           hard to compute self references of this Phi.  @@@
940         There is no simple check for the second subcase.  Therefore we check
941         for a second visit and treat all such cases as the second subcase.
942         Anyways, the basic situation is the same:  we reached a block
943         on two paths without finding a definition of the value:  No Phi
944         nodes are needed on both paths.
945         We return this information "Two paths, no Phi needed" by a very tricky
946         implementation that relies on the fact that an obstack is a stack and
947         will return a node with the same address on different allocations.
948         Look also at phi_merge and new_r_phi_in to understand this.
949         @@@ Unfortunately this does not work, see testprogram
950         three_cfpred_example.
951
952   */
953
954   /* case 4 -- already visited. */
955   if (get_irn_visited(block) == get_irg_visited(current_ir_graph)) return NULL;
956
957   /* visited the first time */
958   set_irn_visited(block, get_irg_visited(current_ir_graph));
959
960   /* Get the local valid value */
961   res = block->attr.block.graph_arr[pos];
962
963   /* case 2 -- If the value is actually computed, return it. */
964   if (res) { return res;};
965
966   if (block->attr.block.matured) { /* case 3 */
967
968     /* The Phi has the same amount of ins as the corresponding block. */
969     int ins = get_irn_arity(block);
970     ir_node **nin;
971     NEW_ARR_A (ir_node *, nin, ins);
972
973     /* Phi merge collects the predecessors and then creates a node. */
974     res = phi_merge (block, pos, mode, nin, ins);
975
976   } else {  /* case 1 */
977     /* The block is not mature, we don't know how many in's are needed.  A Phi
978        with zero predecessors is created.  Such a Phi node is called Phi0
979        node.  (There is also an obsolete Phi0 opcode.) The Phi0 is then added
980        to the list of Phi0 nodes in this block to be matured by mature_block
981        later.
982        The Phi0 has to remember the pos of it's internal value.  If the real
983        Phi is computed, pos is used to update the array with the local
984        values. */
985
986     res = new_r_Phi0 (current_ir_graph, block, mode);
987     res->attr.phi0_pos = pos;
988     res->link = block->link;
989     block->link = res;
990   }
991
992   /* If we get here, the frontend missed a use-before-definition error */
993   if (!res) {
994     /* Error Message */
995     printf("Error: no value set.  Use of undefined variable.  Initializing
996             to zero.\n");
997     assert (mode->code >= irm_f && mode->code <= irm_p);
998     res = new_r_Const (current_ir_graph, block, mode,
999                        tarval_mode_null[mode->code]);
1000   }
1001
1002   /* The local valid value is available now. */
1003   block->attr.block.graph_arr[pos] = res;
1004
1005   return res;
1006 }
1007
1008 #else /* if 0 */
1009
1010 /** This is the simple algorithm.  If first generates a Phi0, then
1011     it starts the recursion.  This causes an Id at the entry of
1012     every block that has no definition of the value! **/
1013
1014 #if USE_EXPICIT_PHI_IN_STACK
1015 /* Just a dummy */
1016 Phi_in_stack * new_Phi_in_stack() {  return NULL; }
1017 #endif
1018
1019 inline ir_node *
1020 new_r_Phi_in (ir_graph *irg, ir_node *block, ir_mode *mode,
1021               ir_node **in, int ins)
1022 {
1023   int i;
1024   ir_node *res, *known;
1025
1026   /* Allocate a new node on the obstack.  The allocation copies the in
1027      array. */
1028   res = new_ir_node (irg, block, op_Phi, mode, ins, in);
1029
1030   /* This loop checks whether the Phi has more than one predecessor.
1031      If so, it is a real Phi node and we break the loop.  Else the
1032      Phi node merges the same definition on several paths and therefore
1033      is not needed. Don't consider Bad nodes! */
1034   known = res;
1035   for (i=0;  i < ins;  ++i)
1036   {
1037     if (in[i]==res || in[i]==known || is_Bad(in[i])) continue;
1038
1039     if (known==res)
1040       known = in[i];
1041     else
1042       break;
1043   }
1044
1045   /* i==ins: there is at most one predecessor, we don't need a phi node. */
1046   if (i==ins) {
1047     if (res != known) {
1048       obstack_free (current_ir_graph->obst, res);
1049       res = known;
1050     } else {
1051       /* A undefined value, e.g., in unreachable code. */
1052       res = new_Bad();
1053     }
1054   } else {
1055     res = optimize (res);
1056     irn_vrfy (res);
1057   }
1058
1059   return res;
1060 }
1061
1062 inline ir_node *
1063 get_r_value_internal (ir_node *block, int pos, ir_mode *mode);
1064
1065 /** This function allocates a dummy Phi node to break recursions,
1066     computes the predecessors for the real phi node, and then
1067     allocates and returns this node.  The routine called to allocate the
1068     node might optimize it away and return a real value.
1069     This function is called with an in-array of proper size. **/
1070 static inline ir_node *
1071 phi_merge (ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins)
1072 {
1073   ir_node *prevBlock, *res, *phi0;
1074   int i;
1075
1076
1077   /* If this block has no value at pos create a Phi0 and remember it
1078      in graph_arr to break recursions. */
1079   phi0 = NULL;
1080   if (!block->attr.block.graph_arr[pos]) {
1081     /* This is commented out as collapsing to Bads is no good idea.
1082        Either we need an assert here, or we need to call a routine
1083        that deals with this case as appropriate for the given language.
1084        Right now a self referencing Id is created which will crash irg_vryfy().
1085
1086        Even if all variables are defined before use, it can happen that
1087        we get to the start block, if a cond has been replaced by a tuple
1088        (bad, jmp).  As the start has a self referencing control flow edge,
1089        we get a self referencing Id, which is hard to optimize away.  We avoid
1090        this by defining the value as a Bad node.
1091        Returning a const with tarval_bad is a preliminary solution.  In some
1092        situations we might want a Warning or an Error. */
1093
1094     if (block == get_irg_start_block(current_ir_graph)) {
1095       block->attr.block.graph_arr[pos] = new_Const(mode, tarval_bad);
1096       return block->attr.block.graph_arr[pos];
1097       } else  {
1098       phi0 = new_r_Phi0(current_ir_graph, block, mode);
1099       block->attr.block.graph_arr[pos] = phi0;
1100     }
1101   }
1102
1103   /* This loop goes to all predecessor blocks of the block the Phi node
1104      is in and there finds the operands of the Phi node by calling
1105      get_r_value_internal.  */
1106   for (i = 1;  i <= ins;  ++i) {
1107     assert (block->in[i]);
1108     if (is_Bad(block->in[i])) {
1109       /* In case a Cond has been optimized we would get right to the start block
1110          with an invalid definition. */
1111       nin[i-1] = new_Bad();
1112       continue;
1113     }
1114     prevBlock = block->in[i]->in[0]; /* go past control flow op to prev block */
1115     assert (prevBlock);
1116     if (!is_Bad(prevBlock)) {
1117       nin[i-1] = get_r_value_internal (prevBlock, pos, mode);
1118     } else {
1119       nin[i-1] = new_Bad();
1120     }
1121   }
1122
1123   /* After collecting all predecessors into the array nin a new Phi node
1124      with these predecessors is created.  This constructor contains an
1125      optimization: If all predecessors of the Phi node are identical it
1126      returns the only operand instead of a new Phi node.  */
1127   res = new_r_Phi_in (current_ir_graph, block, mode, nin, ins);
1128
1129   /* In case we allocated a Phi0 node at the beginning of this procedure,
1130      we need to exchange this Phi0 with the real Phi. */
1131   if (phi0) {
1132     exchange(phi0, res);
1133     block->attr.block.graph_arr[pos] = res;
1134   }
1135
1136   return res;
1137 }
1138
1139 /* This function returns the last definition of a variable.  In case
1140    this variable was last defined in a previous block, Phi nodes are
1141    inserted.  If the part of the firm graph containing the definition
1142    is not yet constructed, a dummy Phi node is returned. */
1143 inline ir_node *
1144 get_r_value_internal (ir_node *block, int pos, ir_mode *mode)
1145 {
1146   ir_node *res;
1147   /* There are 4 cases to treat.
1148
1149      1. The block is not mature and we visit it the first time.  We can not
1150         create a proper Phi node, therefore a Phi0, i.e., a Phi without
1151         predecessors is returned.  This node is added to the linked list (field
1152         "link") of the containing block to be completed when this block is
1153         matured. (Comlpletion will add a new Phi and turn the Phi0 into an Id
1154         node.)
1155
1156      2. The value is already known in this block, graph_arr[pos] is set and we
1157         visit the block the first time.  We can return the value without
1158         creating any new nodes.
1159
1160      3. The block is mature and we visit it the first time.  A Phi node needs
1161         to be created (phi_merge).  If the Phi is not needed, as all it's
1162         operands are the same value reaching the block through different
1163         paths, it's optimized away and the value itself is returned.
1164
1165      4. The block is mature, and we visit it the second time.  Now two
1166         subcases are possible:
1167         * The value was computed completely the last time we were here. This
1168           is the case if there is no loop.  We can return the proper value.
1169         * The recursion that visited this node and set the flag did not
1170           return yet.  We are computing a value in a loop and need to
1171           break the recursion.  This case only happens if we visited
1172           the same block with phi_merge before, which inserted a Phi0.
1173           So we return the Phi0.
1174   */
1175
1176   /* case 4 -- already visited. */
1177   if (get_irn_visited(block) == get_irg_visited(current_ir_graph)) {
1178     /* As phi_merge allocates a Phi0 this value is always defined. Here
1179      is the critical difference of the two algorithms. */
1180     assert(block->attr.block.graph_arr[pos]);
1181     return block->attr.block.graph_arr[pos];
1182   }
1183
1184   /* visited the first time */
1185   set_irn_visited(block, get_irg_visited(current_ir_graph));
1186
1187   /* Get the local valid value */
1188   res = block->attr.block.graph_arr[pos];
1189
1190   /* case 2 -- If the value is actually computed, return it. */
1191   if (res) { return res; };
1192
1193   if (block->attr.block.matured) { /* case 3 */
1194
1195     /* The Phi has the same amount of ins as the corresponding block. */
1196     int ins = get_irn_arity(block);
1197     ir_node **nin;
1198     NEW_ARR_A (ir_node *, nin, ins);
1199
1200     /* Phi merge collects the predecessors and then creates a node. */
1201     res = phi_merge (block, pos, mode, nin, ins);
1202
1203   } else {  /* case 1 */
1204     /* The block is not mature, we don't know how many in's are needed.  A Phi
1205        with zero predecessors is created.  Such a Phi node is called Phi0
1206        node.  The Phi0 is then added to the list of Phi0 nodes in this block
1207        to be matured by mature_block later.
1208        The Phi0 has to remember the pos of it's internal value.  If the real
1209        Phi is computed, pos is used to update the array with the local
1210        values. */
1211     res = new_r_Phi0 (current_ir_graph, block, mode);
1212     res->attr.phi0_pos = pos;
1213     res->link = block->link;
1214     block->link = res;
1215   }
1216
1217   /* If we get here, the frontend missed a use-before-definition error */
1218   if (!res) {
1219     /* Error Message */
1220     printf("Error: no value set.  Use of undefined variable.  Initializing
1221             to zero.\n");
1222     assert (mode->code >= irm_f && mode->code <= irm_p);
1223     res = new_r_Const (current_ir_graph, block, mode,
1224                        tarval_mode_null[mode->code]);
1225   }
1226
1227   /* The local valid value is available now. */
1228   block->attr.block.graph_arr[pos] = res;
1229
1230   return res;
1231 }
1232
1233 #endif /* USE_FAST_PHI_CONSTRUCTION */
1234
1235 /* ************************************************************************** */
1236
1237 /** Finalize a Block node, when all control flows are known.  */
1238 /** Acceptable parameters are only Block nodes.               */
1239 void
1240 mature_block (ir_node *block)
1241 {
1242
1243   int ins;
1244   ir_node *n, **nin;
1245   ir_node *next;
1246
1247   assert (get_irn_opcode(block) == iro_Block);
1248
1249   if (!get_Block_matured(block)) {
1250
1251     /* turn the dynamic in-array into a static one. */
1252     ins = ARR_LEN (block->in)-1;
1253     NEW_ARR_A (ir_node *, nin, ins);
1254     /*  @@@ something is strange here... why isn't the array copied? */
1255
1256     /* Traverse a chain of Phi nodes attached to this block and mature
1257        these, too. **/
1258     for (n = block->link;  n;  n=next) {
1259       inc_irg_visited(current_ir_graph);
1260       next = n->link;
1261       exchange (n, phi_merge (block, n->attr.phi0_pos, n->mode, nin, ins));
1262     }
1263
1264     block->attr.block.matured = 1;
1265
1266     /* Now, as the block is a finished firm node, we can optimize it.
1267        Since other nodes have been allocated since the block was created
1268        we can not free the node on the obstack.  Therefore we have to call
1269        optimize_in_place.
1270        Unfortunately the optimization does not change a lot, as all allocated
1271        nodes refer to the unoptimized node. */
1272     block = optimize_in_place(block);
1273     irn_vrfy(block);
1274   }
1275 }
1276
1277 ir_node *
1278 new_Phi (int arity, ir_node **in, ir_mode *mode)
1279 {
1280   return new_r_Phi (current_ir_graph, current_ir_graph->current_block,
1281                     arity, in, mode);
1282 }
1283
1284 ir_node *
1285 new_Const (ir_mode *mode, tarval *con)
1286 {
1287   return new_r_Const (current_ir_graph, current_ir_graph->start_block,
1288                       mode, con);
1289 }
1290
1291 ir_node *
1292 new_Id (ir_node *val, ir_mode *mode)
1293 {
1294   return new_r_Id (current_ir_graph, current_ir_graph->current_block,
1295                    val, mode);
1296 }
1297
1298 ir_node *
1299 new_Proj (ir_node *arg, ir_mode *mode, long proj)
1300 {
1301   return new_r_Proj (current_ir_graph, current_ir_graph->current_block,
1302                      arg, mode, proj);
1303 }
1304
1305 ir_node *
1306 new_defaultProj (ir_node *arg, long max_proj)
1307 {
1308   ir_node *res;
1309   assert((arg->op==op_Cond) && (get_irn_mode(arg->in[1]) == mode_I));
1310   arg->attr.c.kind = fragmentary;
1311   arg->attr.c.default_proj = max_proj;
1312   res = new_Proj (arg, mode_X, max_proj);
1313   return res;
1314 }
1315
1316 ir_node *
1317 new_Conv (ir_node *op, ir_mode *mode)
1318 {
1319   return new_r_Conv (current_ir_graph, current_ir_graph->current_block,
1320                      op, mode);
1321 }
1322
1323 ir_node *
1324 new_Tuple (int arity, ir_node **in)
1325 {
1326   return new_r_Tuple (current_ir_graph, current_ir_graph->current_block,
1327                       arity, in);
1328 }
1329
1330 ir_node *
1331 new_Add (ir_node *op1, ir_node *op2, ir_mode *mode)
1332 {
1333   return new_r_Add (current_ir_graph, current_ir_graph->current_block,
1334                     op1, op2, mode);
1335 }
1336
1337 ir_node *
1338 new_Sub (ir_node *op1, ir_node *op2, ir_mode *mode)
1339 {
1340   return new_r_Sub (current_ir_graph, current_ir_graph->current_block,
1341                     op1, op2, mode);
1342 }
1343
1344
1345 ir_node *
1346 new_Minus  (ir_node *op,  ir_mode *mode)
1347 {
1348   return new_r_Minus (current_ir_graph, current_ir_graph->current_block,
1349                       op, mode);
1350 }
1351
1352 ir_node *
1353 new_Mul (ir_node *op1, ir_node *op2, ir_mode *mode)
1354 {
1355   return new_r_Mul (current_ir_graph, current_ir_graph->current_block,
1356                     op1, op2, mode);
1357 }
1358
1359 ir_node *
1360 new_Quot (ir_node *memop, ir_node *op1, ir_node *op2)
1361 {
1362   return new_r_Quot (current_ir_graph, current_ir_graph->current_block,
1363                      memop, op1, op2);
1364 }
1365
1366 ir_node *
1367 new_DivMod (ir_node *memop, ir_node *op1, ir_node *op2)
1368 {
1369   return new_r_DivMod (current_ir_graph, current_ir_graph->current_block,
1370                        memop, op1, op2);
1371 }
1372
1373 ir_node *
1374 new_Div (ir_node *memop, ir_node *op1, ir_node *op2)
1375 {
1376   return new_r_Div (current_ir_graph, current_ir_graph->current_block,
1377                     memop, op1, op2);
1378 }
1379
1380 ir_node *
1381 new_Mod (ir_node *memop, ir_node *op1, ir_node *op2)
1382 {
1383   return new_r_Mod (current_ir_graph, current_ir_graph->current_block,
1384                     memop, op1, op2);
1385 }
1386
1387 ir_node *
1388 new_And (ir_node *op1, ir_node *op2, ir_mode *mode)
1389 {
1390   return new_r_And (current_ir_graph, current_ir_graph->current_block,
1391                     op1, op2, mode);
1392 }
1393
1394 ir_node *
1395 new_Or (ir_node *op1, ir_node *op2, ir_mode *mode)
1396 {
1397   return new_r_Or (current_ir_graph, current_ir_graph->current_block,
1398                    op1, op2, mode);
1399 }
1400
1401 ir_node *
1402 new_Eor (ir_node *op1, ir_node *op2, ir_mode *mode)
1403 {
1404   return new_r_Eor (current_ir_graph, current_ir_graph->current_block,
1405                     op1, op2, mode);
1406 }
1407
1408 ir_node *
1409 new_Not (ir_node *op, ir_mode *mode)
1410 {
1411   return new_r_Not (current_ir_graph, current_ir_graph->current_block,
1412                     op, mode);
1413 }
1414
1415 ir_node *
1416 new_Shl (ir_node *op, ir_node *k, ir_mode *mode)
1417 {
1418   return new_r_Shl (current_ir_graph, current_ir_graph->current_block,
1419                     op, k, mode);
1420 }
1421
1422 ir_node *
1423 new_Shr (ir_node *op, ir_node *k, ir_mode *mode)
1424 {
1425   return new_r_Shr (current_ir_graph, current_ir_graph->current_block,
1426                     op, k, mode);
1427 }
1428
1429 ir_node *
1430 new_Shrs (ir_node *op, ir_node *k, ir_mode *mode)
1431 {
1432   return new_r_Shrs (current_ir_graph, current_ir_graph->current_block,
1433                      op, k, mode);
1434 }
1435
1436 ir_node *
1437 new_Rotate (ir_node *op, ir_node *k, ir_mode *mode)
1438 {
1439   return new_r_Rot (current_ir_graph, current_ir_graph->current_block,
1440                      op, k, mode);
1441 }
1442
1443 ir_node *
1444 new_Abs (ir_node *op, ir_mode *mode)
1445 {
1446   return new_r_Abs (current_ir_graph, current_ir_graph->current_block,
1447                     op, mode);
1448 }
1449
1450 ir_node *
1451 new_Cmp (ir_node *op1, ir_node *op2)
1452 {
1453   return new_r_Cmp (current_ir_graph, current_ir_graph->current_block,
1454                     op1, op2);
1455 }
1456
1457 ir_node *
1458 new_Jmp (void)
1459 {
1460   return new_r_Jmp (current_ir_graph, current_ir_graph->current_block);
1461 }
1462
1463 ir_node *
1464 new_Cond (ir_node *c)
1465 {
1466   return new_r_Cond (current_ir_graph, current_ir_graph->current_block, c);
1467 }
1468
1469 ir_node *
1470 new_Call (ir_node *store, ir_node *callee, int arity, ir_node **in,
1471           type *type)
1472 {
1473   return new_r_Call (current_ir_graph, current_ir_graph->current_block,
1474                      store, callee, arity, in, type);
1475 }
1476
1477 ir_node *
1478 new_Return (ir_node* store, int arity, ir_node **in)
1479 {
1480   return new_r_Return (current_ir_graph, current_ir_graph->current_block,
1481                        store, arity, in);
1482 }
1483
1484 ir_node *
1485 new_Raise (ir_node *store, ir_node *obj)
1486 {
1487   return new_r_Raise (current_ir_graph, current_ir_graph->current_block,
1488                       store, obj);
1489 }
1490
1491 ir_node *
1492 new_Load (ir_node *store, ir_node *addr)
1493 {
1494   return new_r_Load (current_ir_graph, current_ir_graph->current_block,
1495                      store, addr);
1496 }
1497
1498 ir_node *
1499 new_Store (ir_node *store, ir_node *addr, ir_node *val)
1500 {
1501   return new_r_Store (current_ir_graph, current_ir_graph->current_block,
1502                       store, addr, val);
1503 }
1504
1505 ir_node *
1506 new_Alloc (ir_node *store, ir_node *size, type *alloc_type,
1507            where_alloc where)
1508 {
1509   return new_r_Alloc (current_ir_graph, current_ir_graph->current_block,
1510                       store, size, alloc_type, where);
1511 }
1512
1513 ir_node *
1514 new_Free (ir_node *store, ir_node *ptr, ir_node *size, type *free_type)
1515 {
1516   return new_r_Free (current_ir_graph, current_ir_graph->current_block,
1517                      store, ptr, size, free_type);
1518 }
1519
1520 ir_node *
1521 new_simpleSel (ir_node *store, ir_node *objptr, entity *ent)
1522 /* GL: objptr was called frame before.  Frame was a bad choice for the name
1523    as the operand could as well be a pointer to a dynamic object. */
1524 {
1525   return new_r_Sel (current_ir_graph, current_ir_graph->current_block,
1526                     store, objptr, 0, NULL, ent);
1527 }
1528
1529 ir_node *
1530 new_Sel (ir_node *store, ir_node *objptr, int n_index, ir_node **index, entity *sel)
1531 {
1532   return new_r_Sel (current_ir_graph, current_ir_graph->current_block,
1533                     store, objptr, n_index, index, sel);
1534 }
1535
1536 ir_node *
1537 new_SymConst (type_or_id_p value, symconst_kind kind)
1538 {
1539   return new_r_SymConst (current_ir_graph, current_ir_graph->current_block,
1540                          value, kind);
1541 }
1542
1543 ir_node *
1544 new_Sync (int arity, ir_node** in)
1545 {
1546   return new_r_Sync (current_ir_graph, current_ir_graph->current_block,
1547                      arity, in);
1548 }
1549
1550
1551 ir_node *
1552 new_Bad (void)
1553 {
1554   return current_ir_graph->bad;
1555 }
1556
1557 /* ********************************************************************* */
1558 /* Comfortable interface with automatic Phi node construction.           */
1559 /* (Uses also constructors of ?? interface, except new_Block.            */
1560 /* ********************************************************************* */
1561
1562 /** Block construction **/
1563 /* immature Block without predecessors */
1564 ir_node *new_immBlock (void) {
1565   ir_node *res;
1566
1567   /* creates a new dynamic in-array as length of in is -1 */
1568   res = new_ir_node (current_ir_graph, NULL, op_Block, mode_R, -1, NULL);
1569   current_ir_graph->current_block = res;
1570   res->attr.block.matured = 0;
1571   set_Block_block_visited(res, 0);
1572
1573   /* Create and initialize array for Phi-node construction. */
1574   res->attr.block.graph_arr = NEW_ARR_D (ir_node *, current_ir_graph->obst,
1575                                          current_ir_graph->n_loc);
1576   memset(res->attr.block.graph_arr, 0, sizeof(ir_node *)*current_ir_graph->n_loc);
1577
1578   /* Immature block may not be optimized! */
1579   irn_vrfy (res);
1580
1581   return res;
1582 }
1583
1584 /* add an adge to a jmp/control flow node */
1585 void
1586 add_in_edge (ir_node *block, ir_node *jmp)
1587 {
1588   if (block->attr.block.matured) {
1589     printf("Error: Block already matured!\n");
1590   }
1591   else {
1592     assert (jmp != NULL);
1593     ARR_APP1 (ir_node *, block->in, jmp);
1594   }
1595 }
1596
1597 /* changing the current block */
1598 void
1599 switch_block (ir_node *target)
1600 {
1601   current_ir_graph->current_block = target;
1602 }
1603
1604 /* ************************ */
1605 /* parameter administration */
1606
1607 /* get a value from the parameter array from the current block by its index */
1608 ir_node *
1609 get_value (int pos, ir_mode *mode)
1610 {
1611   inc_irg_visited(current_ir_graph);
1612   return get_r_value_internal (current_ir_graph->current_block, pos + 1, mode);
1613 }
1614
1615
1616 /* set a value at position pos in the parameter array from the current block */
1617 inline void
1618 set_value (int pos, ir_node *value)
1619 {
1620   current_ir_graph->current_block->attr.block.graph_arr[pos + 1] = value;
1621 }
1622
1623 /* get the current store */
1624 inline ir_node *
1625 get_store (void)
1626 {
1627   /* GL: one could call get_value instead */
1628   inc_irg_visited(current_ir_graph);
1629   return get_r_value_internal (current_ir_graph->current_block, 0, mode_M);
1630 }
1631
1632 /* set the current store */
1633 inline void
1634 set_store (ir_node *store)
1635 {
1636   /* GL: one could call set_value instead */
1637   current_ir_graph->current_block->attr.block.graph_arr[0] = store;
1638 }
1639
1640 /* ********************************************************************* */
1641 /* initialize */
1642
1643 /* call once for each run of the library */
1644 void
1645 init_cons (void)
1646 {
1647 }