further corrections for the keepalive hack
[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  */
25 #include "config.h"
26
27 #include <string.h>
28
29 #include "pset_new.h"
30 #include "ident.h"
31 #include "irnode_t.h"
32 #include "irgraph_t.h"
33 #include "irmode_t.h"
34 #include "irbackedge_t.h"
35 #include "irdump.h"
36 #include "irop_t.h"
37 #include "irprog_t.h"
38 #include "iredgekinds.h"
39 #include "iredges_t.h"
40 #include "ircons.h"
41 #include "error.h"
42
43 #include "irhooks.h"
44 #include "irtools.h"
45 #include "util.h"
46
47 #include "beinfo.h"
48
49 /* some constants fixing the positions of nodes predecessors
50    in the in array */
51 #define CALL_PARAM_OFFSET     (n_Call_max+1)
52 #define BUILTIN_PARAM_OFFSET  (n_Builtin_max+1)
53 #define ASM_PARAM_OFFSET      (n_ASM_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 : ir_relation_false)
94               | (greater ? ir_relation_less : ir_relation_false);
95         return code;
96 }
97
98 /**
99  * Indicates, whether additional data can be registered to ir nodes.
100  * If set to 1, this is not possible anymore.
101  */
102 static int forbid_new_data = 0;
103
104 unsigned firm_add_node_size = 0;
105
106
107 unsigned firm_register_additional_node_data(unsigned size)
108 {
109         assert(!forbid_new_data && "Too late to register additional node data");
110
111         if (forbid_new_data)
112                 return 0;
113
114         return firm_add_node_size += size;
115 }
116
117
118 void init_irnode(void)
119 {
120         /* Forbid the addition of new data to an ir node. */
121         forbid_new_data = 1;
122 }
123
124 struct struct_align {
125         char c;
126         struct s {
127                 int i;
128                 float f;
129                 double d;
130         } s;
131 };
132
133 ir_node *new_ir_node(dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op,
134                      ir_mode *mode, int arity, ir_node *const *in)
135 {
136         ir_node *res;
137         unsigned align = offsetof(struct struct_align, s) - 1;
138         unsigned add_node_size = (firm_add_node_size + align) & ~align;
139         size_t node_size = offsetof(ir_node, attr) + op->attr_size + add_node_size;
140         char *p;
141         int i;
142
143         assert(irg);
144         assert(op);
145         assert(mode);
146         p = (char*)obstack_alloc(irg->obst, node_size);
147         memset(p, 0, node_size);
148         res = (ir_node *)(p + add_node_size);
149
150         res->kind     = k_ir_node;
151         res->op       = op;
152         res->mode     = mode;
153         res->visited  = 0;
154         res->node_idx = irg_register_node_idx(irg, res);
155         res->link     = NULL;
156         res->deps     = NULL;
157
158         if (arity < 0) {
159                 res->in = NEW_ARR_F(ir_node *, 1);  /* 1: space for block */
160         } else {
161                 /* not nice but necessary: End and Sync must always have a flexible array */
162                 if (op == op_End || op == op_Sync)
163                         res->in = NEW_ARR_F(ir_node *, (arity+1));
164                 else
165                         res->in = NEW_ARR_D(ir_node *, irg->obst, (arity+1));
166                 memcpy(&res->in[1], in, sizeof(ir_node *) * arity);
167         }
168
169         res->in[0]   = block;
170         set_irn_dbg_info(res, db);
171         res->node_nr = get_irp_new_node_nr();
172
173         for (i = 0; i < EDGE_KIND_LAST; ++i) {
174                 INIT_LIST_HEAD(&res->edge_info[i].outs_head);
175                 /* edges will be build immediately */
176                 res->edge_info[i].edges_built = 1;
177                 res->edge_info[i].out_count = 0;
178         }
179
180         /* don't put this into the for loop, arity is -1 for some nodes! */
181         edges_notify_edge(res, -1, res->in[0], NULL, irg);
182         for (i = 1; i <= arity; ++i)
183                 edges_notify_edge(res, i - 1, res->in[i], NULL, irg);
184
185         hook_new_node(irg, res);
186         if (get_irg_phase_state(irg) == phase_backend) {
187                 be_info_new_node(irg, res);
188         }
189
190         return res;
191 }
192
193 int (is_ir_node)(const void *thing)
194 {
195         return is_ir_node_(thing);
196 }
197
198 int (get_irn_arity)(const ir_node *node)
199 {
200         return get_irn_arity_(node);
201 }
202
203 ir_node **get_irn_in(const ir_node *node)
204 {
205         return node->in;
206 }
207
208 void set_irn_in(ir_node *node, int arity, ir_node **in)
209 {
210         int i;
211         ir_node *** pOld_in;
212         ir_graph *irg = get_irn_irg(node);
213
214         pOld_in = &node->in;
215
216 #ifndef NDEBUG
217         assert(node != NULL && node->kind == k_ir_node);
218         assert(arity >= 0);
219         for (i = 0; i < arity; ++i) {
220                 assert(in[i] != NULL && in[0]->kind == k_ir_node);
221         }
222 #endif
223
224         for (i = 0; i < arity; i++) {
225                 if (i < (int)ARR_LEN(*pOld_in)-1)
226                         edges_notify_edge(node, i, in[i], (*pOld_in)[i+1], irg);
227                 else
228                         edges_notify_edge(node, i, in[i], NULL,            irg);
229         }
230         for (;i < (int)ARR_LEN(*pOld_in)-1; i++) {
231                 edges_notify_edge(node, i, NULL, (*pOld_in)[i+1], irg);
232         }
233
234         if (arity != (int)ARR_LEN(*pOld_in) - 1) {
235                 ir_node * block = (*pOld_in)[0];
236                 *pOld_in = NEW_ARR_D(ir_node *, irg->obst, arity + 1);
237                 (*pOld_in)[0] = block;
238         }
239         fix_backedges(irg->obst, node);
240
241         memcpy((*pOld_in) + 1, in, sizeof(ir_node *) * arity);
242
243         /* update irg flags */
244         clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
245 }
246
247 ir_node *(get_irn_n)(const ir_node *node, int n)
248 {
249         return get_irn_n_(node, n);
250 }
251
252 void set_irn_n(ir_node *node, int n, ir_node *in)
253 {
254         ir_graph *irg = get_irn_irg(node);
255         assert(node && node->kind == k_ir_node);
256         assert(-1 <= n);
257         assert(n < get_irn_arity(node));
258         assert(in && in->kind == k_ir_node);
259
260         /* Call the hook */
261         hook_set_irn_n(node, n, in, node->in[n + 1]);
262
263         /* Here, we rely on src and tgt being in the current ir graph */
264         edges_notify_edge(node, n, in, node->in[n + 1], irg);
265
266         node->in[n + 1] = in;
267
268         /* update irg flags */
269         clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
270 }
271
272 int add_irn_n(ir_node *node, ir_node *in)
273 {
274         int pos;
275         ir_graph *irg = get_irn_irg(node);
276
277         assert(node->op->opar == oparity_dynamic);
278         pos = ARR_LEN(node->in) - 1;
279         ARR_APP1(ir_node *, node->in, in);
280         edges_notify_edge(node, pos, node->in[pos + 1], NULL, irg);
281
282         /* Call the hook */
283         hook_set_irn_n(node, pos, node->in[pos + 1], NULL);
284
285         return pos;
286 }
287
288 void del_Sync_n(ir_node *n, int i)
289 {
290         int      arity     = get_Sync_n_preds(n);
291         ir_node *last_pred = get_Sync_pred(n, arity - 1);
292         set_Sync_pred(n, i, last_pred);
293         edges_notify_edge(n, arity - 1, NULL, last_pred, get_irn_irg(n));
294         ARR_SHRINKLEN(get_irn_in(n), arity);
295 }
296
297 int (get_irn_deps)(const ir_node *node)
298 {
299         return get_irn_deps_(node);
300 }
301
302 ir_node *(get_irn_dep)(const ir_node *node, int pos)
303 {
304         return get_irn_dep_(node, pos);
305 }
306
307 void set_irn_dep(ir_node *node, int pos, ir_node *dep)
308 {
309         ir_node *old;
310         ir_graph *irg;
311
312         assert(node->deps && "dependency array node yet allocated. use add_irn_dep()");
313         assert(pos >= 0 && pos < (int)ARR_LEN(node->deps) && "dependency index out of range");
314         assert(dep != NULL);
315         old = node->deps[pos];
316         node->deps[pos] = dep;
317         irg = get_irn_irg(node);
318         if (edges_activated_kind(irg, EDGE_KIND_DEP))
319                 edges_notify_edge_kind(node, pos, dep, old, EDGE_KIND_DEP, irg);
320 }
321
322 void add_irn_dep(ir_node *node, ir_node *dep)
323 {
324         ir_graph *irg;
325         assert(dep != NULL);
326         if (node->deps == NULL) {
327                 node->deps = NEW_ARR_F(ir_node *, 0);
328         }
329         ARR_APP1(ir_node*, node->deps, dep);
330         irg = get_irn_irg(node);
331         if (edges_activated_kind(irg, EDGE_KIND_DEP))
332                 edges_notify_edge_kind(node, ARR_LEN(node->deps)-1, dep, NULL, EDGE_KIND_DEP, irg);
333 }
334
335 void delete_irn_dep(ir_node *node, ir_node *dep)
336 {
337         size_t i;
338         size_t n_deps;
339         if (node->deps == NULL)
340                 return;
341
342         n_deps = ARR_LEN(node->deps);
343         for (i = 0; i < n_deps; ++i) {
344                 if (node->deps[i] == dep) {
345                         set_irn_dep(node, i, node->deps[n_deps-1]);
346                         edges_notify_edge(node, i, NULL, dep, get_irn_irg(node));
347                         ARR_SHRINKLEN(node->deps, n_deps-1);
348                         break;
349                 }
350         }
351 }
352
353 void add_irn_deps(ir_node *tgt, ir_node *src)
354 {
355         int i, n;
356
357         for (i = 0, n = get_irn_deps(src); i < n; ++i)
358                 add_irn_dep(tgt, get_irn_dep(src, i));
359 }
360
361
362 ir_mode *(get_irn_mode)(const ir_node *node)
363 {
364         return get_irn_mode_(node);
365 }
366
367 void (set_irn_mode)(ir_node *node, ir_mode *mode)
368 {
369         set_irn_mode_(node, mode);
370 }
371
372 ir_op *(get_irn_op)(const ir_node *node)
373 {
374         return get_irn_op_(node);
375 }
376
377 void (set_irn_op)(ir_node *node, ir_op *op)
378 {
379         set_irn_op_(node, op);
380 }
381
382 unsigned (get_irn_opcode)(const ir_node *node)
383 {
384         return get_irn_opcode_(node);
385 }
386
387 const char *get_irn_opname(const ir_node *node)
388 {
389         return get_id_str(node->op->name);
390 }
391
392 ident *get_irn_opident(const ir_node *node)
393 {
394         assert(node);
395         return node->op->name;
396 }
397
398 ir_visited_t (get_irn_visited)(const ir_node *node)
399 {
400         return get_irn_visited_(node);
401 }
402
403 void (set_irn_visited)(ir_node *node, ir_visited_t visited)
404 {
405         set_irn_visited_(node, visited);
406 }
407
408 void (mark_irn_visited)(ir_node *node)
409 {
410         mark_irn_visited_(node);
411 }
412
413 int (irn_visited)(const ir_node *node)
414 {
415         return irn_visited_(node);
416 }
417
418 int (irn_visited_else_mark)(ir_node *node)
419 {
420         return irn_visited_else_mark_(node);
421 }
422
423 void (set_irn_link)(ir_node *node, void *link)
424 {
425         set_irn_link_(node, link);
426 }
427
428 void *(get_irn_link)(const ir_node *node)
429 {
430         return get_irn_link_(node);
431 }
432
433 op_pin_state (get_irn_pinned)(const ir_node *node)
434 {
435         return get_irn_pinned_(node);
436 }
437
438 op_pin_state (is_irn_pinned_in_irg) (const ir_node *node)
439 {
440         return is_irn_pinned_in_irg_(node);
441 }
442
443 void set_irn_pinned(ir_node *node, op_pin_state state)
444 {
445         /* due to optimization an opt may be turned into a Tuple */
446         if (is_Tuple(node))
447                 return;
448
449         assert(node && get_op_pinned(get_irn_op(node)) >= op_pin_state_exc_pinned);
450         assert(state == op_pin_state_pinned || state == op_pin_state_floats);
451
452         node->attr.except.pin_state = state;
453 }
454
455 long get_irn_node_nr(const ir_node *node)
456 {
457         assert(node);
458         return node->node_nr;
459 }
460
461 void *(get_irn_generic_attr)(ir_node *node)
462 {
463         assert(is_ir_node(node));
464         return get_irn_generic_attr_(node);
465 }
466
467 const void *(get_irn_generic_attr_const)(const ir_node *node)
468 {
469         assert(is_ir_node(node));
470         return get_irn_generic_attr_const_(node);
471 }
472
473 unsigned (get_irn_idx)(const ir_node *node)
474 {
475         assert(is_ir_node(node));
476         return get_irn_idx_(node);
477 }
478
479 int get_irn_pred_pos(ir_node *node, ir_node *arg)
480 {
481         int i;
482         for (i = get_irn_arity(node) - 1; i >= 0; i--) {
483                 if (get_irn_n(node, i) == arg)
484                         return i;
485         }
486         return -1;
487 }
488
489 ir_node *(get_nodes_block)(const ir_node *node)
490 {
491         return get_nodes_block_(node);
492 }
493
494 void set_nodes_block(ir_node *node, ir_node *block)
495 {
496         assert(!is_Block(node));
497         set_irn_n(node, -1, block);
498 }
499
500 ir_type *is_frame_pointer(const ir_node *n)
501 {
502         if (is_Proj(n) && (get_Proj_proj(n) == pn_Start_P_frame_base)) {
503                 ir_node *start = get_Proj_pred(n);
504                 if (is_Start(start)) {
505                         return get_irg_frame_type(get_irn_irg(start));
506                 }
507         }
508         return NULL;
509 }
510
511 ir_node **get_Block_cfgpred_arr(ir_node *node)
512 {
513         assert(is_Block(node));
514         return (ir_node **)&(get_irn_in(node)[1]);
515 }
516
517 int (get_Block_n_cfgpreds)(const ir_node *node)
518 {
519         return get_Block_n_cfgpreds_(node);
520 }
521
522 ir_node *(get_Block_cfgpred)(const ir_node *node, int pos)
523 {
524         return get_Block_cfgpred_(node, pos);
525 }
526
527 void set_Block_cfgpred(ir_node *node, int pos, ir_node *pred)
528 {
529         assert(is_Block(node));
530         set_irn_n(node, pos, pred);
531 }
532
533 int get_Block_cfgpred_pos(const ir_node *block, const ir_node *pred)
534 {
535         int i;
536
537         for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
538                 if (get_Block_cfgpred_block(block, i) == pred)
539                         return i;
540         }
541         return -1;
542 }
543
544 ir_node *(get_Block_cfgpred_block)(const ir_node *node, int pos)
545 {
546         return get_Block_cfgpred_block_(node, pos);
547 }
548
549 int get_Block_matured(const ir_node *node)
550 {
551         assert(is_Block(node));
552         return (int)node->attr.block.is_matured;
553 }
554
555 void set_Block_matured(ir_node *node, int matured)
556 {
557         assert(is_Block(node));
558         node->attr.block.is_matured = matured;
559 }
560
561 ir_visited_t (get_Block_block_visited)(const ir_node *node)
562 {
563         return get_Block_block_visited_(node);
564 }
565
566 void (set_Block_block_visited)(ir_node *node, ir_visited_t visit)
567 {
568         set_Block_block_visited_(node, visit);
569 }
570
571 void (mark_Block_block_visited)(ir_node *node)
572 {
573         mark_Block_block_visited_(node);
574 }
575
576 int (Block_block_visited)(const ir_node *node)
577 {
578         return Block_block_visited_(node);
579 }
580
581 ir_graph *(get_Block_irg)(const ir_node *block)
582 {
583         return get_Block_irg_(block);
584 }
585
586 ir_entity *create_Block_entity(ir_node *block)
587 {
588         ir_entity *entity;
589         assert(is_Block(block));
590
591         entity = block->attr.block.entity;
592         if (entity == NULL) {
593                 ir_label_t nr = get_irp_next_label_nr();
594                 entity = new_label_entity(nr);
595                 set_entity_visibility(entity, ir_visibility_local);
596                 set_entity_linkage(entity, IR_LINKAGE_CONSTANT);
597                 set_entity_compiler_generated(entity, 1);
598
599                 block->attr.block.entity = entity;
600         }
601         return entity;
602 }
603
604 ir_node *(get_Block_phis)(const ir_node *block)
605 {
606         return get_Block_phis_(block);
607 }
608
609 void (set_Block_phis)(ir_node *block, ir_node *phi)
610 {
611         set_Block_phis_(block, phi);
612 }
613
614 void (add_Block_phi)(ir_node *block, ir_node *phi)
615 {
616         add_Block_phi_(block, phi);
617 }
618
619 unsigned (get_Block_mark)(const ir_node *block)
620 {
621         return get_Block_mark_(block);
622 }
623
624 void (set_Block_mark)(ir_node *block, unsigned mark)
625 {
626         set_Block_mark_(block, mark);
627 }
628
629 int get_End_n_keepalives(const ir_node *end)
630 {
631         assert(is_End(end));
632         return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
633 }
634
635 ir_node *get_End_keepalive(const ir_node *end, int pos)
636 {
637         assert(is_End(end));
638         return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
639 }
640
641 void add_End_keepalive(ir_node *end, ir_node *ka)
642 {
643         assert(is_End(end));
644         add_irn_n(end, ka);
645 }
646
647 void set_End_keepalive(ir_node *end, int pos, ir_node *ka)
648 {
649         assert(is_End(end));
650         set_irn_n(end, pos + END_KEEPALIVE_OFFSET, ka);
651 }
652
653 void set_End_keepalives(ir_node *end, int n, ir_node *in[])
654 {
655         size_t e;
656         int    i;
657         ir_graph *irg = get_irn_irg(end);
658
659         /* notify that edges are deleted */
660         for (e = END_KEEPALIVE_OFFSET; e < ARR_LEN(end->in) - 1; ++e) {
661                 edges_notify_edge(end, e, NULL, end->in[e + 1], irg);
662         }
663         ARR_RESIZE(ir_node *, end->in, n + 1 + END_KEEPALIVE_OFFSET);
664
665         for (i = 0; i < n; ++i) {
666                 end->in[1 + END_KEEPALIVE_OFFSET + i] = in[i];
667                 edges_notify_edge(end, END_KEEPALIVE_OFFSET + i, end->in[1 + END_KEEPALIVE_OFFSET + i], NULL, irg);
668         }
669
670         /* update irg flags */
671         clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
672 }
673
674 void remove_End_keepalive(ir_node *end, ir_node *irn)
675 {
676         int      n = get_End_n_keepalives(end);
677         ir_graph *irg;
678
679         int idx = -1;
680         for (int i = n;;) {
681                 if (i-- == 0)
682                         return;
683
684                 ir_node *old_ka = end->in[1 + END_KEEPALIVE_OFFSET + i];
685
686                 /* find irn */
687                 if (old_ka == irn) {
688                         idx = i;
689                         break;
690                 }
691         }
692         irg = get_irn_irg(end);
693
694         /* remove the edge */
695         edges_notify_edge(end, idx, NULL, irn, irg);
696
697         if (idx != n - 1) {
698                 /* exchange with the last one */
699                 ir_node *old = end->in[1 + END_KEEPALIVE_OFFSET + n - 1];
700                 edges_notify_edge(end, n - 1, NULL, old, irg);
701                 end->in[1 + END_KEEPALIVE_OFFSET + idx] = old;
702                 edges_notify_edge(end, idx, old, NULL, irg);
703         }
704         /* now n - 1 keeps, 1 block input */
705         ARR_RESIZE(ir_node *, end->in, (n - 1) + 1 + END_KEEPALIVE_OFFSET);
706
707         /* update irg flags */
708         clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
709 }
710
711 void remove_End_Bads_and_doublets(ir_node *end)
712 {
713         pset_new_t keeps;
714         int        idx, n = get_End_n_keepalives(end);
715         ir_graph   *irg;
716         bool       changed = false;
717
718         if (n <= 0)
719                 return;
720
721         irg = get_irn_irg(end);
722         pset_new_init(&keeps);
723
724         for (idx = n - 1; idx >= 0; --idx) {
725                 ir_node *ka = get_End_keepalive(end, idx);
726
727                 if (is_Bad(ka) || is_NoMem(ka) || pset_new_contains(&keeps, ka)) {
728                         changed = true;
729                         /* remove the edge */
730                         edges_notify_edge(end, idx, NULL, ka, irg);
731
732                         if (idx != n - 1) {
733                                 /* exchange with the last one */
734                                 ir_node *old = end->in[1 + END_KEEPALIVE_OFFSET + n - 1];
735                                 edges_notify_edge(end, n - 1, NULL, old, irg);
736                                 end->in[1 + END_KEEPALIVE_OFFSET + idx] = old;
737                                 edges_notify_edge(end, idx, old, NULL, irg);
738                         }
739                         --n;
740                 } else {
741                         pset_new_insert(&keeps, ka);
742                 }
743         }
744         /* n keeps, 1 block input */
745         ARR_RESIZE(ir_node *, end->in, n + 1 + END_KEEPALIVE_OFFSET);
746
747         pset_new_destroy(&keeps);
748
749         if (changed) {
750                 clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
751         }
752 }
753
754 void free_End(ir_node *end)
755 {
756         assert(is_End(end));
757         end->kind = k_BAD;
758         DEL_ARR_F(end->in);
759         end->in = NULL;   /* @@@ make sure we get an error if we use the
760                              in array afterwards ... */
761 }
762
763 size_t get_Return_n_ress(const ir_node *node)
764 {
765         assert(is_Return(node));
766         return (size_t)(get_irn_arity(node) - RETURN_RESULT_OFFSET);
767 }
768
769 ir_node **get_Return_res_arr(ir_node *node)
770 {
771         assert(is_Return(node));
772         if (get_Return_n_ress(node) > 0)
773                 return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
774         else
775                 return NULL;
776 }
777
778 ir_node *get_Return_res(const ir_node *node, int pos)
779 {
780         assert(is_Return(node));
781         assert(pos >= 0);
782         assert(get_Return_n_ress(node) > (size_t)pos);
783         return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
784 }
785
786 void set_Return_res(ir_node *node, int pos, ir_node *res)
787 {
788         assert(is_Return(node));
789         set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
790 }
791
792 int (is_Const_null)(const ir_node *node)
793 {
794         return is_Const_null_(node);
795 }
796
797 int (is_Const_one)(const ir_node *node)
798 {
799         return is_Const_one_(node);
800 }
801
802 int (is_Const_all_one)(const ir_node *node)
803 {
804         return is_Const_all_one_(node);
805 }
806
807
808
809 symconst_kind get_SymConst_kind(const ir_node *node)
810 {
811         assert(is_SymConst(node));
812         return node->attr.symc.kind;
813 }
814
815 void set_SymConst_kind(ir_node *node, symconst_kind kind)
816 {
817         assert(is_SymConst(node));
818         node->attr.symc.kind = kind;
819 }
820
821 ir_type *get_SymConst_type(const ir_node *node)
822 {
823         /* the cast here is annoying, but we have to compensate for
824            the skip_tip() */
825         ir_node *irn = (ir_node *)node;
826         assert(is_SymConst(node) &&
827                (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
828         return irn->attr.symc.sym.type_p;
829 }
830
831 void set_SymConst_type(ir_node *node, ir_type *tp)
832 {
833         assert(is_SymConst(node) &&
834                (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
835         node->attr.symc.sym.type_p = tp;
836 }
837
838 ir_entity *get_SymConst_entity(const ir_node *node)
839 {
840         assert(is_SymConst(node) && SYMCONST_HAS_ENT(get_SymConst_kind(node)));
841         return node->attr.symc.sym.entity_p;
842 }
843
844 void set_SymConst_entity(ir_node *node, ir_entity *ent)
845 {
846         assert(is_SymConst(node) && SYMCONST_HAS_ENT(get_SymConst_kind(node)));
847         node->attr.symc.sym.entity_p  = ent;
848 }
849
850 ir_enum_const *get_SymConst_enum(const ir_node *node)
851 {
852         assert(is_SymConst(node) && SYMCONST_HAS_ENUM(get_SymConst_kind(node)));
853         return node->attr.symc.sym.enum_p;
854 }
855
856 void set_SymConst_enum(ir_node *node, ir_enum_const *ec)
857 {
858         assert(is_SymConst(node) && SYMCONST_HAS_ENUM(get_SymConst_kind(node)));
859         node->attr.symc.sym.enum_p  = ec;
860 }
861
862 union symconst_symbol
863 get_SymConst_symbol(const ir_node *node)
864 {
865         assert(is_SymConst(node));
866         return node->attr.symc.sym;
867 }
868
869 void set_SymConst_symbol(ir_node *node, union symconst_symbol sym)
870 {
871         assert(is_SymConst(node));
872         node->attr.symc.sym = sym;
873 }
874
875 int get_Sel_n_indexs(const ir_node *node)
876 {
877         assert(is_Sel(node));
878         return (get_irn_arity(node) - SEL_INDEX_OFFSET);
879 }
880
881 ir_node **get_Sel_index_arr(ir_node *node)
882 {
883         assert(is_Sel(node));
884         if (get_Sel_n_indexs(node) > 0)
885                 return (ir_node **)& get_irn_in(node)[SEL_INDEX_OFFSET + 1];
886         else
887                 return NULL;
888 }
889
890 ir_node *get_Sel_index(const ir_node *node, int pos)
891 {
892         assert(is_Sel(node));
893         return get_irn_n(node, pos + SEL_INDEX_OFFSET);
894 }
895
896 void set_Sel_index(ir_node *node, int pos, ir_node *index)
897 {
898         assert(is_Sel(node));
899         set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
900 }
901
902 ir_node **get_Call_param_arr(ir_node *node)
903 {
904         assert(is_Call(node));
905         return &get_irn_in(node)[CALL_PARAM_OFFSET + 1];
906 }
907
908 int get_Call_n_params(const ir_node *node)
909 {
910         assert(is_Call(node));
911         return get_irn_arity(node) - CALL_PARAM_OFFSET;
912 }
913
914 ir_node *get_Call_param(const ir_node *node, int pos)
915 {
916         assert(is_Call(node));
917         return get_irn_n(node, pos + CALL_PARAM_OFFSET);
918 }
919
920 void set_Call_param(ir_node *node, int pos, ir_node *param)
921 {
922         assert(is_Call(node));
923         set_irn_n(node, pos + CALL_PARAM_OFFSET, param);
924 }
925
926 ir_node **get_Builtin_param_arr(ir_node *node)
927 {
928         assert(is_Builtin(node));
929         return &get_irn_in(node)[BUILTIN_PARAM_OFFSET + 1];
930 }
931
932 int get_Builtin_n_params(const ir_node *node)
933 {
934         assert(is_Builtin(node));
935         return (get_irn_arity(node) - BUILTIN_PARAM_OFFSET);
936 }
937
938 ir_node *get_Builtin_param(const ir_node *node, int pos)
939 {
940         assert(is_Builtin(node));
941         return get_irn_n(node, pos + BUILTIN_PARAM_OFFSET);
942 }
943
944 void set_Builtin_param(ir_node *node, int pos, ir_node *param)
945 {
946         assert(is_Builtin(node));
947         set_irn_n(node, pos + BUILTIN_PARAM_OFFSET, param);
948 }
949
950 const char *get_builtin_kind_name(ir_builtin_kind kind)
951 {
952 #define X(a)    case a: return #a
953         switch (kind) {
954                 X(ir_bk_trap);
955                 X(ir_bk_debugbreak);
956                 X(ir_bk_return_address);
957                 X(ir_bk_frame_address);
958                 X(ir_bk_prefetch);
959                 X(ir_bk_ffs);
960                 X(ir_bk_clz);
961                 X(ir_bk_ctz);
962                 X(ir_bk_popcount);
963                 X(ir_bk_parity);
964                 X(ir_bk_bswap);
965                 X(ir_bk_inport);
966                 X(ir_bk_outport);
967                 X(ir_bk_inner_trampoline);
968         }
969         return "<unknown>";
970 #undef X
971 }
972
973
974 int Call_has_callees(const ir_node *node)
975 {
976         assert(is_Call(node));
977         return ((get_irg_callee_info_state(get_irn_irg(node)) != irg_callee_info_none) &&
978                 (node->attr.call.callee_arr != NULL));
979 }
980
981 size_t get_Call_n_callees(const ir_node *node)
982 {
983   assert(is_Call(node) && node->attr.call.callee_arr);
984   return ARR_LEN(node->attr.call.callee_arr);
985 }
986
987 ir_entity *get_Call_callee(const ir_node *node, size_t pos)
988 {
989         assert(pos < get_Call_n_callees(node));
990         return node->attr.call.callee_arr[pos];
991 }
992
993 void set_Call_callee_arr(ir_node *node, size_t n, ir_entity ** arr)
994 {
995         ir_graph *irg = get_irn_irg(node);
996
997         assert(is_Call(node));
998         if (node->attr.call.callee_arr == NULL || get_Call_n_callees(node) != n) {
999                 node->attr.call.callee_arr = NEW_ARR_D(ir_entity *, irg->obst, n);
1000         }
1001         memcpy(node->attr.call.callee_arr, arr, n * sizeof(ir_entity *));
1002 }
1003
1004 void remove_Call_callee_arr(ir_node *node)
1005 {
1006         assert(is_Call(node));
1007         node->attr.call.callee_arr = NULL;
1008 }
1009
1010 int is_Cast_upcast(ir_node *node)
1011 {
1012         ir_type *totype   = get_Cast_type(node);
1013         ir_type *fromtype = get_irn_typeinfo_type(get_Cast_op(node));
1014
1015         assert(get_irg_typeinfo_state(get_irn_irg(node)) == ir_typeinfo_consistent);
1016         assert(fromtype);
1017
1018         while (is_Pointer_type(totype) && is_Pointer_type(fromtype)) {
1019                 totype   = get_pointer_points_to_type(totype);
1020                 fromtype = get_pointer_points_to_type(fromtype);
1021         }
1022
1023         assert(fromtype);
1024
1025         if (!is_Class_type(totype)) return 0;
1026         return is_SubClass_of(fromtype, totype);
1027 }
1028
1029 int is_Cast_downcast(ir_node *node)
1030 {
1031         ir_type *totype   = get_Cast_type(node);
1032         ir_type *fromtype = get_irn_typeinfo_type(get_Cast_op(node));
1033
1034         assert(get_irg_typeinfo_state(get_irn_irg(node)) == ir_typeinfo_consistent);
1035         assert(fromtype);
1036
1037         while (is_Pointer_type(totype) && is_Pointer_type(fromtype)) {
1038                 totype   = get_pointer_points_to_type(totype);
1039                 fromtype = get_pointer_points_to_type(fromtype);
1040         }
1041
1042         assert(fromtype);
1043
1044         if (!is_Class_type(totype)) return 0;
1045         return is_SubClass_of(totype, fromtype);
1046 }
1047
1048 int (is_unop)(const ir_node *node)
1049 {
1050         return is_unop_(node);
1051 }
1052
1053 ir_node *get_unop_op(const ir_node *node)
1054 {
1055         if (node->op->opar == oparity_unary)
1056                 return get_irn_n(node, node->op->op_index);
1057
1058         assert(node->op->opar == oparity_unary);
1059         return NULL;
1060 }
1061
1062 void set_unop_op(ir_node *node, ir_node *op)
1063 {
1064         if (node->op->opar == oparity_unary)
1065                 set_irn_n(node, node->op->op_index, op);
1066
1067         assert(node->op->opar == oparity_unary);
1068 }
1069
1070 int (is_binop)(const ir_node *node)
1071 {
1072         return is_binop_(node);
1073 }
1074
1075 ir_node *get_binop_left(const ir_node *node)
1076 {
1077         assert(node->op->opar == oparity_binary);
1078         return get_irn_n(node, node->op->op_index);
1079 }
1080
1081 void set_binop_left(ir_node *node, ir_node *left)
1082 {
1083         assert(node->op->opar == oparity_binary);
1084         set_irn_n(node, node->op->op_index, left);
1085 }
1086
1087 ir_node *get_binop_right(const ir_node *node)
1088 {
1089         assert(node->op->opar == oparity_binary);
1090         return get_irn_n(node, node->op->op_index + 1);
1091 }
1092
1093 void set_binop_right(ir_node *node, ir_node *right)
1094 {
1095         assert(node->op->opar == oparity_binary);
1096         set_irn_n(node, node->op->op_index + 1, right);
1097 }
1098
1099 ir_node **get_Phi_preds_arr(ir_node *node)
1100 {
1101   assert(is_Phi(node));
1102   return (ir_node **)&(get_irn_in(node)[1]);
1103 }
1104
1105 int get_Phi_n_preds(const ir_node *node)
1106 {
1107         assert(is_Phi(node));
1108         return get_irn_arity(node);
1109 }
1110
1111 ir_node *get_Phi_pred(const ir_node *node, int pos)
1112 {
1113         assert(is_Phi(node));
1114         return get_irn_n(node, pos);
1115 }
1116
1117 void set_Phi_pred(ir_node *node, int pos, ir_node *pred)
1118 {
1119         assert(is_Phi(node));
1120         set_irn_n(node, pos, pred);
1121 }
1122
1123 ir_node *(get_Phi_next)(const ir_node *phi)
1124 {
1125         return get_Phi_next_(phi);
1126 }
1127
1128 void (set_Phi_next)(ir_node *phi, ir_node *next)
1129 {
1130         set_Phi_next_(phi, next);
1131 }
1132
1133 int is_memop(const ir_node *node)
1134 {
1135         return is_op_uses_memory(get_irn_op(node));
1136 }
1137
1138 ir_node *get_memop_mem(const ir_node *node)
1139 {
1140         const ir_op *op = get_irn_op(node);
1141         assert(is_memop(node));
1142         return get_irn_n(node, op->memory_index);
1143 }
1144
1145 void set_memop_mem(ir_node *node, ir_node *mem)
1146 {
1147         const ir_op *op = get_irn_op(node);
1148         assert(is_memop(node));
1149         set_irn_n(node, op->memory_index, mem);
1150 }
1151
1152 ir_node **get_Sync_preds_arr(ir_node *node)
1153 {
1154         assert(is_Sync(node));
1155         return (ir_node **)&(get_irn_in(node)[1]);
1156 }
1157
1158 int get_Sync_n_preds(const ir_node *node)
1159 {
1160         assert(is_Sync(node));
1161         return (get_irn_arity(node));
1162 }
1163
1164 ir_node *get_Sync_pred(const ir_node *node, int pos)
1165 {
1166         assert(is_Sync(node));
1167         return get_irn_n(node, pos);
1168 }
1169
1170 void set_Sync_pred(ir_node *node, int pos, ir_node *pred)
1171 {
1172         assert(is_Sync(node));
1173         set_irn_n(node, pos, pred);
1174 }
1175
1176 void add_Sync_pred(ir_node *node, ir_node *pred)
1177 {
1178         assert(is_Sync(node));
1179         add_irn_n(node, pred);
1180 }
1181
1182 int (is_arg_Proj)(const ir_node *node)
1183 {
1184         return is_arg_Proj_(node);
1185 }
1186
1187 int is_x_except_Proj(const ir_node *node)
1188 {
1189         ir_node *pred;
1190         if (!is_Proj(node))
1191                 return false;
1192         pred = get_Proj_pred(node);
1193         if (!is_fragile_op(pred))
1194                 return false;
1195         return get_Proj_proj(node) == pred->op->pn_x_except;
1196 }
1197
1198 int is_x_regular_Proj(const ir_node *node)
1199 {
1200         ir_node *pred;
1201         if (!is_Proj(node))
1202                 return false;
1203         pred = get_Proj_pred(node);
1204         if (!is_fragile_op(pred))
1205                 return false;
1206         return get_Proj_proj(node) == pred->op->pn_x_regular;
1207 }
1208
1209 void ir_set_throws_exception(ir_node *node, int throws_exception)
1210 {
1211         except_attr *attr = &node->attr.except;
1212         assert(is_fragile_op(node));
1213         attr->throws_exception = throws_exception;
1214 }
1215
1216 int ir_throws_exception(const ir_node *node)
1217 {
1218         const except_attr *attr = &node->attr.except;
1219         assert(is_fragile_op(node));
1220         return attr->throws_exception;
1221 }
1222
1223 ir_node **get_Tuple_preds_arr(ir_node *node)
1224 {
1225         assert(is_Tuple(node));
1226         return (ir_node **)&(get_irn_in(node)[1]);
1227 }
1228
1229 int get_Tuple_n_preds(const ir_node *node)
1230 {
1231         assert(is_Tuple(node));
1232         return get_irn_arity(node);
1233 }
1234
1235 ir_node *get_Tuple_pred(const ir_node *node, int pos)
1236 {
1237   assert(is_Tuple(node));
1238   return get_irn_n(node, pos);
1239 }
1240
1241 void set_Tuple_pred(ir_node *node, int pos, ir_node *pred)
1242 {
1243         assert(is_Tuple(node));
1244         set_irn_n(node, pos, pred);
1245 }
1246
1247 int get_ASM_n_inputs(const ir_node *node)
1248 {
1249         assert(is_ASM(node));
1250         return get_irn_arity(node) - ASM_PARAM_OFFSET;
1251 }
1252
1253 ir_node *get_ASM_input(const ir_node *node, int pos)
1254 {
1255         return get_irn_n(node, ASM_PARAM_OFFSET + pos);
1256 }
1257
1258 size_t get_ASM_n_output_constraints(const ir_node *node)
1259 {
1260         assert(is_ASM(node));
1261         return ARR_LEN(node->attr.assem.output_constraints);
1262 }
1263
1264 size_t get_ASM_n_clobbers(const ir_node *node)
1265 {
1266         assert(is_ASM(node));
1267         return ARR_LEN(node->attr.assem.clobbers);
1268 }
1269
1270 ir_graph *(get_irn_irg)(const ir_node *node)
1271 {
1272         return get_irn_irg_(node);
1273 }
1274
1275 ir_node *skip_Proj(ir_node *node)
1276 {
1277         /* don't assert node !!! */
1278         if (node == NULL)
1279                 return NULL;
1280
1281         if (is_Proj(node))
1282                 node = get_Proj_pred(node);
1283
1284         return node;
1285 }
1286
1287 const ir_node *
1288 skip_Proj_const(const ir_node *node)
1289 {
1290         /* don't assert node !!! */
1291         if (node == NULL)
1292                 return NULL;
1293
1294         if (is_Proj(node))
1295                 node = get_Proj_pred(node);
1296
1297         return node;
1298 }
1299
1300 ir_node *skip_Tuple(ir_node *node)
1301 {
1302   ir_node *pred;
1303
1304 restart:
1305         if (is_Proj(node)) {
1306             pred = get_Proj_pred(node);
1307
1308                 if (is_Proj(pred)) { /* nested Tuple ? */
1309                     pred = skip_Tuple(pred);
1310
1311                         if (is_Tuple(pred)) {
1312                                 node = get_Tuple_pred(pred, get_Proj_proj(node));
1313                                 goto restart;
1314                         }
1315                 } else if (is_Tuple(pred)) {
1316                         node = get_Tuple_pred(pred, get_Proj_proj(node));
1317                         goto restart;
1318                 }
1319         }
1320         return node;
1321 }
1322
1323 ir_node *skip_Cast(ir_node *node)
1324 {
1325         if (is_Cast(node))
1326                 return get_Cast_op(node);
1327         return node;
1328 }
1329
1330 const ir_node *skip_Cast_const(const ir_node *node)
1331 {
1332         if (is_Cast(node))
1333                 return get_Cast_op(node);
1334         return node;
1335 }
1336
1337 ir_node *skip_Pin(ir_node *node)
1338 {
1339         if (is_Pin(node))
1340                 return get_Pin_op(node);
1341         return node;
1342 }
1343
1344 ir_node *skip_Confirm(ir_node *node)
1345 {
1346         if (is_Confirm(node))
1347                 return get_Confirm_value(node);
1348         return node;
1349 }
1350
1351 ir_node *skip_HighLevel_ops(ir_node *node)
1352 {
1353         while (is_op_highlevel(get_irn_op(node))) {
1354                 node = get_irn_n(node, 0);
1355         }
1356         return node;
1357 }
1358
1359
1360 ir_node *skip_Id(ir_node *node)
1361 {
1362         /* This should compact Id-cycles to self-cycles. It has the same (or less?) complexity
1363          * than any other approach, as Id chains are resolved and all point to the real node, or
1364          * all id's are self loops.
1365          *
1366          * Note: This function takes 10% of mostly ANY the compiler run, so it's
1367          * a little bit "hand optimized".
1368          */
1369         ir_node *pred;
1370         /* don't assert node !!! */
1371
1372         if (!node || (node->op != op_Id)) return node;
1373
1374         /* Don't use get_Id_pred():  We get into an endless loop for
1375            self-referencing Ids. */
1376         pred = node->in[0+1];
1377
1378         if (pred->op != op_Id) return pred;
1379
1380         if (node != pred) {  /* not a self referencing Id. Resolve Id chain. */
1381                 ir_node *rem_pred, *res;
1382
1383                 if (pred->op != op_Id) return pred; /* shortcut */
1384                 rem_pred = pred;
1385
1386                 assert(get_irn_arity (node) > 0);
1387
1388                 node->in[0+1] = node;   /* turn us into a self referencing Id:  shorten Id cycles. */
1389                 res = skip_Id(rem_pred);
1390                 if (is_Id(res)) /* self-loop */ return node;
1391
1392                 node->in[0+1] = res;    /* Turn Id chain into Ids all referencing the chain end. */
1393                 return res;
1394         } else {
1395                 return node;
1396         }
1397 }
1398
1399 int (is_SymConst_addr_ent)(const ir_node *node)
1400 {
1401         return is_SymConst_addr_ent_(node);
1402 }
1403
1404 int is_cfop(const ir_node *node)
1405 {
1406         if (is_fragile_op(node) && ir_throws_exception(node))
1407                 return true;
1408
1409         return is_op_cfopcode(get_irn_op(node));
1410 }
1411
1412 int is_unknown_jump(const ir_node *node)
1413 {
1414         return is_op_unknown_jump(get_irn_op(node));
1415 }
1416
1417 int is_fragile_op(const ir_node *node)
1418 {
1419         return is_op_fragile(get_irn_op(node));
1420 }
1421
1422 int (is_irn_forking)(const ir_node *node)
1423 {
1424         return is_irn_forking_(node);
1425 }
1426
1427 void (copy_node_attr)(ir_graph *irg, const ir_node *old_node, ir_node *new_node)
1428 {
1429         copy_node_attr_(irg, old_node, new_node);
1430 }
1431
1432 ir_type *(get_irn_type_attr)(ir_node *node)
1433 {
1434         return get_irn_type_attr_(node);
1435 }
1436
1437 ir_entity *(get_irn_entity_attr)(ir_node *node)
1438 {
1439         return get_irn_entity_attr_(node);
1440 }
1441
1442 int (is_irn_constlike)(const ir_node *node)
1443 {
1444         return is_irn_constlike_(node);
1445 }
1446
1447 int (is_irn_keep)(const ir_node *node)
1448 {
1449         return is_irn_keep_(node);
1450 }
1451
1452 int (is_irn_start_block_placed)(const ir_node *node)
1453 {
1454         return is_irn_start_block_placed_(node);
1455 }
1456
1457 int (is_irn_cse_neutral)(const ir_node *node)
1458 {
1459         return is_irn_cse_neutral_(node);
1460 }
1461
1462 const char *get_cond_jmp_predicate_name(cond_jmp_predicate pred)
1463 {
1464 #define X(a)    case a: return #a
1465         switch (pred) {
1466                 X(COND_JMP_PRED_NONE);
1467                 X(COND_JMP_PRED_TRUE);
1468                 X(COND_JMP_PRED_FALSE);
1469         }
1470         return "<unknown>";
1471 #undef X
1472 }
1473
1474 /** Return the attribute type of a SymConst node if exists */
1475 static ir_type *get_SymConst_attr_type(const ir_node *self)
1476 {
1477         symconst_kind kind = get_SymConst_kind(self);
1478         if (SYMCONST_HAS_TYPE(kind))
1479                 return get_SymConst_type(self);
1480         return NULL;
1481 }
1482
1483 /** Return the attribute entity of a SymConst node if exists */
1484 static ir_entity *get_SymConst_attr_entity(const ir_node *self)
1485 {
1486         symconst_kind kind = get_SymConst_kind(self);
1487         if (SYMCONST_HAS_ENT(kind))
1488                 return get_SymConst_entity(self);
1489         return NULL;
1490 }
1491
1492 static void register_get_type_func(ir_op *op, get_type_attr_func func)
1493 {
1494         op->ops.get_type_attr = func;
1495 }
1496
1497 static void register_get_entity_func(ir_op *op, get_entity_attr_func func)
1498 {
1499         op->ops.get_entity_attr = func;
1500 }
1501
1502 void ir_register_getter_ops(void)
1503 {
1504         register_get_type_func(op_Alloc,    get_Alloc_type);
1505         register_get_type_func(op_Builtin,  get_Builtin_type);
1506         register_get_type_func(op_Call,     get_Call_type);
1507         register_get_type_func(op_Cast,     get_Cast_type);
1508         register_get_type_func(op_CopyB,    get_CopyB_type);
1509         register_get_type_func(op_Free,     get_Free_type);
1510         register_get_type_func(op_InstOf,   get_InstOf_type);
1511         register_get_type_func(op_SymConst, get_SymConst_attr_type);
1512
1513         register_get_entity_func(op_SymConst, get_SymConst_attr_entity);
1514         register_get_entity_func(op_Sel,      get_Sel_entity);
1515         register_get_entity_func(op_Block,    get_Block_entity);
1516 }
1517
1518 void (set_irn_dbg_info)(ir_node *n, dbg_info *db)
1519 {
1520         set_irn_dbg_info_(n, db);
1521 }
1522
1523 dbg_info *(get_irn_dbg_info)(const ir_node *n)
1524 {
1525         return get_irn_dbg_info_(n);
1526 }
1527
1528 ir_switch_table *ir_new_switch_table(ir_graph *irg, size_t n_entries)
1529 {
1530         struct obstack *obst = get_irg_obstack(irg);
1531         ir_switch_table *res = OALLOCFZ(obst, ir_switch_table, entries, n_entries);
1532         res->n_entries = n_entries;
1533         return res;
1534 }
1535
1536 void ir_switch_table_set(ir_switch_table *table, size_t n,
1537                          ir_tarval *min, ir_tarval *max, long pn)
1538 {
1539         ir_switch_table_entry *entry = ir_switch_table_get_entry(table, n);
1540         entry->min = min;
1541         entry->max = max;
1542         entry->pn  = pn;
1543 }
1544
1545 size_t (ir_switch_table_get_n_entries)(const ir_switch_table *table)
1546 {
1547         return ir_switch_table_get_n_entries_(table);
1548 }
1549
1550 ir_tarval *ir_switch_table_get_max(const ir_switch_table *table, size_t e)
1551 {
1552         return ir_switch_table_get_entry_const(table, e)->max;
1553 }
1554
1555 ir_tarval *ir_switch_table_get_min(const ir_switch_table *table, size_t e)
1556 {
1557         return ir_switch_table_get_entry_const(table, e)->min;
1558 }
1559
1560 long ir_switch_table_get_pn(const ir_switch_table *table, size_t e)
1561 {
1562         return ir_switch_table_get_entry_const(table, e)->pn;
1563 }
1564
1565 ir_switch_table *ir_switch_table_duplicate(ir_graph *irg,
1566                                            const ir_switch_table *table)
1567 {
1568         size_t n_entries = ir_switch_table_get_n_entries(table);
1569         size_t e;
1570         ir_switch_table *res = ir_new_switch_table(irg, n_entries);
1571         for (e = 0; e < n_entries; ++e) {
1572                 const ir_switch_table_entry *entry
1573                         = ir_switch_table_get_entry_const(table, e);
1574                 ir_switch_table_entry *new_entry = ir_switch_table_get_entry(res, e);
1575                 *new_entry = *entry;
1576         }
1577         return res;
1578 }
1579
1580 bool only_used_by_keepalive(const ir_node *node)
1581 {
1582         foreach_out_edge(node, edge) {
1583                 ir_node *succ = get_edge_src_irn(edge);
1584                 if (is_End(succ))
1585                         continue;
1586                 if (is_Proj(succ) && only_used_by_keepalive(succ))
1587                         return true;
1588                 /* found a real user */
1589                 return false;
1590         }
1591         return true;
1592 }
1593
1594 /* include generated code */
1595 #include "gen_irnode.c.inl"