remove lots of unnecessary and dangerous current_ir_graph usages
[libfirm] / ir / ir / irnode.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   Representation of an intermediate operation.
23  * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Michael Beck
24  * @version $Id$
25  */
26 #include "config.h"
27
28 #include <string.h>
29
30 #include "pset_new.h"
31 #include "ident.h"
32 #include "irnode_t.h"
33 #include "irgraph_t.h"
34 #include "irmode_t.h"
35 #include "irbackedge_t.h"
36 #include "irdump.h"
37 #include "irop_t.h"
38 #include "irprog_t.h"
39 #include "iredgekinds.h"
40 #include "iredges_t.h"
41 #include "ircons.h"
42 #include "error.h"
43
44 #include "irhooks.h"
45 #include "irtools.h"
46
47 #include "beinfo.h"
48
49 /* some constants fixing the positions of nodes predecessors
50    in the in array */
51 #define CALL_PARAM_OFFSET     2
52 #define BUILDIN_PARAM_OFFSET  1
53 #define SEL_INDEX_OFFSET      2
54 #define RETURN_RESULT_OFFSET  1  /* mem is not a result */
55 #define END_KEEPALIVE_OFFSET  0
56
57 static const char *pnc_name_arr [] = {
58         "pn_Cmp_False", "pn_Cmp_Eq", "pn_Cmp_Lt", "pn_Cmp_Le",
59         "pn_Cmp_Gt", "pn_Cmp_Ge", "pn_Cmp_Lg", "pn_Cmp_Leg",
60         "pn_Cmp_Uo", "pn_Cmp_Ue", "pn_Cmp_Ul", "pn_Cmp_Ule",
61         "pn_Cmp_Ug", "pn_Cmp_Uge", "pn_Cmp_Ne", "pn_Cmp_True"
62 };
63
64 /**
65  * returns the pnc name from an pnc constant
66  */
67 const char *get_pnc_string(int pnc)
68 {
69         assert(pnc >= 0 && pnc <
70                         (int) (sizeof(pnc_name_arr)/sizeof(pnc_name_arr[0])));
71         return pnc_name_arr[pnc];
72 }
73
74 /*
75  * Calculates the negated (Complement(R)) pnc condition.
76  */
77 pn_Cmp get_negated_pnc(long pnc, ir_mode *mode)
78 {
79         pnc ^= pn_Cmp_True;
80
81         /* do NOT add the Uo bit for non-floating point values */
82         if (! mode_is_float(mode))
83                 pnc &= ~pn_Cmp_Uo;
84
85         return (pn_Cmp) pnc;
86 }
87
88 /* Calculates the inversed (R^-1) pnc condition, i.e., "<" --> ">" */
89 pn_Cmp get_inversed_pnc(long pnc)
90 {
91         long code    = pnc & ~(pn_Cmp_Lt|pn_Cmp_Gt);
92         long lesser  = pnc & pn_Cmp_Lt;
93         long greater = pnc & pn_Cmp_Gt;
94
95         code |= (lesser ? pn_Cmp_Gt : 0) | (greater ? pn_Cmp_Lt : 0);
96
97         return (pn_Cmp) code;
98 }
99
100 /**
101  * Indicates, whether additional data can be registered to ir nodes.
102  * If set to 1, this is not possible anymore.
103  */
104 static int forbid_new_data = 0;
105
106 /**
107  * The amount of additional space for custom data to be allocated upon
108  * creating a new node.
109  */
110 unsigned firm_add_node_size = 0;
111
112
113 /* register new space for every node */
114 unsigned firm_register_additional_node_data(unsigned size)
115 {
116         assert(!forbid_new_data && "Too late to register additional node data");
117
118         if (forbid_new_data)
119                 return 0;
120
121         return firm_add_node_size += size;
122 }
123
124
125 void init_irnode(void)
126 {
127         /* Forbid the addition of new data to an ir node. */
128         forbid_new_data = 1;
129 }
130
131 struct struct_align {
132         char c;
133         struct s {
134                 int i;
135                 float f;
136                 double d;
137         } s;
138 };
139
140 /*
141  * irnode constructor.
142  * Create a new irnode in irg, with an op, mode, arity and
143  * some incoming irnodes.
144  * If arity is negative, a node with a dynamic array is created.
145  */
146 ir_node *new_ir_node(dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op,
147                      ir_mode *mode, int arity, ir_node **in)
148 {
149         ir_node *res;
150         unsigned align = offsetof(struct struct_align, s) - 1;
151         unsigned add_node_size = (firm_add_node_size + align) & ~align;
152         size_t node_size = offsetof(ir_node, attr) + op->attr_size + add_node_size;
153         char *p;
154         int i;
155
156         assert(irg);
157         assert(op);
158         assert(mode);
159         p = obstack_alloc(irg->obst, node_size);
160         memset(p, 0, node_size);
161         res = (ir_node *)(p + add_node_size);
162
163         res->kind     = k_ir_node;
164         res->op       = op;
165         res->mode     = mode;
166         res->visited  = 0;
167         res->node_idx = irg_register_node_idx(irg, res);
168         res->link     = NULL;
169         res->deps     = NULL;
170
171         if (arity < 0) {
172                 res->in = NEW_ARR_F(ir_node *, 1);  /* 1: space for block */
173         } else {
174                 /* not nice but necessary: End and Sync must always have a flexible array */
175                 if (op == op_End || op == op_Sync)
176                         res->in = NEW_ARR_F(ir_node *, (arity+1));
177                 else
178                         res->in = NEW_ARR_D(ir_node *, irg->obst, (arity+1));
179                 memcpy(&res->in[1], in, sizeof(ir_node *) * arity);
180         }
181
182         res->in[0]   = block;
183         set_irn_dbg_info(res, db);
184         res->out     = NULL;
185         res->node_nr = get_irp_new_node_nr();
186
187         for (i = 0; i < EDGE_KIND_LAST; ++i) {
188                 INIT_LIST_HEAD(&res->edge_info[i].outs_head);
189                 /* edges will be build immediately */
190                 res->edge_info[i].edges_built = 1;
191                 res->edge_info[i].out_count = 0;
192         }
193
194         /* don't put this into the for loop, arity is -1 for some nodes! */
195         edges_notify_edge(res, -1, res->in[0], NULL, irg);
196         for (i = 1; i <= arity; ++i)
197                 edges_notify_edge(res, i - 1, res->in[i], NULL, irg);
198
199         hook_new_node(irg, res);
200         if (get_irg_phase_state(irg) == phase_backend) {
201                 be_info_new_node(res);
202         }
203
204         return res;
205 }
206
207 /*-- getting some parameters from ir_nodes --*/
208
209 int (is_ir_node)(const void *thing)
210 {
211         return _is_ir_node(thing);
212 }
213
214 int (get_irn_arity)(const ir_node *node)
215 {
216         return _get_irn_arity(node);
217 }
218
219 /* Returns the array with ins. This array is shifted with respect to the
220    array accessed by get_irn_n: The block operand is at position 0 not -1.
221    (@@@ This should be changed.)
222    The order of the predecessors in this array is not guaranteed, except that
223    lists of operands as predecessors of Block or arguments of a Call are
224    consecutive. */
225 ir_node **get_irn_in(const ir_node *node)
226 {
227         return node->in;
228 }
229
230 void set_irn_in(ir_node *node, int arity, ir_node **in)
231 {
232         int i;
233         ir_node *** pOld_in;
234         ir_graph *irg = get_irn_irg(node);
235
236         pOld_in = &node->in;
237
238
239         for (i = 0; i < arity; i++) {
240                 if (i < ARR_LEN(*pOld_in)-1)
241                         edges_notify_edge(node, i, in[i], (*pOld_in)[i+1], irg);
242                 else
243                         edges_notify_edge(node, i, in[i], NULL,            irg);
244         }
245         for (;i < ARR_LEN(*pOld_in)-1; i++) {
246                 edges_notify_edge(node, i, NULL, (*pOld_in)[i+1], irg);
247         }
248
249         if (arity != ARR_LEN(*pOld_in) - 1) {
250                 ir_node * block = (*pOld_in)[0];
251                 *pOld_in = NEW_ARR_D(ir_node *, irg->obst, arity + 1);
252                 (*pOld_in)[0] = block;
253         }
254         fix_backedges(irg->obst, node);
255
256         memcpy((*pOld_in) + 1, in, sizeof(ir_node *) * arity);
257 }
258
259 ir_node *(get_irn_n)(const ir_node *node, int n)
260 {
261         return _get_irn_n(node, n);
262 }
263
264 void set_irn_n(ir_node *node, int n, ir_node *in)
265 {
266         ir_graph *irg = get_irn_irg(node);
267         assert(node && node->kind == k_ir_node);
268         assert(-1 <= n);
269         assert(n < get_irn_arity(node));
270         assert(in && in->kind == k_ir_node);
271
272         /* Call the hook */
273         hook_set_irn_n(node, n, in, node->in[n + 1]);
274
275         /* Here, we rely on src and tgt being in the current ir graph */
276         edges_notify_edge(node, n, in, node->in[n + 1], irg);
277
278         node->in[n + 1] = in;
279 }
280
281 int add_irn_n(ir_node *node, ir_node *in)
282 {
283         int pos;
284         ir_graph *irg = get_irn_irg(node);
285
286         assert(node->op->opar == oparity_dynamic);
287         pos = ARR_LEN(node->in) - 1;
288         ARR_APP1(ir_node *, node->in, in);
289         edges_notify_edge(node, pos, node->in[pos + 1], NULL, irg);
290
291         /* Call the hook */
292         hook_set_irn_n(node, pos, node->in[pos + 1], NULL);
293
294         return pos;
295 }
296
297 void del_Sync_n(ir_node *n, int i)
298 {
299         int      arity     = get_Sync_n_preds(n);
300         ir_node *last_pred = get_Sync_pred(n, arity - 1);
301         set_Sync_pred(n, i, last_pred);
302         edges_notify_edge(n, arity - 1, NULL, last_pred, get_irn_irg(n));
303         ARR_SHRINKLEN(get_irn_in(n), arity);
304 }
305
306 int (get_irn_deps)(const ir_node *node)
307 {
308         return _get_irn_deps(node);
309 }
310
311 ir_node *(get_irn_dep)(const ir_node *node, int pos)
312 {
313         return _get_irn_dep(node, pos);
314 }
315
316 void (set_irn_dep)(ir_node *node, int pos, ir_node *dep)
317 {
318         _set_irn_dep(node, pos, dep);
319 }
320
321 int add_irn_dep(ir_node *node, ir_node *dep)
322 {
323         int res = 0;
324
325         /* DEP edges are only allowed in backend phase */
326         assert(get_irg_phase_state(get_irn_irg(node)) == phase_backend);
327         if (node->deps == NULL) {
328                 node->deps = NEW_ARR_F(ir_node *, 1);
329                 node->deps[0] = dep;
330         } else {
331                 int i, n;
332                 int first_zero = -1;
333
334                 for (i = 0, n = ARR_LEN(node->deps); i < n; ++i) {
335                         if (node->deps[i] == NULL)
336                                 first_zero = i;
337
338                         if (node->deps[i] == dep)
339                                 return i;
340                 }
341
342                 if (first_zero >= 0) {
343                         node->deps[first_zero] = dep;
344                         res = first_zero;
345                 } else {
346                         ARR_APP1(ir_node *, node->deps, dep);
347                         res = n;
348                 }
349         }
350
351         edges_notify_edge_kind(node, res, dep, NULL, EDGE_KIND_DEP, get_irn_irg(node));
352
353         return res;
354 }
355
356 void add_irn_deps(ir_node *tgt, ir_node *src)
357 {
358         int i, n;
359
360         for (i = 0, n = get_irn_deps(src); i < n; ++i)
361                 add_irn_dep(tgt, get_irn_dep(src, i));
362 }
363
364
365 ir_mode *(get_irn_mode)(const ir_node *node)
366 {
367         return _get_irn_mode(node);
368 }
369
370 void (set_irn_mode)(ir_node *node, ir_mode *mode)
371 {
372         _set_irn_mode(node, mode);
373 }
374
375 /** Gets the string representation of the mode .*/
376 const char *get_irn_modename(const ir_node *node)
377 {
378         assert(node);
379         return get_mode_name(node->mode);
380 }
381
382 ident *get_irn_modeident(const ir_node *node)
383 {
384         assert(node);
385         return get_mode_ident(node->mode);
386 }
387
388 ir_op *(get_irn_op)(const ir_node *node)
389 {
390         return _get_irn_op(node);
391 }
392
393 /* should be private to the library: */
394 void (set_irn_op)(ir_node *node, ir_op *op)
395 {
396         _set_irn_op(node, op);
397 }
398
399 unsigned (get_irn_opcode)(const ir_node *node)
400 {
401         return _get_irn_opcode(node);
402 }
403
404 const char *get_irn_opname(const ir_node *node)
405 {
406         assert(node);
407         if (is_Phi0(node)) return "Phi0";
408         return get_id_str(node->op->name);
409 }
410
411 ident *get_irn_opident(const ir_node *node)
412 {
413         assert(node);
414         return node->op->name;
415 }
416
417 ir_visited_t (get_irn_visited)(const ir_node *node)
418 {
419         return _get_irn_visited(node);
420 }
421
422 void (set_irn_visited)(ir_node *node, ir_visited_t visited)
423 {
424         _set_irn_visited(node, visited);
425 }
426
427 void (mark_irn_visited)(ir_node *node)
428 {
429         _mark_irn_visited(node);
430 }
431
432 int (irn_visited)(const ir_node *node)
433 {
434         return _irn_visited(node);
435 }
436
437 int (irn_visited_else_mark)(ir_node *node)
438 {
439         return _irn_visited_else_mark(node);
440 }
441
442 void (set_irn_link)(ir_node *node, void *link)
443 {
444         _set_irn_link(node, link);
445 }
446
447 void *(get_irn_link)(const ir_node *node)
448 {
449         return _get_irn_link(node);
450 }
451
452 op_pin_state (get_irn_pinned)(const ir_node *node)
453 {
454         return _get_irn_pinned(node);
455 }
456
457 op_pin_state (is_irn_pinned_in_irg) (const ir_node *node)
458 {
459         return _is_irn_pinned_in_irg(node);
460 }
461
462 void set_irn_pinned(ir_node *node, op_pin_state state)
463 {
464         /* due to optimization an opt may be turned into a Tuple */
465         if (is_Tuple(node))
466                 return;
467
468         assert(node && get_op_pinned(get_irn_op(node)) >= op_pin_state_exc_pinned);
469         assert(state == op_pin_state_pinned || state == op_pin_state_floats);
470
471         node->attr.except.pin_state = state;
472 }
473
474 /* Outputs a unique number for this node */
475 long get_irn_node_nr(const ir_node *node)
476 {
477         assert(node);
478         return node->node_nr;
479 }
480
481 void *(get_irn_generic_attr)(ir_node *node)
482 {
483         assert(is_ir_node(node));
484         return _get_irn_generic_attr(node);
485 }
486
487 const void *(get_irn_generic_attr_const)(const ir_node *node)
488 {
489         assert(is_ir_node(node));
490         return _get_irn_generic_attr_const(node);
491 }
492
493 unsigned (get_irn_idx)(const ir_node *node)
494 {
495         assert(is_ir_node(node));
496         return _get_irn_idx(node);
497 }
498
499 int get_irn_pred_pos(ir_node *node, ir_node *arg)
500 {
501         int i;
502         for (i = get_irn_arity(node) - 1; i >= 0; i--) {
503                 if (get_irn_n(node, i) == arg)
504                         return i;
505         }
506         return -1;
507 }
508
509 /** manipulate fields of individual nodes **/
510
511 /* this works for all except Block */
512 ir_node *get_nodes_block(const ir_node *node)
513 {
514         assert(node->op != op_Block);
515         return get_irn_n(node, -1);
516 }
517
518 void set_nodes_block(ir_node *node, ir_node *block)
519 {
520         assert(node->op != op_Block);
521         set_irn_n(node, -1, block);
522 }
523
524 /* this works for all except Block */
525 ir_node *get_nodes_MacroBlock(const ir_node *node)
526 {
527         assert(node->op != op_Block);
528         return get_Block_MacroBlock(get_irn_n(node, -1));
529 }
530
531 /* Test whether arbitrary node is frame pointer, i.e. Proj(pn_Start_P_frame_base)
532  * from Start.  If so returns frame type, else Null. */
533 ir_type *is_frame_pointer(const ir_node *n)
534 {
535         if (is_Proj(n) && (get_Proj_proj(n) == pn_Start_P_frame_base)) {
536                 ir_node *start = get_Proj_pred(n);
537                 if (is_Start(start)) {
538                         return get_irg_frame_type(get_irn_irg(start));
539                 }
540         }
541         return NULL;
542 }
543
544 /* Test whether arbitrary node is tls pointer, i.e. Proj(pn_Start_P_tls)
545  * from Start.  If so returns tls type, else Null. */
546 ir_type *is_tls_pointer(const ir_node *n)
547 {
548         if (is_Proj(n) && (get_Proj_proj(n) == pn_Start_P_tls)) {
549                 ir_node *start = get_Proj_pred(n);
550                 if (is_Start(start)) {
551                         return get_tls_type();
552                 }
553         }
554         return NULL;
555 }
556
557 ir_node **get_Block_cfgpred_arr(ir_node *node)
558 {
559         assert(is_Block(node));
560         return (ir_node **)&(get_irn_in(node)[1]);
561 }
562
563 int (get_Block_n_cfgpreds)(const ir_node *node)
564 {
565         return _get_Block_n_cfgpreds(node);
566 }
567
568 ir_node *(get_Block_cfgpred)(const ir_node *node, int pos)
569 {
570         return _get_Block_cfgpred(node, pos);
571 }
572
573 void set_Block_cfgpred(ir_node *node, int pos, ir_node *pred)
574 {
575         assert(is_Block(node));
576         set_irn_n(node, pos, pred);
577 }
578
579 int get_Block_cfgpred_pos(const ir_node *block, const ir_node *pred)
580 {
581         int i;
582
583         for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
584                 if (get_Block_cfgpred_block(block, i) == pred)
585                         return i;
586         }
587         return -1;
588 }
589
590 ir_node *(get_Block_cfgpred_block)(const ir_node *node, int pos)
591 {
592         return _get_Block_cfgpred_block(node, pos);
593 }
594
595 int get_Block_matured(const ir_node *node)
596 {
597         assert(is_Block(node));
598         return (int)node->attr.block.is_matured;
599 }
600
601 void set_Block_matured(ir_node *node, int matured)
602 {
603         assert(is_Block(node));
604         node->attr.block.is_matured = matured;
605 }
606
607 ir_visited_t (get_Block_block_visited)(const ir_node *node)
608 {
609         return _get_Block_block_visited(node);
610 }
611
612 void (set_Block_block_visited)(ir_node *node, ir_visited_t visit)
613 {
614         _set_Block_block_visited(node, visit);
615 }
616
617 void (mark_Block_block_visited)(ir_node *node)
618 {
619         _mark_Block_block_visited(node);
620 }
621
622 int (Block_block_visited)(const ir_node *node)
623 {
624         return _Block_block_visited(node);
625 }
626
627 ir_node *(set_Block_dead)(ir_node *block)
628 {
629         return _set_Block_dead(block);
630 }
631
632 int (is_Block_dead)(const ir_node *block)
633 {
634         return _is_Block_dead(block);
635 }
636
637 ir_extblk *get_Block_extbb(const ir_node *block)
638 {
639         ir_extblk *res;
640         assert(is_Block(block));
641         res = block->attr.block.extblk;
642         assert(res == NULL || is_ir_extbb(res));
643         return res;
644 }
645
646 void set_Block_extbb(ir_node *block, ir_extblk *extblk)
647 {
648         assert(is_Block(block));
649         assert(extblk == NULL || is_ir_extbb(extblk));
650         block->attr.block.extblk = extblk;
651 }
652
653 /* Returns the macro block header of a block.*/
654 ir_node *get_Block_MacroBlock(const ir_node *block)
655 {
656         ir_node *mbh;
657         assert(is_Block(block));
658         mbh = get_irn_n(block, -1);
659         /* once macro block header is respected by all optimizations,
660            this assert can be removed */
661         assert(mbh != NULL);
662         return mbh;
663 }
664
665 /* Sets the macro block header of a block. */
666 void set_Block_MacroBlock(ir_node *block, ir_node *mbh)
667 {
668         assert(is_Block(block));
669         mbh = skip_Id(mbh);
670         assert(is_Block(mbh));
671         set_irn_n(block, -1, mbh);
672 }
673
674 /* returns the macro block header of a node. */
675 ir_node *get_irn_MacroBlock(const ir_node *n)
676 {
677         if (! is_Block(n)) {
678                 n = get_nodes_block(n);
679                 /* if the Block is Bad, do NOT try to get it's MB, it will fail. */
680                 if (is_Bad(n))
681                         return (ir_node *)n;
682         }
683         return get_Block_MacroBlock(n);
684 }
685
686 /* returns the graph of a Block. */
687 ir_graph *(get_Block_irg)(const ir_node *block)
688 {
689         return _get_Block_irg(block);
690 }
691
692 ir_entity *create_Block_entity(ir_node *block)
693 {
694         ir_entity *entity;
695         assert(is_Block(block));
696
697         entity = block->attr.block.entity;
698         if (entity == NULL) {
699                 ir_label_t  nr;
700                 ir_type   *glob;
701
702                 glob = get_glob_type();
703                 entity = new_entity(glob, id_unique("block_%u"), get_code_type());
704                 set_entity_visibility(entity, ir_visibility_local);
705                 set_entity_linkage(entity, IR_LINKAGE_CONSTANT);
706                 nr = get_irp_next_label_nr();
707                 set_entity_label(entity, nr);
708                 set_entity_compiler_generated(entity, 1);
709
710                 block->attr.block.entity = entity;
711         }
712         return entity;
713 }
714
715 ir_entity *get_Block_entity(const ir_node *block)
716 {
717         assert(is_Block(block));
718         return block->attr.block.entity;
719 }
720
721 void set_Block_entity(ir_node *block, ir_entity *entity)
722 {
723         assert(is_Block(block));
724         assert(get_entity_type(entity) == get_code_type());
725         block->attr.block.entity = entity;
726 }
727
728 int has_Block_entity(const ir_node *block)
729 {
730         return block->attr.block.entity != NULL;
731 }
732
733 ir_node *(get_Block_phis)(const ir_node *block)
734 {
735         return _get_Block_phis(block);
736 }
737
738 void (set_Block_phis)(ir_node *block, ir_node *phi)
739 {
740         _set_Block_phis(block, phi);
741 }
742
743 void (add_Block_phi)(ir_node *block, ir_node *phi)
744 {
745         _add_Block_phi(block, phi);
746 }
747
748 /* Get the Block mark (single bit). */
749 unsigned (get_Block_mark)(const ir_node *block)
750 {
751         return _get_Block_mark(block);
752 }
753
754 /* Set the Block mark (single bit). */
755 void (set_Block_mark)(ir_node *block, unsigned mark)
756 {
757         _set_Block_mark(block, mark);
758 }
759
760 int get_End_n_keepalives(const ir_node *end)
761 {
762         assert(is_End(end));
763         return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
764 }
765
766 ir_node *get_End_keepalive(const ir_node *end, int pos)
767 {
768         assert(is_End(end));
769         return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
770 }
771
772 void add_End_keepalive(ir_node *end, ir_node *ka)
773 {
774         assert(is_End(end));
775         add_irn_n(end, ka);
776 }
777
778 void set_End_keepalive(ir_node *end, int pos, ir_node *ka)
779 {
780         assert(is_End(end));
781         set_irn_n(end, pos + END_KEEPALIVE_OFFSET, ka);
782 }
783
784 /* Set new keep-alives */
785 void set_End_keepalives(ir_node *end, int n, ir_node *in[])
786 {
787         int i;
788         ir_graph *irg = get_irn_irg(end);
789
790         /* notify that edges are deleted */
791         for (i = END_KEEPALIVE_OFFSET; i < ARR_LEN(end->in) - 1; ++i) {
792                 edges_notify_edge(end, i, NULL, end->in[i + 1], irg);
793         }
794         ARR_RESIZE(ir_node *, end->in, n + 1 + END_KEEPALIVE_OFFSET);
795
796         for (i = 0; i < n; ++i) {
797                 end->in[1 + END_KEEPALIVE_OFFSET + i] = in[i];
798                 edges_notify_edge(end, END_KEEPALIVE_OFFSET + i, end->in[1 + END_KEEPALIVE_OFFSET + i], NULL, irg);
799         }
800 }
801
802 /* Set new keep-alives from old keep-alives, skipping irn */
803 void remove_End_keepalive(ir_node *end, ir_node *irn)
804 {
805         int      n = get_End_n_keepalives(end);
806         int      i, idx;
807         ir_graph *irg;
808
809         idx = -1;
810         for (i = n -1; i >= 0; --i) {
811                 ir_node *old_ka = end->in[1 + END_KEEPALIVE_OFFSET + i];
812
813                 /* find irn */
814                 if (old_ka == irn) {
815                         idx = i;
816                         goto found;
817                 }
818         }
819         return;
820 found:
821         irg = get_irn_irg(end);
822
823         /* remove the edge */
824         edges_notify_edge(end, idx, NULL, irn, irg);
825
826         if (idx != n - 1) {
827                 /* exchange with the last one */
828                 ir_node *old = end->in[1 + END_KEEPALIVE_OFFSET + n - 1];
829                 edges_notify_edge(end, n - 1, NULL, old, irg);
830                 end->in[1 + END_KEEPALIVE_OFFSET + idx] = old;
831                 edges_notify_edge(end, idx, old, NULL, irg);
832         }
833         /* now n - 1 keeps, 1 block input */
834         ARR_RESIZE(ir_node *, end->in, (n - 1) + 1 + END_KEEPALIVE_OFFSET);
835 }
836
837 /* remove Bads, NoMems and doublets from the keep-alive set */
838 void remove_End_Bads_and_doublets(ir_node *end)
839 {
840         pset_new_t keeps;
841         int        idx, n = get_End_n_keepalives(end);
842         ir_graph   *irg;
843
844         if (n <= 0)
845                 return;
846
847         irg = get_irn_irg(end);
848         pset_new_init(&keeps);
849
850         for (idx = n - 1; idx >= 0; --idx) {
851                 ir_node *ka = get_End_keepalive(end, idx);
852
853                 if (is_Bad(ka) || is_NoMem(ka) || pset_new_contains(&keeps, ka)) {
854                         /* remove the edge */
855                         edges_notify_edge(end, idx, NULL, ka, irg);
856
857                         if (idx != n - 1) {
858                                 /* exchange with the last one */
859                                 ir_node *old = end->in[1 + END_KEEPALIVE_OFFSET + n - 1];
860                                 edges_notify_edge(end, n - 1, NULL, old, irg);
861                                 end->in[1 + END_KEEPALIVE_OFFSET + idx] = old;
862                                 edges_notify_edge(end, idx, old, NULL, irg);
863                         }
864                         --n;
865                 } else {
866                         pset_new_insert(&keeps, ka);
867                 }
868         }
869         /* n keeps, 1 block input */
870         ARR_RESIZE(ir_node *, end->in, n + 1 + END_KEEPALIVE_OFFSET);
871
872         pset_new_destroy(&keeps);
873 }
874
875 void free_End(ir_node *end)
876 {
877         assert(is_End(end));
878         end->kind = k_BAD;
879         DEL_ARR_F(end->in);
880         end->in = NULL;   /* @@@ make sure we get an error if we use the
881                              in array afterwards ... */
882 }
883
884 int get_Return_n_ress(const ir_node *node)
885 {
886         assert(is_Return(node));
887         return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
888 }
889
890 ir_node **get_Return_res_arr(ir_node *node)
891 {
892         assert(is_Return(node));
893         if (get_Return_n_ress(node) > 0)
894                 return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
895         else
896                 return NULL;
897 }
898
899 /*
900 void set_Return_n_res(ir_node *node, int results)
901 {
902         assert(is_Return(node));
903 }
904 */
905
906 ir_node *get_Return_res(const ir_node *node, int pos)
907 {
908         assert(is_Return(node));
909         assert(get_Return_n_ress(node) > pos);
910         return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
911 }
912
913 void set_Return_res(ir_node *node, int pos, ir_node *res)
914 {
915         assert(is_Return(node));
916         set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
917 }
918
919 int (is_Const_null)(const ir_node *node)
920 {
921         return _is_Const_null(node);
922 }
923
924 int (is_Const_one)(const ir_node *node)
925 {
926         return _is_Const_one(node);
927 }
928
929 int (is_Const_all_one)(const ir_node *node)
930 {
931         return _is_Const_all_one(node);
932 }
933
934
935 /* The source language type.  Must be an atomic type.  Mode of type must
936    be mode of node. For tarvals from entities type must be pointer to
937    entity type. */
938 ir_type *get_Const_type(const ir_node *node)
939 {
940         assert(is_Const(node));
941         return node->attr.con.tp;
942 }
943
944 void set_Const_type(ir_node *node, ir_type *tp)
945 {
946         assert(is_Const(node));
947         if (tp != firm_unknown_type) {
948                 assert(is_atomic_type(tp));
949                 assert(get_type_mode(tp) == get_irn_mode(node));
950         }
951         node->attr.con.tp = tp;
952 }
953
954
955 symconst_kind get_SymConst_kind(const ir_node *node)
956 {
957         assert(is_SymConst(node));
958         return node->attr.symc.kind;
959 }
960
961 void set_SymConst_kind(ir_node *node, symconst_kind kind)
962 {
963         assert(is_SymConst(node));
964         node->attr.symc.kind = kind;
965 }
966
967 ir_type *get_SymConst_type(const ir_node *node)
968 {
969         /* the cast here is annoying, but we have to compensate for
970            the skip_tip() */
971         ir_node *irn = (ir_node *)node;
972         assert(is_SymConst(node) &&
973                (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
974         return irn->attr.symc.sym.type_p;
975 }
976
977 void set_SymConst_type(ir_node *node, ir_type *tp)
978 {
979         assert(is_SymConst(node) &&
980                (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
981         node->attr.symc.sym.type_p = tp;
982 }
983
984
985 /* Only to access SymConst of kind symconst_addr_ent.  Else assertion: */
986 ir_entity *get_SymConst_entity(const ir_node *node)
987 {
988         assert(is_SymConst(node) && SYMCONST_HAS_ENT(get_SymConst_kind(node)));
989         return node->attr.symc.sym.entity_p;
990 }
991
992 void set_SymConst_entity(ir_node *node, ir_entity *ent)
993 {
994         assert(is_SymConst(node) && SYMCONST_HAS_ENT(get_SymConst_kind(node)));
995         node->attr.symc.sym.entity_p  = ent;
996 }
997
998 ir_enum_const *get_SymConst_enum(const ir_node *node)
999 {
1000         assert(is_SymConst(node) && SYMCONST_HAS_ENUM(get_SymConst_kind(node)));
1001         return node->attr.symc.sym.enum_p;
1002 }
1003
1004 void set_SymConst_enum(ir_node *node, ir_enum_const *ec)
1005 {
1006         assert(is_SymConst(node) && SYMCONST_HAS_ENUM(get_SymConst_kind(node)));
1007         node->attr.symc.sym.enum_p  = ec;
1008 }
1009
1010 union symconst_symbol
1011 get_SymConst_symbol(const ir_node *node)
1012 {
1013         assert(is_SymConst(node));
1014         return node->attr.symc.sym;
1015 }
1016
1017 void set_SymConst_symbol(ir_node *node, union symconst_symbol sym)
1018 {
1019         assert(is_SymConst(node));
1020         node->attr.symc.sym = sym;
1021 }
1022
1023 ir_type *get_SymConst_value_type(const ir_node *node)
1024 {
1025         assert(is_SymConst(node));
1026         return node->attr.symc.tp;
1027 }
1028
1029 void set_SymConst_value_type(ir_node *node, ir_type *tp)
1030 {
1031         assert(is_SymConst(node));
1032         node->attr.symc.tp = tp;
1033 }
1034
1035 int get_Sel_n_indexs(const ir_node *node)
1036 {
1037         assert(is_Sel(node));
1038         return (get_irn_arity(node) - SEL_INDEX_OFFSET);
1039 }
1040
1041 ir_node **get_Sel_index_arr(ir_node *node)
1042 {
1043         assert(is_Sel(node));
1044         if (get_Sel_n_indexs(node) > 0)
1045                 return (ir_node **)& get_irn_in(node)[SEL_INDEX_OFFSET + 1];
1046         else
1047                 return NULL;
1048 }
1049
1050 ir_node *get_Sel_index(const ir_node *node, int pos)
1051 {
1052         assert(is_Sel(node));
1053         return get_irn_n(node, pos + SEL_INDEX_OFFSET);
1054 }
1055
1056 void set_Sel_index(ir_node *node, int pos, ir_node *index)
1057 {
1058         assert(is_Sel(node));
1059         set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
1060 }
1061
1062
1063 /* For unary and binary arithmetic operations the access to the
1064    operands can be factored out.  Left is the first, right the
1065    second arithmetic value  as listed in tech report 0999-33.
1066    unops are: Minus, Abs, Not, Conv, Cast
1067    binops are: Add, Sub, Mul, Quot, DivMod, Div, Mod, And, Or, Eor, Shl,
1068    Shr, Shrs, Rotate, Cmp */
1069
1070
1071 ir_node **get_Call_param_arr(ir_node *node)
1072 {
1073         assert(is_Call(node));
1074         return &get_irn_in(node)[CALL_PARAM_OFFSET + 1];
1075 }
1076
1077 int get_Call_n_params(const ir_node *node)
1078 {
1079         assert(is_Call(node));
1080         return (get_irn_arity(node) - CALL_PARAM_OFFSET);
1081 }
1082
1083 ir_node *get_Call_param(const ir_node *node, int pos)
1084 {
1085         assert(is_Call(node));
1086         return get_irn_n(node, pos + CALL_PARAM_OFFSET);
1087 }
1088
1089 void set_Call_param(ir_node *node, int pos, ir_node *param)
1090 {
1091         assert(is_Call(node));
1092         set_irn_n(node, pos + CALL_PARAM_OFFSET, param);
1093 }
1094
1095 ir_node **get_Builtin_param_arr(ir_node *node)
1096 {
1097         assert(is_Builtin(node));
1098         return &get_irn_in(node)[BUILDIN_PARAM_OFFSET + 1];
1099 }
1100
1101 int get_Builtin_n_params(const ir_node *node)
1102 {
1103         assert(is_Builtin(node));
1104         return (get_irn_arity(node) - BUILDIN_PARAM_OFFSET);
1105 }
1106
1107 ir_node *get_Builtin_param(const ir_node *node, int pos)
1108 {
1109         assert(is_Builtin(node));
1110         return get_irn_n(node, pos + BUILDIN_PARAM_OFFSET);
1111 }
1112
1113 void set_Builtin_param(ir_node *node, int pos, ir_node *param)
1114 {
1115         assert(is_Builtin(node));
1116         set_irn_n(node, pos + BUILDIN_PARAM_OFFSET, param);
1117 }
1118
1119 /* Returns a human readable string for the ir_builtin_kind. */
1120 const char *get_builtin_kind_name(ir_builtin_kind kind)
1121 {
1122 #define X(a)    case a: return #a
1123         switch (kind) {
1124                 X(ir_bk_trap);
1125                 X(ir_bk_debugbreak);
1126                 X(ir_bk_return_address);
1127                 X(ir_bk_frame_address);
1128                 X(ir_bk_prefetch);
1129                 X(ir_bk_ffs);
1130                 X(ir_bk_clz);
1131                 X(ir_bk_ctz);
1132                 X(ir_bk_popcount);
1133                 X(ir_bk_parity);
1134                 X(ir_bk_bswap);
1135                 X(ir_bk_inport);
1136                 X(ir_bk_outport);
1137                 X(ir_bk_inner_trampoline);
1138         }
1139         return "<unknown>";
1140 #undef X
1141 }
1142
1143
1144 int Call_has_callees(const ir_node *node)
1145 {
1146         assert(is_Call(node));
1147         return ((get_irg_callee_info_state(get_irn_irg(node)) != irg_callee_info_none) &&
1148                 (node->attr.call.callee_arr != NULL));
1149 }
1150
1151 int get_Call_n_callees(const ir_node *node)
1152 {
1153   assert(is_Call(node) && node->attr.call.callee_arr);
1154   return ARR_LEN(node->attr.call.callee_arr);
1155 }
1156
1157 ir_entity *get_Call_callee(const ir_node *node, int pos)
1158 {
1159         assert(pos >= 0 && pos < get_Call_n_callees(node));
1160         return node->attr.call.callee_arr[pos];
1161 }
1162
1163 void set_Call_callee_arr(ir_node *node, const int n, ir_entity ** arr)
1164 {
1165         ir_graph *irg = get_irn_irg(node);
1166
1167         assert(is_Call(node));
1168         if (node->attr.call.callee_arr == NULL || get_Call_n_callees(node) != n) {
1169                 node->attr.call.callee_arr = NEW_ARR_D(ir_entity *, irg->obst, n);
1170         }
1171         memcpy(node->attr.call.callee_arr, arr, n * sizeof(ir_entity *));
1172 }
1173
1174 void remove_Call_callee_arr(ir_node *node)
1175 {
1176         assert(is_Call(node));
1177         node->attr.call.callee_arr = NULL;
1178 }
1179
1180 /*
1181  * Returns non-zero if a Call is surely a self-recursive Call.
1182  * Beware: if this functions returns 0, the call might be self-recursive!
1183  */
1184 int is_self_recursive_Call(const ir_node *call)
1185 {
1186         const ir_node *callee = get_Call_ptr(call);
1187
1188         if (is_SymConst_addr_ent(callee)) {
1189                 const ir_entity *ent = get_SymConst_entity(callee);
1190                 const ir_graph  *irg = get_entity_irg(ent);
1191                 if (irg == get_irn_irg(call))
1192                         return 1;
1193         }
1194         return 0;
1195 }
1196
1197 /* Checks for upcast.
1198  *
1199  * Returns true if the Cast node casts a class type to a super type.
1200  */
1201 int is_Cast_upcast(ir_node *node)
1202 {
1203         ir_type *totype   = get_Cast_type(node);
1204         ir_type *fromtype = get_irn_typeinfo_type(get_Cast_op(node));
1205
1206         assert(get_irg_typeinfo_state(get_irn_irg(node)) == ir_typeinfo_consistent);
1207         assert(fromtype);
1208
1209         while (is_Pointer_type(totype) && is_Pointer_type(fromtype)) {
1210                 totype   = get_pointer_points_to_type(totype);
1211                 fromtype = get_pointer_points_to_type(fromtype);
1212         }
1213
1214         assert(fromtype);
1215
1216         if (!is_Class_type(totype)) return 0;
1217         return is_SubClass_of(fromtype, totype);
1218 }
1219
1220 /* Checks for downcast.
1221  *
1222  * Returns true if the Cast node casts a class type to a sub type.
1223  */
1224 int is_Cast_downcast(ir_node *node)
1225 {
1226         ir_type *totype   = get_Cast_type(node);
1227         ir_type *fromtype = get_irn_typeinfo_type(get_Cast_op(node));
1228
1229         assert(get_irg_typeinfo_state(get_irn_irg(node)) == ir_typeinfo_consistent);
1230         assert(fromtype);
1231
1232         while (is_Pointer_type(totype) && is_Pointer_type(fromtype)) {
1233                 totype   = get_pointer_points_to_type(totype);
1234                 fromtype = get_pointer_points_to_type(fromtype);
1235         }
1236
1237         assert(fromtype);
1238
1239         if (!is_Class_type(totype)) return 0;
1240         return is_SubClass_of(totype, fromtype);
1241 }
1242
1243 int (is_unop)(const ir_node *node)
1244 {
1245         return _is_unop(node);
1246 }
1247
1248 ir_node *get_unop_op(const ir_node *node)
1249 {
1250         if (node->op->opar == oparity_unary)
1251                 return get_irn_n(node, node->op->op_index);
1252
1253         assert(node->op->opar == oparity_unary);
1254         return NULL;
1255 }
1256
1257 void set_unop_op(ir_node *node, ir_node *op)
1258 {
1259         if (node->op->opar == oparity_unary)
1260                 set_irn_n(node, node->op->op_index, op);
1261
1262         assert(node->op->opar == oparity_unary);
1263 }
1264
1265 int (is_binop)(const ir_node *node)
1266 {
1267         return _is_binop(node);
1268 }
1269
1270 ir_node *get_binop_left(const ir_node *node)
1271 {
1272         assert(node->op->opar == oparity_binary);
1273         return get_irn_n(node, node->op->op_index);
1274 }
1275
1276 void set_binop_left(ir_node *node, ir_node *left)
1277 {
1278         assert(node->op->opar == oparity_binary);
1279         set_irn_n(node, node->op->op_index, left);
1280 }
1281
1282 ir_node *get_binop_right(const ir_node *node)
1283 {
1284         assert(node->op->opar == oparity_binary);
1285         return get_irn_n(node, node->op->op_index + 1);
1286 }
1287
1288 void set_binop_right(ir_node *node, ir_node *right)
1289 {
1290         assert(node->op->opar == oparity_binary);
1291         set_irn_n(node, node->op->op_index + 1, right);
1292 }
1293
1294 int is_Phi0(const ir_node *n)
1295 {
1296         assert(n);
1297
1298         return ((get_irn_op(n) == op_Phi) &&
1299                 (get_irn_arity(n) == 0) &&
1300                 (get_irg_phase_state(get_irn_irg(n)) ==  phase_building));
1301 }
1302
1303 ir_node **get_Phi_preds_arr(ir_node *node)
1304 {
1305   assert(node->op == op_Phi);
1306   return (ir_node **)&(get_irn_in(node)[1]);
1307 }
1308
1309 int get_Phi_n_preds(const ir_node *node)
1310 {
1311         assert(is_Phi(node) || is_Phi0(node));
1312         return (get_irn_arity(node));
1313 }
1314
1315 /*
1316 void set_Phi_n_preds(ir_node *node, int n_preds)
1317 {
1318         assert(node->op == op_Phi);
1319 }
1320 */
1321
1322 ir_node *get_Phi_pred(const ir_node *node, int pos)
1323 {
1324         assert(is_Phi(node) || is_Phi0(node));
1325         return get_irn_n(node, pos);
1326 }
1327
1328 void set_Phi_pred(ir_node *node, int pos, ir_node *pred)
1329 {
1330         assert(is_Phi(node) || is_Phi0(node));
1331         set_irn_n(node, pos, pred);
1332 }
1333
1334 ir_node *(get_Phi_next)(const ir_node *phi)
1335 {
1336         return _get_Phi_next(phi);
1337 }
1338
1339 void (set_Phi_next)(ir_node *phi, ir_node *next)
1340 {
1341         _set_Phi_next(phi, next);
1342 }
1343
1344 int is_memop(const ir_node *node)
1345 {
1346         ir_opcode code = get_irn_opcode(node);
1347         return (code == iro_Load || code == iro_Store);
1348 }
1349
1350 ir_node *get_memop_mem(const ir_node *node)
1351 {
1352         assert(is_memop(node));
1353         return get_irn_n(node, 0);
1354 }
1355
1356 void set_memop_mem(ir_node *node, ir_node *mem)
1357 {
1358         assert(is_memop(node));
1359         set_irn_n(node, 0, mem);
1360 }
1361
1362 ir_node *get_memop_ptr(const ir_node *node)
1363 {
1364         assert(is_memop(node));
1365         return get_irn_n(node, 1);
1366 }
1367
1368 void set_memop_ptr(ir_node *node, ir_node *ptr)
1369 {
1370         assert(is_memop(node));
1371         set_irn_n(node, 1, ptr);
1372 }
1373
1374 ir_volatility get_Load_volatility(const ir_node *node)
1375 {
1376         assert(is_Load(node));
1377         return node->attr.load.volatility;
1378 }
1379
1380 void set_Load_volatility(ir_node *node, ir_volatility volatility)
1381 {
1382         assert(is_Load(node));
1383         node->attr.load.volatility = volatility;
1384 }
1385
1386 ir_align get_Load_align(const ir_node *node)
1387 {
1388         assert(is_Load(node));
1389         return node->attr.load.aligned;
1390 }
1391
1392 void set_Load_align(ir_node *node, ir_align align)
1393 {
1394         assert(is_Load(node));
1395         node->attr.load.aligned = align;
1396 }
1397
1398
1399 ir_volatility get_Store_volatility(const ir_node *node)
1400 {
1401         assert(is_Store(node));
1402         return node->attr.store.volatility;
1403 }
1404
1405 void set_Store_volatility(ir_node *node, ir_volatility volatility)
1406 {
1407         assert(is_Store(node));
1408         node->attr.store.volatility = volatility;
1409 }
1410
1411 ir_align get_Store_align(const ir_node *node)
1412 {
1413         assert(is_Store(node));
1414         return node->attr.store.aligned;
1415 }
1416
1417 void set_Store_align(ir_node *node, ir_align align)
1418 {
1419         assert(is_Store(node));
1420         node->attr.store.aligned = align;
1421 }
1422
1423
1424 ir_node **get_Sync_preds_arr(ir_node *node)
1425 {
1426         assert(is_Sync(node));
1427         return (ir_node **)&(get_irn_in(node)[1]);
1428 }
1429
1430 int get_Sync_n_preds(const ir_node *node)
1431 {
1432         assert(is_Sync(node));
1433         return (get_irn_arity(node));
1434 }
1435
1436 /*
1437 void set_Sync_n_preds(ir_node *node, int n_preds)
1438 {
1439         assert(is_Sync(node));
1440 }
1441 */
1442
1443 ir_node *get_Sync_pred(const ir_node *node, int pos)
1444 {
1445         assert(is_Sync(node));
1446         return get_irn_n(node, pos);
1447 }
1448
1449 void set_Sync_pred(ir_node *node, int pos, ir_node *pred)
1450 {
1451         assert(is_Sync(node));
1452         set_irn_n(node, pos, pred);
1453 }
1454
1455 /* Add a new Sync predecessor */
1456 void add_Sync_pred(ir_node *node, ir_node *pred)
1457 {
1458         assert(is_Sync(node));
1459         add_irn_n(node, pred);
1460 }
1461
1462 /* Returns the source language type of a Proj node. */
1463 ir_type *get_Proj_type(const ir_node *n)
1464 {
1465         ir_type *tp   = firm_unknown_type;
1466         ir_node *pred = get_Proj_pred(n);
1467
1468         switch (get_irn_opcode(pred)) {
1469         case iro_Proj: {
1470                 ir_node *pred_pred;
1471                 /* Deal with Start / Call here: we need to know the Proj Nr. */
1472                 assert(get_irn_mode(pred) == mode_T);
1473                 pred_pred = get_Proj_pred(pred);
1474
1475                 if (is_Start(pred_pred))  {
1476                         ir_type *mtp = get_entity_type(get_irg_entity(get_irn_irg(pred_pred)));
1477                         tp = get_method_param_type(mtp, get_Proj_proj(n));
1478                 } else if (is_Call(pred_pred)) {
1479                         ir_type *mtp = get_Call_type(pred_pred);
1480                         tp = get_method_res_type(mtp, get_Proj_proj(n));
1481                 }
1482         } break;
1483         case iro_Start: break;
1484         case iro_Call: break;
1485         case iro_Load: {
1486                 ir_node *a = get_Load_ptr(pred);
1487                 if (is_Sel(a))
1488                         tp = get_entity_type(get_Sel_entity(a));
1489         } break;
1490         default:
1491                 break;
1492         }
1493         return tp;
1494 }
1495
1496 long get_Proj_proj(const ir_node *node)
1497 {
1498         assert(is_Proj(node));
1499         return node->attr.proj;
1500 }
1501
1502 void set_Proj_proj(ir_node *node, long proj)
1503 {
1504         assert(is_Proj(node));
1505         node->attr.proj = proj;
1506 }
1507
1508 int (is_arg_Proj)(const ir_node *node)
1509 {
1510         return _is_arg_Proj(node);
1511 }
1512
1513 ir_node **get_Tuple_preds_arr(ir_node *node)
1514 {
1515         assert(is_Tuple(node));
1516         return (ir_node **)&(get_irn_in(node)[1]);
1517 }
1518
1519 int get_Tuple_n_preds(const ir_node *node)
1520 {
1521         assert(is_Tuple(node));
1522         return get_irn_arity(node);
1523 }
1524
1525 ir_node *get_Tuple_pred(const ir_node *node, int pos)
1526 {
1527   assert(is_Tuple(node));
1528   return get_irn_n(node, pos);
1529 }
1530
1531 void set_Tuple_pred(ir_node *node, int pos, ir_node *pred)
1532 {
1533         assert(is_Tuple(node));
1534         set_irn_n(node, pos, pred);
1535 }
1536
1537 int get_ASM_n_input_constraints(const ir_node *node)
1538 {
1539         assert(is_ASM(node));
1540         return ARR_LEN(node->attr.assem.input_constraints);
1541 }
1542
1543 int get_ASM_n_output_constraints(const ir_node *node)
1544 {
1545         assert(is_ASM(node));
1546         return ARR_LEN(node->attr.assem.output_constraints);
1547 }
1548
1549 int get_ASM_n_clobbers(const ir_node *node)
1550 {
1551         assert(is_ASM(node));
1552         return ARR_LEN(node->attr.assem.clobbers);
1553 }
1554
1555 /* returns the graph of a node */
1556 ir_graph *(get_irn_irg)(const ir_node *node)
1557 {
1558         return _get_irn_irg(node);
1559 }
1560
1561
1562 /*----------------------------------------------------------------*/
1563 /*  Auxiliary routines                                            */
1564 /*----------------------------------------------------------------*/
1565
1566 ir_node *skip_Proj(ir_node *node)
1567 {
1568         /* don't assert node !!! */
1569         if (node == NULL)
1570                 return NULL;
1571
1572         if (is_Proj(node))
1573                 node = get_Proj_pred(node);
1574
1575         return node;
1576 }
1577
1578 const ir_node *
1579 skip_Proj_const(const ir_node *node)
1580 {
1581         /* don't assert node !!! */
1582         if (node == NULL)
1583                 return NULL;
1584
1585         if (is_Proj(node))
1586                 node = get_Proj_pred(node);
1587
1588         return node;
1589 }
1590
1591 ir_node *skip_Tuple(ir_node *node)
1592 {
1593   ir_node *pred;
1594   ir_op   *op;
1595
1596 restart:
1597         if (is_Proj(node)) {
1598             pred = get_Proj_pred(node);
1599             op   = get_irn_op(pred);
1600
1601                 /*
1602                  * Looks strange but calls get_irn_op() only once
1603                  * in most often cases.
1604                  */
1605                 if (op == op_Proj) { /* nested Tuple ? */
1606                     pred = skip_Tuple(pred);
1607
1608                         if (is_Tuple(pred)) {
1609                                 node = get_Tuple_pred(pred, get_Proj_proj(node));
1610                                 goto restart;
1611                         }
1612                 } else if (op == op_Tuple) {
1613                         node = get_Tuple_pred(pred, get_Proj_proj(node));
1614                         goto restart;
1615                 }
1616         }
1617         return node;
1618 }
1619
1620 /* returns operand of node if node is a Cast */
1621 ir_node *skip_Cast(ir_node *node)
1622 {
1623         if (is_Cast(node))
1624                 return get_Cast_op(node);
1625         return node;
1626 }
1627
1628 /* returns operand of node if node is a Cast */
1629 const ir_node *skip_Cast_const(const ir_node *node)
1630 {
1631         if (is_Cast(node))
1632                 return get_Cast_op(node);
1633         return node;
1634 }
1635
1636 /* returns operand of node if node is a Pin */
1637 ir_node *skip_Pin(ir_node *node)
1638 {
1639         if (is_Pin(node))
1640                 return get_Pin_op(node);
1641         return node;
1642 }
1643
1644 /* returns operand of node if node is a Confirm */
1645 ir_node *skip_Confirm(ir_node *node)
1646 {
1647         if (is_Confirm(node))
1648                 return get_Confirm_value(node);
1649         return node;
1650 }
1651
1652 /* skip all high-level ops */
1653 ir_node *skip_HighLevel_ops(ir_node *node)
1654 {
1655         while (is_op_highlevel(get_irn_op(node))) {
1656                 node = get_irn_n(node, 0);
1657         }
1658         return node;
1659 }
1660
1661
1662 /* This should compact Id-cycles to self-cycles. It has the same (or less?) complexity
1663  * than any other approach, as Id chains are resolved and all point to the real node, or
1664  * all id's are self loops.
1665  *
1666  * Note: This function takes 10% of mostly ANY the compiler run, so it's
1667  * a little bit "hand optimized".
1668  *
1669  * Moreover, it CANNOT be switched off using get_opt_normalize() ...
1670  */
1671 ir_node *skip_Id(ir_node *node)
1672 {
1673         ir_node *pred;
1674         /* don't assert node !!! */
1675
1676         if (!node || (node->op != op_Id)) return node;
1677
1678         /* Don't use get_Id_pred():  We get into an endless loop for
1679            self-referencing Ids. */
1680         pred = node->in[0+1];
1681
1682         if (pred->op != op_Id) return pred;
1683
1684         if (node != pred) {  /* not a self referencing Id. Resolve Id chain. */
1685                 ir_node *rem_pred, *res;
1686
1687                 if (pred->op != op_Id) return pred; /* shortcut */
1688                 rem_pred = pred;
1689
1690                 assert(get_irn_arity (node) > 0);
1691
1692                 node->in[0+1] = node;   /* turn us into a self referencing Id:  shorten Id cycles. */
1693                 res = skip_Id(rem_pred);
1694                 if (res->op == op_Id) /* self-loop */ return node;
1695
1696                 node->in[0+1] = res;    /* Turn Id chain into Ids all referencing the chain end. */
1697                 return res;
1698         } else {
1699                 return node;
1700         }
1701 }
1702
1703 int (is_strictConv)(const ir_node *node)
1704 {
1705         return _is_strictConv(node);
1706 }
1707
1708 /* Returns true if node is a SymConst node with kind symconst_addr_ent. */
1709 int (is_SymConst_addr_ent)(const ir_node *node)
1710 {
1711         return _is_SymConst_addr_ent(node);
1712 }
1713
1714 /* Returns true if the operation manipulates control flow. */
1715 int is_cfop(const ir_node *node)
1716 {
1717         return is_op_cfopcode(get_irn_op(node));
1718 }
1719
1720 /* Returns true if the operation can change the control flow because
1721    of an exception. */
1722 int is_fragile_op(const ir_node *node)
1723 {
1724         return is_op_fragile(get_irn_op(node));
1725 }
1726
1727 /* Returns the memory operand of fragile operations. */
1728 ir_node *get_fragile_op_mem(ir_node *node)
1729 {
1730         assert(node && is_fragile_op(node));
1731
1732         switch (get_irn_opcode(node)) {
1733         case iro_Call  :
1734         case iro_Quot  :
1735         case iro_DivMod:
1736         case iro_Div   :
1737         case iro_Mod   :
1738         case iro_Load  :
1739         case iro_Store :
1740         case iro_Alloc :
1741         case iro_Bound :
1742         case iro_CopyB :
1743                 return get_irn_n(node, pn_Generic_M);
1744         case iro_Bad   :
1745         case iro_Unknown:
1746                 return node;
1747         default:
1748                 panic("should not be reached");
1749         }
1750 }
1751
1752 /* Returns the result mode of a Div operation. */
1753 ir_mode *get_divop_resmod(const ir_node *node)
1754 {
1755         switch (get_irn_opcode(node)) {
1756         case iro_Quot  : return get_Quot_resmode(node);
1757         case iro_DivMod: return get_DivMod_resmode(node);
1758         case iro_Div   : return get_Div_resmode(node);
1759         case iro_Mod   : return get_Mod_resmode(node);
1760         default:
1761                 panic("should not be reached");
1762         }
1763 }
1764
1765 /* Returns true if the operation is a forking control flow operation. */
1766 int (is_irn_forking)(const ir_node *node)
1767 {
1768         return _is_irn_forking(node);
1769 }
1770
1771 void (copy_node_attr)(ir_graph *irg, const ir_node *old_node, ir_node *new_node)
1772 {
1773         _copy_node_attr(irg, old_node, new_node);
1774 }
1775
1776 /* Return the type associated with the value produced by n
1777  * if the node remarks this type as it is the case for
1778  * Cast, Const, SymConst and some Proj nodes. */
1779 ir_type *(get_irn_type)(ir_node *node)
1780 {
1781         return _get_irn_type(node);
1782 }
1783
1784 /* Return the type attribute of a node n (SymConst, Call, Alloc, Free,
1785    Cast) or NULL.*/
1786 ir_type *(get_irn_type_attr)(ir_node *node)
1787 {
1788         return _get_irn_type_attr(node);
1789 }
1790
1791 /* Return the entity attribute of a node n (SymConst, Sel) or NULL. */
1792 ir_entity *(get_irn_entity_attr)(ir_node *node)
1793 {
1794         return _get_irn_entity_attr(node);
1795 }
1796
1797 /* Returns non-zero for constant-like nodes. */
1798 int (is_irn_constlike)(const ir_node *node)
1799 {
1800         return _is_irn_constlike(node);
1801 }
1802
1803 /*
1804  * Returns non-zero for nodes that are allowed to have keep-alives and
1805  * are neither Block nor PhiM.
1806  */
1807 int (is_irn_keep)(const ir_node *node)
1808 {
1809         return _is_irn_keep(node);
1810 }
1811
1812 /*
1813  * Returns non-zero for nodes that are always placed in the start block.
1814  */
1815 int (is_irn_start_block_placed)(const ir_node *node)
1816 {
1817         return _is_irn_start_block_placed(node);
1818 }
1819
1820 /* Returns non-zero for nodes that are machine operations. */
1821 int (is_irn_machine_op)(const ir_node *node)
1822 {
1823         return _is_irn_machine_op(node);
1824 }
1825
1826 /* Returns non-zero for nodes that are machine operands. */
1827 int (is_irn_machine_operand)(const ir_node *node)
1828 {
1829         return _is_irn_machine_operand(node);
1830 }
1831
1832 /* Returns non-zero for nodes that have the n'th user machine flag set. */
1833 int (is_irn_machine_user)(const ir_node *node, unsigned n)
1834 {
1835         return _is_irn_machine_user(node, n);
1836 }
1837
1838 /* Returns non-zero for nodes that are CSE neutral to its users. */
1839 int (is_irn_cse_neutral)(const ir_node *node)
1840 {
1841         return _is_irn_cse_neutral(node);
1842 }
1843
1844 /* Gets the string representation of the jump prediction .*/
1845 const char *get_cond_jmp_predicate_name(cond_jmp_predicate pred)
1846 {
1847 #define X(a)    case a: return #a
1848         switch (pred) {
1849                 X(COND_JMP_PRED_NONE);
1850                 X(COND_JMP_PRED_TRUE);
1851                 X(COND_JMP_PRED_FALSE);
1852         }
1853         return "<unknown>";
1854 #undef X
1855 }
1856
1857 /** the get_type operation must be always implemented and return a firm type */
1858 static ir_type *get_Default_type(const ir_node *n)
1859 {
1860         (void) n;
1861         return get_unknown_type();
1862 }
1863
1864 /* Sets the get_type operation for an ir_op_ops. */
1865 ir_op_ops *firm_set_default_get_type(ir_opcode code, ir_op_ops *ops)
1866 {
1867         switch (code) {
1868         case iro_Const:    ops->get_type = get_Const_type; break;
1869         case iro_SymConst: ops->get_type = get_SymConst_value_type; break;
1870         case iro_Cast:     ops->get_type = get_Cast_type; break;
1871         case iro_Proj:     ops->get_type = get_Proj_type; break;
1872         default:
1873                 /* not allowed to be NULL */
1874                 if (! ops->get_type)
1875                         ops->get_type = get_Default_type;
1876                 break;
1877         }
1878         return ops;
1879 }
1880
1881 /** Return the attribute type of a SymConst node if exists */
1882 static ir_type *get_SymConst_attr_type(const ir_node *self)
1883 {
1884         symconst_kind kind = get_SymConst_kind(self);
1885         if (SYMCONST_HAS_TYPE(kind))
1886                 return get_SymConst_type(self);
1887         return NULL;
1888 }
1889
1890 /** Return the attribute entity of a SymConst node if exists */
1891 static ir_entity *get_SymConst_attr_entity(const ir_node *self)
1892 {
1893         symconst_kind kind = get_SymConst_kind(self);
1894         if (SYMCONST_HAS_ENT(kind))
1895                 return get_SymConst_entity(self);
1896         return NULL;
1897 }
1898
1899 /** the get_type_attr operation must be always implemented */
1900 static ir_type *get_Null_type(const ir_node *n)
1901 {
1902         (void) n;
1903         return firm_unknown_type;
1904 }
1905
1906 /* Sets the get_type operation for an ir_op_ops. */
1907 ir_op_ops *firm_set_default_get_type_attr(ir_opcode code, ir_op_ops *ops)
1908 {
1909         switch (code) {
1910         case iro_SymConst: ops->get_type_attr = get_SymConst_attr_type; break;
1911         case iro_Call:     ops->get_type_attr = get_Call_type; break;
1912         case iro_Alloc:    ops->get_type_attr = get_Alloc_type; break;
1913         case iro_Free:     ops->get_type_attr = get_Free_type; break;
1914         case iro_Cast:     ops->get_type_attr = get_Cast_type; break;
1915         default:
1916                 /* not allowed to be NULL */
1917                 if (! ops->get_type_attr)
1918                         ops->get_type_attr = get_Null_type;
1919                 break;
1920         }
1921         return ops;
1922 }
1923
1924 /** the get_entity_attr operation must be always implemented */
1925 static ir_entity *get_Null_ent(const ir_node *n)
1926 {
1927         (void) n;
1928         return NULL;
1929 }
1930
1931 /* Sets the get_type operation for an ir_op_ops. */
1932 ir_op_ops *firm_set_default_get_entity_attr(ir_opcode code, ir_op_ops *ops)
1933 {
1934         switch (code) {
1935         case iro_SymConst: ops->get_entity_attr = get_SymConst_attr_entity; break;
1936         case iro_Sel:      ops->get_entity_attr = get_Sel_entity; break;
1937         default:
1938                 /* not allowed to be NULL */
1939                 if (! ops->get_entity_attr)
1940                         ops->get_entity_attr = get_Null_ent;
1941                 break;
1942         }
1943         return ops;
1944 }
1945
1946 /* Sets the debug information of a node. */
1947 void (set_irn_dbg_info)(ir_node *n, dbg_info *db)
1948 {
1949         _set_irn_dbg_info(n, db);
1950 }
1951
1952 /**
1953  * Returns the debug information of an node.
1954  *
1955  * @param n   The node.
1956  */
1957 dbg_info *(get_irn_dbg_info)(const ir_node *n)
1958 {
1959         return _get_irn_dbg_info(n);
1960 }
1961
1962 /* checks whether a node represents a global address */
1963 int is_Global(const ir_node *node)
1964 {
1965         return is_SymConst_addr_ent(node);
1966 }
1967
1968 /* returns the entity of a global address */
1969 ir_entity *get_Global_entity(const ir_node *node)
1970 {
1971         return get_SymConst_entity(node);
1972 }
1973
1974 /*
1975  * Calculate a hash value of a node.
1976  */
1977 unsigned firm_default_hash(const ir_node *node)
1978 {
1979         unsigned h;
1980         int i, irn_arity;
1981
1982         /* hash table value = 9*(9*(9*(9*(9*arity+in[0])+in[1])+ ...)+mode)+code */
1983         h = irn_arity = get_irn_arity(node);
1984
1985         /* consider all in nodes... except the block if not a control flow. */
1986         for (i = is_cfop(node) ? -1 : 0;  i < irn_arity;  ++i) {
1987                 ir_node *pred = get_irn_n(node, i);
1988                 if (is_irn_cse_neutral(pred))
1989                         h *= 9;
1990                 else
1991                         h = 9*h + HASH_PTR(pred);
1992         }
1993
1994         /* ...mode,... */
1995         h = 9*h + HASH_PTR(get_irn_mode(node));
1996         /* ...and code */
1997         h = 9*h + HASH_PTR(get_irn_op(node));
1998
1999         return h;
2000 }  /* firm_default_hash */
2001
2002 /* include generated code */
2003 #include "gen_irnode.c.inl"