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