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