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