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