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