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