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