*** 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 "array.h"
14 # include "iropt.h"
15 /* memset belongs to string.h */
16 # include "string.h"
17
18 /* irnode constructor                                             */
19 /* create a new irnode in irg, with an op, mode, arity and        */
20 /* some incoming irnodes                                          */
21 /* this constructor is used in every specified irnode constructor */
22 inline ir_node *
23 new_ir_node (ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mode,
24              int arity, ir_node **in)
25 {
26   ir_node *res;
27   int node_size = offsetof (ir_node, attr) +  op->attr_size;
28
29   res = (ir_node *) obstack_alloc (irg->obst, node_size);
30
31   res->kind = k_ir_node;
32   res->op = op;
33   res->mode = mode;
34   res->visit = 0;
35   res->link = NULL;
36   if (arity < 0) {
37     res->in = NEW_ARR_F (ir_node *, 1);
38   } else {
39     res->in = NEW_ARR_D (ir_node *, irg->obst, (arity+1));
40     memcpy (&res->in[1], in, sizeof (ir_node *) * arity);
41   }
42   res->in[0] = block;
43   return res;
44 }
45
46
47
48
49 /*********************************************** */
50 /** privat interfaces, for professional use only */
51
52 /*CS*/
53 inline ir_node *
54 new_r_Block (ir_graph *irg,  int arity, ir_node **in)
55 {
56   ir_node *res;
57
58   return res;
59
60 }
61
62 ir_node *
63 new_r_Start (ir_graph *irg, ir_node *block)
64 {
65   ir_node *res;
66
67   res = new_ir_node (irg, block, op_Start, mode_T, 0, NULL);
68
69   ir_vrfy (res);
70   return res;
71 }
72
73
74 ir_node *
75 new_r_End (ir_graph *irg, ir_node *block)
76 {
77   ir_node *res;
78
79   res = new_ir_node (irg, block, op_End, mode_X, -1, NULL);
80
81   ir_vrfy (res);
82   return res;
83
84 }
85
86
87 /* Creates a Phi node with 0 predecessors */
88 inline ir_node *
89 new_r_Phi0 (ir_graph *irg, ir_node *block, ir_mode *mode)
90 {
91   ir_node *res;
92
93   res = new_ir_node (irg, block, op_Phi, mode, 0, NULL);
94
95   /* GL I'm not sure whether we should optimize this guy. *
96      res = optimize (res); ??? */
97   ir_vrfy (res);
98   return res;
99 }
100
101 /* Creates a Phi node with all predecessors.  Calling this constructor
102    is only allowed if the corresponding block is mature.  */
103 ir_node *
104 new_r_Phi (ir_graph *irg, ir_node *block, int arity, ir_node **in, ir_mode *mode)
105 {
106   ir_node *res;
107
108   assert( get_Block_matured(block) );
109   assert( get_irn_arity(block) == arity );
110
111   res = new_ir_node (irg, block, op_Phi, mode, arity, in);
112
113   res = optimize (res);
114   ir_vrfy (res);
115   return res;
116 }
117
118 /* This is a stack used for allocating and deallocating nodes in
119    new_r_Phi_in.  The original implementation used the obstack
120    to model this stack, now it is explicit.  This reduces side effects.
121 */
122 #if USE_EXPICIT_PHI_IN_STACK
123 Phi_in_stack *
124 new_Phi_in_stack() {
125   Phi_in_stack *res;
126
127   res = (Phi_in_stack *) malloc ( sizeof (Phi_in_stack));
128
129   res->stack = NEW_ARR_F (ir_node *, 1);
130   res->pos = 0;
131
132   return res;
133 }
134
135
136 void free_to_Phi_in_stack(ir_node *phi) {
137   assert(get_irn_opcode(phi) == iro_Phi);
138
139   if (ARR_LEN(current_ir_graph->Phi_in_stack->stack) ==
140       current_ir_graph->Phi_in_stack->pos)
141     ARR_APP1 (ir_node *, current_ir_graph->Phi_in_stack->stack, phi);
142   else
143     current_ir_graph->Phi_in_stack->stack[current_ir_graph->Phi_in_stack->pos] = phi;
144
145   (current_ir_graph->Phi_in_stack->pos)++;
146 }
147
148 ir_node *
149 alloc_or_pop_from_Phi_in_stack(ir_graph *irg, ir_node *block, ir_mode *mode,
150              int arity, ir_node **in) {
151   ir_node *res;
152   ir_node **stack = current_ir_graph->Phi_in_stack->stack;
153   int pos = current_ir_graph->Phi_in_stack->pos;
154
155
156   if (pos == 0) {
157     /* We need to allocate a new node */
158     res = new_ir_node (irg, block, op_Phi, mode, arity, in);
159   } else {
160     /* reuse the old node and initialize it again. */
161     res = stack[pos-1];
162
163     assert (res->kind == k_ir_node);
164     assert (res->op == op_Phi);
165     res->mode = mode;
166     res->visit = 0;
167     res->link = NULL;
168     assert (arity >= 0);
169     /* ???!!! How to free the old in array??  */
170     res->in = NEW_ARR_D (ir_node *, irg->obst, (arity+1));
171     res->in[0] = block;
172     memcpy (&res->in[1], in, sizeof (ir_node *) * arity);
173
174     (current_ir_graph->Phi_in_stack->pos)--;
175   }
176   return res;
177 }
178 #endif
179
180
181
182 /* Creates a Phi node with a given, fixed array **in of predecessors.
183    If the Phi node is unnecessary, as the same value reaches the block
184    through all control flow paths, it is eliminated and the value
185    returned directly.  This constructor is only intended for use in
186    the automatic Phi node generation triggered by get_value or mature.
187    The implementation is quite tricky and depends on the fact, that
188    the nodes are allocated on a stack:
189    The in array contains predecessors and NULLs.  The NULLs appear,
190    if get_r_value_internal, that computed the predecessors, reached
191    the same block on two paths.  In this case the same value reaches
192    this block on both paths, there is no definition in between.  We need
193    not allocate a Phi where these path's merge, but we have to communicate
194    this fact to the caller.  This happens by returning a pointer to the
195    node the caller _will_ allocate.  (Yes, we predict the address. We can
196    do so because the nodes are allocated on the obstack.)  The caller then
197    finds a pointer to itself and, when this routine is called again,
198    eliminates itself.
199    */
200 inline ir_node *
201 new_r_Phi_in (ir_graph *irg, ir_node *block, ir_mode *mode,
202               ir_node **in, int ins)
203 {
204   int i;
205   ir_node *res, *known;
206
207   /* allocate a new node on the obstack.
208      This can return a node to which some of the pointers in the in-array
209      already point.
210      Attention: the constructor copies the in array, i.e., the later changes
211      to the array in this routine do not affect the constructed node!  If
212      the in array contains NULLs, there will be missing predecessors in the
213      returned node.
214      Is this a possible internal state of the Phi node generation? */
215 #if USE_EXPICIT_PHI_IN_STACK
216   res = known = alloc_or_pop_from_Phi_in_stack(irg, block, mode, ins, in);
217 #else
218   res = known = new_ir_node (irg, block, op_Phi, mode, ins, in);
219 #endif
220   /* The in-array can contain NULLs.  These were returned by get_r_value_internal
221      if it reached the same block/definition on a second path.
222      The NULLs are replaced by the node itself to simplify the test in the
223      next loop. */
224   for (i=0;  i < ins;  ++i)
225     if (in[i] == NULL) in[i] = res;
226
227   /* This loop checks whether the Phi has more than one predecessor.
228      If so, it is a real Phi node and we break the loop.  Else the
229      Phi node merges the same definition on several paths and therefore
230      is not needed. */
231   for (i=0;  i < ins;  ++i)
232   {
233     if (in[i]==res || in[i]==known) continue;
234
235     if (known==res)
236       known = in[i];
237     else
238       break;
239   }
240
241   /* i==ins: there is at most one predecessor, we don't need a phi node. */
242   if (i==ins) {
243 #if USE_EXPICIT_PHI_IN_STACK
244     free_to_Phi_in_stack(res);
245 #else
246     obstack_free (current_ir_graph->obst, res);
247 #endif
248     res = known;
249   } else {
250     res = optimize (res);
251     ir_vrfy (res);
252   }
253
254   /* return the pointer to the Phi node.  This node might be deallocated! */
255   return res;
256 }
257
258 ir_node *
259 new_r_Const (ir_graph *irg, ir_node *block, ir_mode *mode, tarval *con)
260 {
261   ir_node *res;
262   res = new_ir_node (irg, block, op_Const, mode, 0, NULL);
263   res->attr.con = con;
264   res = optimize (res);
265   ir_vrfy (res);
266
267 #if 0
268   res = local_optimize_newby (res);
269 # endif
270
271   return res;
272 }
273
274 ir_node *
275 new_r_Id (ir_graph *irg, ir_node *block, ir_node *val, ir_mode *mode)
276 {
277   ir_node *in[1] = {val};
278   ir_node *res;
279   res = new_ir_node (irg, block, op_Id, mode, 1, in);
280   res = optimize (res);
281   ir_vrfy (res);
282   return res;
283 }
284
285 ir_node *
286 new_r_Proj (ir_graph *irg, ir_node *block, ir_node *arg, ir_mode *mode, long proj)
287 {
288   ir_node *in[1] = {arg};
289   ir_node *res;
290   res = new_ir_node (irg, block, op_Proj, mode, 1, in);
291   res->attr.proj = proj;
292   res = optimize (res);
293   ir_vrfy (res);
294   return res;
295
296 }
297
298 ir_node *
299 new_r_Conv (ir_graph *irg, ir_node *block, ir_node *op, ir_mode *mode)
300 {
301   ir_node *in[1] = {op};
302   ir_node *res;
303   res = new_ir_node (irg, block, op_Conv, mode, 1, in);
304   res = optimize (res);
305   ir_vrfy (res);
306   return res;
307
308 }
309
310 ir_node *
311 new_r_Tuple (ir_graph *irg, ir_node *block, int arity, ir_node **in)
312 {
313   ir_node *res;
314
315   res = new_ir_node (irg, block, op_Tuple, mode_T, arity, in);
316   res = optimize (res);
317   ir_vrfy (res);
318   return res;
319 }
320
321 inline ir_node *
322 new_r_Add (ir_graph *irg, ir_node *block,
323            ir_node *op1, ir_node *op2, ir_mode *mode)
324 {
325   ir_node *in[2] = {op1, op2};
326   ir_node *res;
327   res = new_ir_node (irg, block, op_Add, mode, 2, in);
328   res = optimize (res);
329   ir_vrfy (res);
330   return res;
331 }
332
333 inline ir_node *
334 new_r_Sub (ir_graph *irg, ir_node *block,
335            ir_node *op1, ir_node *op2, ir_mode *mode)
336 {
337   ir_node *in[2] = {op1, op2};
338   ir_node *res;
339   res = new_ir_node (irg, block, op_Sub, mode, 2, in);
340   res = optimize (res);
341   ir_vrfy (res);
342   return res;
343 }
344
345 inline ir_node *
346 new_r_Minus (ir_graph *irg, ir_node *block,
347              ir_node *op,  ir_mode *mode)
348 {
349   ir_node *in[1] = {op};
350   ir_node *res;
351   res = new_ir_node (irg, block, op_Minus, mode, 1, in);
352   res = optimize (res);
353   ir_vrfy (res);
354   return res;
355 }
356
357 inline ir_node *
358 new_r_Mul (ir_graph *irg, ir_node *block,
359            ir_node *op1, ir_node *op2, ir_mode *mode)
360 {
361   ir_node *in[2] = {op1, op2};
362   ir_node *res;
363   res = new_ir_node (irg, block, op_Mul, mode, 2, in);
364   res = optimize (res);
365   ir_vrfy (res);
366   return res;
367 }
368
369 inline ir_node *
370 new_r_Quot (ir_graph *irg, ir_node *block,
371             ir_node *memop, ir_node *op1, ir_node *op2)
372 {
373   ir_node *in[3] = {memop, op1, op2};
374   ir_node *res;
375   res = new_ir_node (irg, block, op_Quot, mode_T, 2, in);
376   res = optimize (res);
377   ir_vrfy (res);
378   return res;
379 }
380
381 inline ir_node *
382 new_r_DivMod (ir_graph *irg, ir_node *block,
383               ir_node *memop, ir_node *op1, ir_node *op2)
384 {
385   ir_node *in[3] = {memop, op1, op2};
386   ir_node *res;
387   res = new_ir_node (irg, block, op_DivMod, mode_T, 2, in);
388   res = optimize (res);
389   ir_vrfy (res);
390   return res;
391 }
392
393 inline ir_node *
394 new_r_Div (ir_graph *irg, ir_node *block,
395            ir_node *memop, ir_node *op1, ir_node *op2)
396 {
397   ir_node *in[3] = {memop, op1, op2};
398   ir_node *res;
399   res = new_ir_node (irg, block, op_Div, mode_T, 2, in);
400   res = optimize (res);
401   ir_vrfy (res);
402   return res;
403 }
404
405 inline ir_node *
406 new_r_Mod (ir_graph *irg, ir_node *block,
407            ir_node *memop, ir_node *op1, ir_node *op2)
408 {
409   ir_node *in[3] = {memop, op1, op2};
410   ir_node *res;
411   res = new_ir_node (irg, block, op_Mod, mode_T, 2, in);
412   res = optimize (res);
413   ir_vrfy (res);
414   return res;
415 }
416
417 inline ir_node *
418 new_r_And (ir_graph *irg, ir_node *block,
419            ir_node *op1, ir_node *op2, ir_mode *mode)
420 {
421   ir_node *in[2] = {op1, op2};
422   ir_node *res;
423   res = new_ir_node (irg, block, op_And, mode, 2, in);
424   res = optimize (res);
425   ir_vrfy (res);
426   return res;
427 }
428
429 inline ir_node *
430 new_r_Or (ir_graph *irg, ir_node *block,
431           ir_node *op1, ir_node *op2, ir_mode *mode)
432 {
433   ir_node *in[2] = {op1, op2};
434   ir_node *res;
435   res = new_ir_node (irg, block, op_Or, mode, 2, in);
436   res = optimize (res);
437   ir_vrfy (res);
438   return res;
439 }
440
441 inline ir_node *
442 new_r_Eor (ir_graph *irg, ir_node *block,
443           ir_node *op1, ir_node *op2, ir_mode *mode)
444 {
445   ir_node *in[2] = {op1, op2};
446   ir_node *res;
447   res = new_ir_node (irg, block, op_Eor, mode, 2, in);
448   res = optimize (res);
449   ir_vrfy (res);
450   return res;
451 }
452
453 inline ir_node *
454 new_r_Not    (ir_graph *irg, ir_node *block,
455               ir_node *op, ir_mode *mode)
456 {
457   ir_node *in[1] = {op};
458   ir_node *res;
459   res = new_ir_node (irg, block, op_Not, mode, 1, in);
460   res = optimize (res);
461   ir_vrfy (res);
462   return res;
463 }
464
465 inline ir_node *
466 new_r_Shl (ir_graph *irg, ir_node *block,
467           ir_node *op, ir_node *k, ir_mode *mode)
468 {
469   ir_node *in[2] = {op, k};
470   ir_node *res;
471   res = new_ir_node (irg, block, op_Shl, mode, 2, in);
472   res = optimize (res);
473   ir_vrfy (res);
474   return res;
475 }
476
477 inline ir_node *
478 new_r_Shr (ir_graph *irg, ir_node *block,
479            ir_node *op, ir_node *k, ir_mode *mode)
480 {
481   ir_node *in[2] = {op, k};
482   ir_node *res;
483   res = new_ir_node (irg, block, op_Shr, mode, 2, in);
484   res = optimize (res);
485   ir_vrfy (res);
486   return res;
487 }
488
489 inline ir_node *
490 new_r_Shrs (ir_graph *irg, ir_node *block,
491            ir_node *op, ir_node *k, ir_mode *mode)
492 {
493   ir_node *in[2] = {op, k};
494   ir_node *res;
495   res = new_ir_node (irg, block, op_Shrs, mode, 2, in);
496   res = optimize (res);
497   ir_vrfy (res);
498   return res;
499 }
500
501 inline ir_node *
502 new_r_Rot (ir_graph *irg, ir_node *block,
503            ir_node *op, ir_node *k, ir_mode *mode)
504 {
505   ir_node *in[2] = {op, k};
506   ir_node *res;
507   res = new_ir_node (irg, block, op_Rot, mode, 2, in);
508   res = optimize (res);
509   ir_vrfy (res);
510   return res;
511 }
512
513 inline ir_node *
514 new_r_Abs (ir_graph *irg, ir_node *block,
515            ir_node *op, ir_mode *mode)
516 {
517   ir_node *in[1] = {op};
518   ir_node *res;
519   res = new_ir_node (irg, block, op_Abs, mode, 1, in);
520   res = optimize (res);
521   ir_vrfy (res);
522   return res;
523 }
524
525 inline ir_node *
526 new_r_Cmp (ir_graph *irg, ir_node *block,
527            ir_node *op1, ir_node *op2)
528 {
529   ir_node *in[2] = {op1, op2};
530   ir_node *res;
531   res = new_ir_node (irg, block, op_Cmp, mode_T, 2, in);
532   res = optimize (res);
533   ir_vrfy (res);
534   return res;
535 }
536
537 inline ir_node *
538 new_r_Jmp (ir_graph *irg, ir_node *block)
539 {
540   ir_node *in[0] = {};
541   ir_node *res;
542   res = new_ir_node (irg, block, op_Jmp, mode_X, 0, in);
543   res = optimize (res);
544   ir_vrfy (res);
545   return res;
546 }
547
548 inline ir_node *
549 new_r_Cond (ir_graph *irg, ir_node *block, ir_node *c)
550 {
551   ir_node *in[1] = {c};
552   ir_node *res;
553   res = new_ir_node (irg, block, op_Cond, mode_T, 1, in);
554   res = optimize (res);
555   ir_vrfy (res);
556   return res;
557 }
558
559 ir_node *
560 new_r_Call (ir_graph *irg, ir_node *block, ir_node *store,
561             ir_node *callee, int arity, ir_node **in, type_method *type)
562 {
563   ir_node **r_in;
564   ir_node *res;
565   int r_arity;
566
567   r_arity = arity+2;
568   NEW_ARR_A (ir_node *, r_in, r_arity);
569   r_in[0] = store;
570   r_in[1] = callee;
571   memcpy (&r_in[2], in, sizeof (ir_node *) * arity);
572
573   res = new_ir_node (irg, block, op_Call, mode_T, r_arity, r_in);
574
575   set_Call_type(res, type);
576   res = optimize (res);
577   ir_vrfy (res);
578   return res;
579 }
580
581 ir_node *
582 new_r_Return (ir_graph *irg, ir_node *block,
583               ir_node *store, int arity, ir_node **in)
584 {
585   ir_node **r_in;
586   ir_node *res;
587   int r_arity;
588
589   r_arity = arity+1;
590
591   NEW_ARR_A (ir_node *, r_in, r_arity);
592
593   r_in[0] = store;
594
595   memcpy (&r_in[1], in, sizeof (ir_node *) * arity);
596
597   res = new_ir_node (irg, block, op_Return, mode_X, r_arity, r_in);
598
599   res = optimize (res);
600
601   ir_vrfy (res);
602   return res;
603 }
604
605 inline ir_node *
606 new_r_Raise (ir_graph *irg, ir_node *block, ir_node *store, ir_node *obj)
607 {
608   ir_node *in[2] = {store, obj};
609   ir_node *res;
610   res = new_ir_node (irg, block, op_Raise, mode_X, 2, in);
611
612   res = optimize (res);
613   ir_vrfy (res);
614   return res;
615 }
616
617 inline ir_node *
618 new_r_Load (ir_graph *irg, ir_node *block,
619             ir_node *store, ir_node *adr)
620 {
621   ir_node *in[2] = {store, adr};
622   ir_node *res;
623   res = new_ir_node (irg, block, op_Load, mode_T, 2, in);
624
625   res = optimize (res);
626   ir_vrfy (res);
627   return res;
628 }
629
630 inline ir_node *
631 new_r_Store (ir_graph *irg, ir_node *block,
632              ir_node *store, ir_node *adr, ir_node *val)
633 {
634   ir_node *in[3] = {store, adr, val};
635   ir_node *res;
636   res = new_ir_node (irg, block, op_Store, mode_T, 3, in);
637
638   res = optimize (res);
639   ir_vrfy (res);
640   return res;
641 }
642
643 inline ir_node *
644 new_r_Alloc (ir_graph *irg, ir_node *block, ir_node *store,
645             ir_node *size, type *alloc_type, where_alloc where)
646 {
647   ir_node *in[2] = {store, size};
648   ir_node *res;
649   res = new_ir_node (irg, block, op_Alloc, mode_T, 2, in);
650
651   res->attr.a.where = where;
652   res->attr.a.type = alloc_type;
653
654   res = optimize (res);
655   ir_vrfy (res);
656   return res;
657 }
658
659 inline ir_node *
660 new_r_Free (ir_graph *irg, ir_node *block, ir_node *store,
661             ir_node *ptr, ir_node *size, type *free_type)
662 {
663   ir_node *in[3] = {store, ptr, size};
664   ir_node *res;
665   res = new_ir_node (irg, block, op_Free, mode_T, 3, in);
666
667   res->attr.f = free_type;
668
669   res = optimize (res);
670   ir_vrfy (res);
671   return res;
672 }
673
674 inline ir_node *
675 new_r_Sel (ir_graph *irg, ir_node *block, ir_node *store, ir_node *objptr,
676            int arity, ir_node **in, entity *ent)
677 {
678   ir_node **r_in;
679   ir_node *res;
680   int r_arity;
681
682   r_arity = arity + 2;
683   NEW_ARR_A (ir_node *, r_in, r_arity);
684   r_in[0] = store;
685   r_in[1] = objptr;
686   memcpy (&r_in[2], in, sizeof (ir_node *) * arity);
687   res = new_ir_node (irg, block, op_Sel, mode_p, r_arity, r_in);
688
689   res->attr.s.ltyp = static_linkage;
690   res->attr.s.ent = ent;
691
692   res = optimize (res);
693   ir_vrfy (res);
694   return res;
695 }
696
697 inline ir_node *
698 new_r_SymConst (ir_graph *irg, ir_node *block, type_or_id *value,
699                 symconst_kind symkind)
700 {
701   ir_node *in[0] = {};
702   ir_node *res;
703   res = new_ir_node (irg, block, op_SymConst, mode_I, 0, in);
704
705   res->attr.i.num = symkind;
706   if (symkind == linkage_ptr_info) {
707     res->attr.i.tori.ptrinfo = (ident *)value;
708   } else {
709     assert (   (   (symkind == type_tag)
710                 || (symkind == size))
711             && (is_type(value)));
712     res->attr.i.tori.typ = (type *)value;
713   }
714   res = optimize (res);
715   ir_vrfy (res);
716   return res;
717 }
718
719 ir_node *
720 new_r_Sync (ir_graph *irg, ir_node *block, int arity, ir_node **in)
721 {
722   ir_node *res;
723
724   res = new_ir_node (irg, block, op_Sync, mode_M, arity, in);
725
726   res = optimize (res);
727   ir_vrfy (res);
728   return res;
729 }
730
731
732 ir_node *
733 new_r_Bad (ir_node *block)
734 {
735   return current_ir_graph->bad;
736 }
737
738 /***********************/
739 /** public interfaces  */
740 /** construction tools */
741
742 ir_node *
743 new_Start (void)
744 {
745   ir_node *res;
746
747   res = new_ir_node (current_ir_graph, current_ir_graph->current_block,
748                      op_Start, mode_T, 0, NULL);
749
750   res = optimize (res);
751   ir_vrfy (res);
752   return res;
753 }
754
755
756 ir_node *
757 new_End (void)
758 {
759   ir_node *res;
760
761   res = new_ir_node (current_ir_graph,  current_ir_graph->current_block,
762                      op_End, mode_X, -1, NULL);
763
764   res = optimize (res);
765   ir_vrfy (res);
766   return res;
767
768 }
769
770 ir_node *
771 new_Block (void)
772 {
773   ir_node *res;
774
775   res = new_ir_node (current_ir_graph, NULL, op_Block, mode_R, -1, NULL);
776   current_ir_graph->current_block = res;
777   res->attr.block.matured = 0;
778   set_Block_block_visit(res, 0);
779
780   /* forget this optimization. use this only if mature !!!!
781   res = optimize (res); */
782   ir_vrfy (res);
783
784   /** create a new dynamic array, which stores all parameters in irnodes */
785   /** using the same obstack as the whole irgraph */
786   res->attr.block.graph_arr = NEW_ARR_D (ir_node *, current_ir_graph->obst,
787                                          current_ir_graph->params);
788
789   /** initialize the parameter array */
790   memset(res->attr.block.graph_arr, 0, sizeof(ir_node *)*current_ir_graph->params);
791
792   return res;
793 }
794
795
796 ir_node *
797 new_Phi (int arity, ir_node **in, ir_mode *mode)
798 {
799   return new_r_Phi (current_ir_graph, current_ir_graph->current_block,
800                     arity, in, mode);
801 }
802
803 ir_node *
804 new_Const (ir_mode *mode, tarval *con)
805 {
806   return new_r_Const (current_ir_graph, current_ir_graph->start_block,
807                       mode, con);
808 }
809
810 ir_node *
811 new_Id (ir_node *val, ir_mode *mode)
812 {
813   return new_r_Id (current_ir_graph, current_ir_graph->current_block,
814                    val, mode);
815 }
816
817 ir_node *
818 new_Proj (ir_node *arg, ir_mode *mode, long proj)
819 {
820   return new_r_Proj (current_ir_graph, current_ir_graph->current_block,
821                      arg, mode, proj);
822 }
823
824 ir_node *
825 new_Conv (ir_node *op, ir_mode *mode)
826 {
827   return new_r_Conv (current_ir_graph, current_ir_graph->current_block,
828                      op, mode);
829 }
830
831 ir_node *
832 new_Tuple (int arity, ir_node **in)
833 {
834   return new_r_Tuple (current_ir_graph, current_ir_graph->current_block,
835                       arity, in);
836 }
837
838 ir_node *
839 new_Add (ir_node *op1, ir_node *op2, ir_mode *mode)
840 {
841   return new_r_Add (current_ir_graph, current_ir_graph->current_block,
842                     op1, op2, mode);
843 }
844
845 ir_node *
846 new_Sub (ir_node *op1, ir_node *op2, ir_mode *mode)
847 {
848   return new_r_Sub (current_ir_graph, current_ir_graph->current_block,
849                     op1, op2, mode);
850 }
851
852
853 ir_node *
854 new_Minus  (ir_node *op,  ir_mode *mode)
855 {
856   return new_r_Minus (current_ir_graph, current_ir_graph->current_block,
857                       op, mode);
858 }
859
860 ir_node *
861 new_Mul (ir_node *op1, ir_node *op2, ir_mode *mode)
862 {
863   return new_r_Mul (current_ir_graph, current_ir_graph->current_block,
864                     op1, op2, mode);
865 }
866
867 ir_node *
868 new_Quot (ir_node *memop, ir_node *op1, ir_node *op2)
869 {
870   return new_r_Quot (current_ir_graph, current_ir_graph->current_block,
871                      memop, op1, op2);
872 }
873
874 ir_node *
875 new_DivMod (ir_node *memop, ir_node *op1, ir_node *op2)
876 {
877   return new_r_DivMod (current_ir_graph, current_ir_graph->current_block,
878                        memop, op1, op2);
879 }
880
881 ir_node *
882 new_Div (ir_node *memop, ir_node *op1, ir_node *op2)
883 {
884   return new_r_Div (current_ir_graph, current_ir_graph->current_block,
885                     memop, op1, op2);
886 }
887
888 ir_node *
889 new_Mod (ir_node *memop, ir_node *op1, ir_node *op2)
890 {
891   return new_r_Mod (current_ir_graph, current_ir_graph->current_block,
892                     memop, op1, op2);
893 }
894
895 ir_node *
896 new_And (ir_node *op1, ir_node *op2, ir_mode *mode)
897 {
898   return new_r_And (current_ir_graph, current_ir_graph->current_block,
899                     op1, op2, mode);
900 }
901
902 ir_node *
903 new_Or (ir_node *op1, ir_node *op2, ir_mode *mode)
904 {
905   return new_r_Or (current_ir_graph, current_ir_graph->current_block,
906                    op1, op2, mode);
907 }
908
909 ir_node *
910 new_Eor (ir_node *op1, ir_node *op2, ir_mode *mode)
911 {
912   return new_r_Eor (current_ir_graph, current_ir_graph->current_block,
913                     op1, op2, mode);
914 }
915
916 ir_node *
917 new_Not (ir_node *op, ir_mode *mode)
918 {
919   return new_r_Not (current_ir_graph, current_ir_graph->current_block,
920                     op, mode);
921 }
922
923 ir_node *
924 new_Shl (ir_node *op, ir_node *k, ir_mode *mode)
925 {
926   return new_r_Shl (current_ir_graph, current_ir_graph->current_block,
927                     op, k, mode);
928 }
929
930 ir_node *
931 new_Shr (ir_node *op, ir_node *k, ir_mode *mode)
932 {
933   return new_r_Shr (current_ir_graph, current_ir_graph->current_block,
934                     op, k, mode);
935 }
936
937 ir_node *
938 new_Shrs (ir_node *op, ir_node *k, ir_mode *mode)
939 {
940   return new_r_Shrs (current_ir_graph, current_ir_graph->current_block,
941                      op, k, mode);
942 }
943
944 ir_node *
945 new_Rotate (ir_node *op, ir_node *k, ir_mode *mode)
946 {
947   return new_r_Rot (current_ir_graph, current_ir_graph->current_block,
948                      op, k, mode);
949 }
950
951 ir_node *
952 new_Abs (ir_node *op, ir_mode *mode)
953 {
954   return new_r_Abs (current_ir_graph, current_ir_graph->current_block,
955                     op, mode);
956 }
957
958 ir_node *
959 new_Cmp (ir_node *op1, ir_node *op2)
960 {
961   return new_r_Cmp (current_ir_graph, current_ir_graph->current_block,
962                     op1, op2);
963 }
964
965 ir_node *
966 new_Jmp (void)
967 {
968   return new_r_Jmp (current_ir_graph, current_ir_graph->current_block);
969 }
970
971 ir_node *
972 new_Cond (ir_node *c)
973 {
974   return new_r_Cond (current_ir_graph, current_ir_graph->current_block, c);
975 }
976
977 ir_node *
978 new_Call (ir_node *store, ir_node *callee, int arity, ir_node **in,
979           type_method *type)
980 {
981   return new_r_Call (current_ir_graph, current_ir_graph->current_block,
982                      store, callee, arity, in, type);
983 }
984
985 /* make M parameter in call explicit:
986 new_Return (ir_node* store, int arity, ir_node **in) */
987 ir_node *
988 new_Return (ir_node* store, int arity, ir_node **in)
989 {
990   return new_r_Return (current_ir_graph, current_ir_graph->current_block,
991                        store, arity, in);
992 }
993
994 ir_node *
995 new_Raise (ir_node *store, ir_node *obj)
996 {
997   return new_r_Raise (current_ir_graph, current_ir_graph->current_block,
998                       store, obj);
999 }
1000
1001 ir_node *
1002 new_Load (ir_node *store, ir_node *addr)
1003 {
1004   return new_r_Load (current_ir_graph, current_ir_graph->current_block,
1005                      store, addr);
1006 }
1007
1008 ir_node *
1009 new_Store (ir_node *store, ir_node *addr, ir_node *val)
1010 {
1011   return new_r_Store (current_ir_graph, current_ir_graph->current_block,
1012                       store, addr, val);
1013 }
1014
1015 ir_node *
1016 new_Alloc (ir_node *store, ir_node *size, type *alloc_type,
1017            where_alloc where)
1018 {
1019   return new_r_Alloc (current_ir_graph, current_ir_graph->current_block,
1020                       store, size, alloc_type, where);
1021 }
1022
1023 ir_node *
1024 new_Free (ir_node *store, ir_node *ptr, ir_node *size, type *free_type)
1025 {
1026   return new_r_Free (current_ir_graph, current_ir_graph->current_block,
1027                      store, ptr, size, free_type);
1028 }
1029
1030 ir_node *
1031 new_simpleSel (ir_node *store, ir_node *objptr, entity *ent)
1032 /* GL: objptr was called frame before.  Frame was a bad choice for the name
1033    as the operand could as well be a pointer to a dynamic object. */
1034 {
1035   return new_r_Sel (current_ir_graph, current_ir_graph->current_block,
1036                     store, objptr, 0, NULL, ent);
1037 }
1038
1039 ir_node *
1040 new_Sel (ir_node *store, ir_node *objptr, int n_index, ir_node **index, entity *sel)
1041 {
1042   return new_r_Sel (current_ir_graph, current_ir_graph->current_block,
1043                     store, objptr, n_index, index, sel);
1044 }
1045
1046 ir_node *
1047 new_SymConst (type_or_id *value, symconst_kind kind)
1048 {
1049   return new_r_SymConst (current_ir_graph, current_ir_graph->current_block,
1050                          value, kind);
1051 }
1052
1053 ir_node *
1054 new_Sync (int arity, ir_node** in)
1055 {
1056   return new_r_Sync (current_ir_graph, current_ir_graph->current_block,
1057                      arity, in);
1058 }
1059
1060
1061 ir_node *
1062 new_Bad (void)
1063 {
1064   return current_ir_graph->bad;
1065 }
1066
1067 #if 0
1068 /************************/
1069 /* ir block constructor */
1070
1071 /* GL: what's this good for? */
1072
1073 typedef struct ir_block {
1074   char closed;
1075   char matured;
1076   /* -1 = error, 0 = OK */
1077 } ir_block;
1078
1079 ir_block *
1080 new_ir_Block(void)
1081 {
1082   ir_block *res;
1083
1084   res->closed = -1;
1085   res->matured = -1;
1086
1087   return res;
1088 }
1089 #endif
1090
1091 /* initialize */
1092
1093 /* call once for each run of the library */
1094 void
1095 init_cons (void)
1096 {
1097 }