7a6fb311851603c2a0e18d749e9f0c9a02bccaf7
[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 ir_node **get_Tuple_preds_arr(ir_node *node)
1332 {
1333         assert(is_Tuple(node));
1334         return (ir_node **)&(get_irn_in(node)[1]);
1335 }
1336
1337 int get_Tuple_n_preds(const ir_node *node)
1338 {
1339         assert(is_Tuple(node));
1340         return get_irn_arity(node);
1341 }
1342
1343 ir_node *get_Tuple_pred(const ir_node *node, int pos)
1344 {
1345   assert(is_Tuple(node));
1346   return get_irn_n(node, pos);
1347 }
1348
1349 void set_Tuple_pred(ir_node *node, int pos, ir_node *pred)
1350 {
1351         assert(is_Tuple(node));
1352         set_irn_n(node, pos, pred);
1353 }
1354
1355 int get_ASM_n_input_constraints(const ir_node *node)
1356 {
1357         assert(is_ASM(node));
1358         return ARR_LEN(node->attr.assem.input_constraints);
1359 }
1360
1361 int get_ASM_n_output_constraints(const ir_node *node)
1362 {
1363         assert(is_ASM(node));
1364         return ARR_LEN(node->attr.assem.output_constraints);
1365 }
1366
1367 int get_ASM_n_clobbers(const ir_node *node)
1368 {
1369         assert(is_ASM(node));
1370         return ARR_LEN(node->attr.assem.clobbers);
1371 }
1372
1373 /* returns the graph of a node */
1374 ir_graph *(get_irn_irg)(const ir_node *node)
1375 {
1376         return _get_irn_irg(node);
1377 }
1378
1379
1380 /*----------------------------------------------------------------*/
1381 /*  Auxiliary routines                                            */
1382 /*----------------------------------------------------------------*/
1383
1384 ir_node *skip_Proj(ir_node *node)
1385 {
1386         /* don't assert node !!! */
1387         if (node == NULL)
1388                 return NULL;
1389
1390         if (is_Proj(node))
1391                 node = get_Proj_pred(node);
1392
1393         return node;
1394 }
1395
1396 const ir_node *
1397 skip_Proj_const(const ir_node *node)
1398 {
1399         /* don't assert node !!! */
1400         if (node == NULL)
1401                 return NULL;
1402
1403         if (is_Proj(node))
1404                 node = get_Proj_pred(node);
1405
1406         return node;
1407 }
1408
1409 ir_node *skip_Tuple(ir_node *node)
1410 {
1411   ir_node *pred;
1412
1413 restart:
1414         if (is_Proj(node)) {
1415             pred = get_Proj_pred(node);
1416
1417                 if (is_Proj(pred)) { /* nested Tuple ? */
1418                     pred = skip_Tuple(pred);
1419
1420                         if (is_Tuple(pred)) {
1421                                 node = get_Tuple_pred(pred, get_Proj_proj(node));
1422                                 goto restart;
1423                         }
1424                 } else if (is_Tuple(pred)) {
1425                         node = get_Tuple_pred(pred, get_Proj_proj(node));
1426                         goto restart;
1427                 }
1428         }
1429         return node;
1430 }
1431
1432 /* returns operand of node if node is a Cast */
1433 ir_node *skip_Cast(ir_node *node)
1434 {
1435         if (is_Cast(node))
1436                 return get_Cast_op(node);
1437         return node;
1438 }
1439
1440 /* returns operand of node if node is a Cast */
1441 const ir_node *skip_Cast_const(const ir_node *node)
1442 {
1443         if (is_Cast(node))
1444                 return get_Cast_op(node);
1445         return node;
1446 }
1447
1448 /* returns operand of node if node is a Pin */
1449 ir_node *skip_Pin(ir_node *node)
1450 {
1451         if (is_Pin(node))
1452                 return get_Pin_op(node);
1453         return node;
1454 }
1455
1456 /* returns operand of node if node is a Confirm */
1457 ir_node *skip_Confirm(ir_node *node)
1458 {
1459         if (is_Confirm(node))
1460                 return get_Confirm_value(node);
1461         return node;
1462 }
1463
1464 /* skip all high-level ops */
1465 ir_node *skip_HighLevel_ops(ir_node *node)
1466 {
1467         while (is_op_highlevel(get_irn_op(node))) {
1468                 node = get_irn_n(node, 0);
1469         }
1470         return node;
1471 }
1472
1473
1474 /* This should compact Id-cycles to self-cycles. It has the same (or less?) complexity
1475  * than any other approach, as Id chains are resolved and all point to the real node, or
1476  * all id's are self loops.
1477  *
1478  * Note: This function takes 10% of mostly ANY the compiler run, so it's
1479  * a little bit "hand optimized".
1480  */
1481 ir_node *skip_Id(ir_node *node)
1482 {
1483         ir_node *pred;
1484         /* don't assert node !!! */
1485
1486         if (!node || (node->op != op_Id)) return node;
1487
1488         /* Don't use get_Id_pred():  We get into an endless loop for
1489            self-referencing Ids. */
1490         pred = node->in[0+1];
1491
1492         if (pred->op != op_Id) return pred;
1493
1494         if (node != pred) {  /* not a self referencing Id. Resolve Id chain. */
1495                 ir_node *rem_pred, *res;
1496
1497                 if (pred->op != op_Id) return pred; /* shortcut */
1498                 rem_pred = pred;
1499
1500                 assert(get_irn_arity (node) > 0);
1501
1502                 node->in[0+1] = node;   /* turn us into a self referencing Id:  shorten Id cycles. */
1503                 res = skip_Id(rem_pred);
1504                 if (is_Id(res)) /* self-loop */ return node;
1505
1506                 node->in[0+1] = res;    /* Turn Id chain into Ids all referencing the chain end. */
1507                 return res;
1508         } else {
1509                 return node;
1510         }
1511 }
1512
1513 int (is_strictConv)(const ir_node *node)
1514 {
1515         return _is_strictConv(node);
1516 }
1517
1518 /* Returns true if node is a SymConst node with kind symconst_addr_ent. */
1519 int (is_SymConst_addr_ent)(const ir_node *node)
1520 {
1521         return _is_SymConst_addr_ent(node);
1522 }
1523
1524 /* Returns true if the operation manipulates control flow. */
1525 int is_cfop(const ir_node *node)
1526 {
1527         return is_op_cfopcode(get_irn_op(node));
1528 }
1529
1530 int is_unknown_jump(const ir_node *node)
1531 {
1532         return is_op_unknown_jump(get_irn_op(node));
1533 }
1534
1535 /* Returns true if the operation can change the control flow because
1536    of an exception. */
1537 int is_fragile_op(const ir_node *node)
1538 {
1539         return is_op_fragile(get_irn_op(node));
1540 }
1541
1542 /* Returns the memory operand of fragile operations. */
1543 ir_node *get_fragile_op_mem(ir_node *node)
1544 {
1545         assert(node && is_fragile_op(node));
1546         return get_irn_n(node, node->op->fragile_mem_index);
1547 }
1548
1549 /* Returns true if the operation is a forking control flow operation. */
1550 int (is_irn_forking)(const ir_node *node)
1551 {
1552         return _is_irn_forking(node);
1553 }
1554
1555 void (copy_node_attr)(ir_graph *irg, const ir_node *old_node, ir_node *new_node)
1556 {
1557         _copy_node_attr(irg, old_node, new_node);
1558 }
1559
1560 /* Return the type attribute of a node n (SymConst, Call, Alloc, Free,
1561    Cast) or NULL.*/
1562 ir_type *(get_irn_type_attr)(ir_node *node)
1563 {
1564         return _get_irn_type_attr(node);
1565 }
1566
1567 /* Return the entity attribute of a node n (SymConst, Sel) or NULL. */
1568 ir_entity *(get_irn_entity_attr)(ir_node *node)
1569 {
1570         return _get_irn_entity_attr(node);
1571 }
1572
1573 /* Returns non-zero for constant-like nodes. */
1574 int (is_irn_constlike)(const ir_node *node)
1575 {
1576         return _is_irn_constlike(node);
1577 }
1578
1579 /*
1580  * Returns non-zero for nodes that are allowed to have keep-alives and
1581  * are neither Block nor PhiM.
1582  */
1583 int (is_irn_keep)(const ir_node *node)
1584 {
1585         return _is_irn_keep(node);
1586 }
1587
1588 /*
1589  * Returns non-zero for nodes that are always placed in the start block.
1590  */
1591 int (is_irn_start_block_placed)(const ir_node *node)
1592 {
1593         return _is_irn_start_block_placed(node);
1594 }
1595
1596 /* Returns non-zero for nodes that are machine operations. */
1597 int (is_irn_machine_op)(const ir_node *node)
1598 {
1599         return _is_irn_machine_op(node);
1600 }
1601
1602 /* Returns non-zero for nodes that are machine operands. */
1603 int (is_irn_machine_operand)(const ir_node *node)
1604 {
1605         return _is_irn_machine_operand(node);
1606 }
1607
1608 /* Returns non-zero for nodes that have the n'th user machine flag set. */
1609 int (is_irn_machine_user)(const ir_node *node, unsigned n)
1610 {
1611         return _is_irn_machine_user(node, n);
1612 }
1613
1614 /* Returns non-zero for nodes that are CSE neutral to its users. */
1615 int (is_irn_cse_neutral)(const ir_node *node)
1616 {
1617         return _is_irn_cse_neutral(node);
1618 }
1619
1620 /* Gets the string representation of the jump prediction .*/
1621 const char *get_cond_jmp_predicate_name(cond_jmp_predicate pred)
1622 {
1623 #define X(a)    case a: return #a
1624         switch (pred) {
1625                 X(COND_JMP_PRED_NONE);
1626                 X(COND_JMP_PRED_TRUE);
1627                 X(COND_JMP_PRED_FALSE);
1628         }
1629         return "<unknown>";
1630 #undef X
1631 }
1632
1633 /** Return the attribute type of a SymConst node if exists */
1634 static ir_type *get_SymConst_attr_type(const ir_node *self)
1635 {
1636         symconst_kind kind = get_SymConst_kind(self);
1637         if (SYMCONST_HAS_TYPE(kind))
1638                 return get_SymConst_type(self);
1639         return NULL;
1640 }
1641
1642 /** Return the attribute entity of a SymConst node if exists */
1643 static ir_entity *get_SymConst_attr_entity(const ir_node *self)
1644 {
1645         symconst_kind kind = get_SymConst_kind(self);
1646         if (SYMCONST_HAS_ENT(kind))
1647                 return get_SymConst_entity(self);
1648         return NULL;
1649 }
1650
1651 /** the get_type_attr operation must be always implemented */
1652 static ir_type *get_Null_type(const ir_node *n)
1653 {
1654         (void) n;
1655         return firm_unknown_type;
1656 }
1657
1658 /* Sets the get_type operation for an ir_op_ops. */
1659 ir_op_ops *firm_set_default_get_type_attr(unsigned code, ir_op_ops *ops)
1660 {
1661         switch (code) {
1662         case iro_SymConst: ops->get_type_attr = get_SymConst_attr_type; break;
1663         case iro_Call:     ops->get_type_attr = get_Call_type; break;
1664         case iro_Alloc:    ops->get_type_attr = get_Alloc_type; break;
1665         case iro_Free:     ops->get_type_attr = get_Free_type; break;
1666         case iro_Cast:     ops->get_type_attr = get_Cast_type; break;
1667         default:
1668                 /* not allowed to be NULL */
1669                 if (! ops->get_type_attr)
1670                         ops->get_type_attr = get_Null_type;
1671                 break;
1672         }
1673         return ops;
1674 }
1675
1676 /** the get_entity_attr operation must be always implemented */
1677 static ir_entity *get_Null_ent(const ir_node *n)
1678 {
1679         (void) n;
1680         return NULL;
1681 }
1682
1683 /* Sets the get_type operation for an ir_op_ops. */
1684 ir_op_ops *firm_set_default_get_entity_attr(unsigned code, ir_op_ops *ops)
1685 {
1686         switch (code) {
1687         case iro_SymConst: ops->get_entity_attr = get_SymConst_attr_entity; break;
1688         case iro_Sel:      ops->get_entity_attr = get_Sel_entity; break;
1689         default:
1690                 /* not allowed to be NULL */
1691                 if (! ops->get_entity_attr)
1692                         ops->get_entity_attr = get_Null_ent;
1693                 break;
1694         }
1695         return ops;
1696 }
1697
1698 /* Sets the debug information of a node. */
1699 void (set_irn_dbg_info)(ir_node *n, dbg_info *db)
1700 {
1701         _set_irn_dbg_info(n, db);
1702 }
1703
1704 /**
1705  * Returns the debug information of an node.
1706  *
1707  * @param n   The node.
1708  */
1709 dbg_info *(get_irn_dbg_info)(const ir_node *n)
1710 {
1711         return _get_irn_dbg_info(n);
1712 }
1713
1714 /* checks whether a node represents a global address */
1715 int is_Global(const ir_node *node)
1716 {
1717         return is_SymConst_addr_ent(node);
1718 }
1719
1720 /* returns the entity of a global address */
1721 ir_entity *get_Global_entity(const ir_node *node)
1722 {
1723         return get_SymConst_entity(node);
1724 }
1725
1726 /*
1727  * Calculate a hash value of a node.
1728  */
1729 unsigned firm_default_hash(const ir_node *node)
1730 {
1731         unsigned h;
1732         int i, irn_arity;
1733
1734         /* hash table value = 9*(9*(9*(9*(9*arity+in[0])+in[1])+ ...)+mode)+code */
1735         h = irn_arity = get_irn_arity(node);
1736
1737         /* consider all in nodes... except the block if not a control flow. */
1738         for (i = is_cfop(node) ? -1 : 0;  i < irn_arity;  ++i) {
1739                 ir_node *pred = get_irn_n(node, i);
1740                 if (is_irn_cse_neutral(pred))
1741                         h *= 9;
1742                 else
1743                         h = 9*h + HASH_PTR(pred);
1744         }
1745
1746         /* ...mode,... */
1747         h = 9*h + HASH_PTR(get_irn_mode(node));
1748         /* ...and code */
1749         h = 9*h + HASH_PTR(get_irn_op(node));
1750
1751         return h;
1752 }  /* firm_default_hash */
1753
1754 /* include generated code */
1755 #include "gen_irnode.c.inl"