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