becopyheur2: Cache the admissible registers eagerly.
[libfirm] / ir / ir / irnode.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief   Representation of an intermediate operation.
9  * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Michael Beck
10  */
11 #include "config.h"
12
13 #include <string.h>
14
15 #include "pset_new.h"
16 #include "ident.h"
17 #include "irnode_t.h"
18 #include "irgraph_t.h"
19 #include "irmode_t.h"
20 #include "irbackedge_t.h"
21 #include "irdump.h"
22 #include "irop_t.h"
23 #include "irprog_t.h"
24 #include "iredgekinds.h"
25 #include "iredges_t.h"
26 #include "ircons.h"
27 #include "error.h"
28
29 #include "irhooks.h"
30 #include "irtools.h"
31 #include "util.h"
32
33 #include "beinfo.h"
34
35 /* some constants fixing the positions of nodes predecessors
36    in the in array */
37 #define END_KEEPALIVE_OFFSET  0
38
39 static const char *relation_names [] = {
40         "false",
41         "equal",
42         "less",
43         "less_equal",
44         "greater",
45         "greater_equal",
46         "less_greater",
47         "less_equal_greater",
48         "unordered",
49         "unordered_equal",
50         "unordered_less",
51         "unordered_less_equal",
52         "unordered_greater",
53         "unordered_greater_equal",
54         "not_equal",
55         "true"
56 };
57
58 const char *get_relation_string(ir_relation relation)
59 {
60         assert(relation < (ir_relation)ARRAY_SIZE(relation_names));
61         return relation_names[relation];
62 }
63
64 ir_relation get_negated_relation(ir_relation relation)
65 {
66         return relation ^ ir_relation_true;
67 }
68
69 ir_relation get_inversed_relation(ir_relation relation)
70 {
71         ir_relation code    = relation & ~(ir_relation_less|ir_relation_greater);
72         bool        less    = relation & ir_relation_less;
73         bool        greater = relation & ir_relation_greater;
74         code |= (less ? ir_relation_greater : ir_relation_false)
75               | (greater ? ir_relation_less : ir_relation_false);
76         return code;
77 }
78
79 ir_node *new_ir_node(dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op,
80                      ir_mode *mode, int arity, ir_node *const *in)
81 {
82         int i;
83
84         assert(irg);
85         assert(op);
86         assert(mode);
87
88         size_t   const node_size = offsetof(ir_node, attr) + op->attr_size;
89         ir_node *const res       = (ir_node*)OALLOCNZ(get_irg_obstack(irg), char, node_size);
90
91         res->kind     = k_ir_node;
92         res->op       = op;
93         res->mode     = mode;
94         res->visited  = 0;
95         res->node_idx = irg_register_node_idx(irg, res);
96         res->link     = NULL;
97         res->deps     = NULL;
98
99         if (arity < 0) {
100                 res->in = NEW_ARR_F(ir_node *, 1);  /* 1: space for block */
101         } else {
102                 /* not nice but necessary: End and Sync must always have a flexible array */
103                 if (op == op_End || op == op_Sync)
104                         res->in = NEW_ARR_F(ir_node *, (arity+1));
105                 else
106                         res->in = NEW_ARR_D(ir_node*, get_irg_obstack(irg), arity + 1);
107                 memcpy(&res->in[1], in, sizeof(ir_node *) * arity);
108         }
109
110         res->in[0]   = block;
111         set_irn_dbg_info(res, db);
112         res->node_nr = get_irp_new_node_nr();
113
114         for (i = 0; i < EDGE_KIND_LAST; ++i) {
115                 INIT_LIST_HEAD(&res->edge_info[i].outs_head);
116                 /* edges will be build immediately */
117                 res->edge_info[i].edges_built = 1;
118                 res->edge_info[i].out_count = 0;
119         }
120
121         /* don't put this into the for loop, arity is -1 for some nodes! */
122         if (block != NULL)
123                 edges_notify_edge(res, -1, block, NULL, irg);
124         for (i = 1; i <= arity; ++i)
125                 edges_notify_edge(res, i - 1, res->in[i], NULL, irg);
126
127         hook_new_node(irg, res);
128         if (irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
129                 be_info_new_node(irg, res);
130         }
131
132         return res;
133 }
134
135 int (is_ir_node)(const void *thing)
136 {
137         return is_ir_node_(thing);
138 }
139
140 int (get_irn_arity)(const ir_node *node)
141 {
142         return get_irn_arity_(node);
143 }
144
145 ir_node **get_irn_in(const ir_node *node)
146 {
147         return node->in;
148 }
149
150 void set_irn_in(ir_node *const node, int const arity, ir_node *const *const in)
151 {
152         int i;
153         ir_node *** pOld_in;
154         ir_graph *irg = get_irn_irg(node);
155
156         pOld_in = &node->in;
157
158 #ifndef NDEBUG
159         assert(node != NULL && node->kind == k_ir_node);
160         assert(arity >= 0);
161         for (i = 0; i < arity; ++i) {
162                 assert(in[i] != NULL && in[0]->kind == k_ir_node);
163         }
164 #endif
165
166         for (i = 0; i < arity; i++) {
167                 if (i < (int)ARR_LEN(*pOld_in)-1)
168                         edges_notify_edge(node, i, in[i], (*pOld_in)[i+1], irg);
169                 else
170                         edges_notify_edge(node, i, in[i], NULL,            irg);
171         }
172         for (;i < (int)ARR_LEN(*pOld_in)-1; i++) {
173                 edges_notify_edge(node, i, NULL, (*pOld_in)[i+1], irg);
174         }
175
176         if (arity != (int)ARR_LEN(*pOld_in) - 1) {
177                 ir_node * block = (*pOld_in)[0];
178                 *pOld_in = NEW_ARR_D(ir_node*, get_irg_obstack(irg), arity + 1);
179                 (*pOld_in)[0] = block;
180         }
181         fix_backedges(get_irg_obstack(irg), node);
182
183         memcpy((*pOld_in) + 1, in, sizeof(ir_node *) * arity);
184
185         /* update irg flags */
186         clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
187 }
188
189 ir_node *(get_irn_n)(const ir_node *node, int n)
190 {
191         return get_irn_n_(node, n);
192 }
193
194 void set_irn_n(ir_node *node, int n, ir_node *in)
195 {
196         ir_graph *irg = get_irn_irg(node);
197         assert(node && node->kind == k_ir_node);
198         assert(-1 <= n);
199         assert(n < get_irn_arity(node));
200         assert(in && in->kind == k_ir_node);
201
202         /* Call the hook */
203         hook_set_irn_n(node, n, in, node->in[n + 1]);
204
205         /* Here, we rely on src and tgt being in the current ir graph */
206         edges_notify_edge(node, n, in, node->in[n + 1], irg);
207
208         node->in[n + 1] = in;
209
210         /* update irg flags */
211         clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
212 }
213
214 int add_irn_n(ir_node *node, ir_node *in)
215 {
216         int pos;
217         ir_graph *irg = get_irn_irg(node);
218
219         assert(node->op->opar == oparity_dynamic);
220         pos = ARR_LEN(node->in) - 1;
221         ARR_APP1(ir_node *, node->in, in);
222         edges_notify_edge(node, pos, node->in[pos + 1], NULL, irg);
223
224         /* Call the hook */
225         hook_set_irn_n(node, pos, node->in[pos + 1], NULL);
226
227         /* update irg flags */
228         clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
229
230         return pos;
231 }
232
233 static void del_irn_n(ir_node *node, int n)
234 {
235         ir_graph *irg = get_irn_irg(node);
236
237         /* remove the edge */
238         ir_node *pred = node->in[n+1];
239         edges_notify_edge(node, n, NULL, pred, irg);
240
241         int arity = get_irn_arity(node);
242         if (n != arity-1) {
243                 /* exchange with the last one */
244                 ir_node *old = node->in[arity];
245                 edges_notify_edge(node, arity-1, NULL, old, irg);
246                 node->in[n+1] = old;
247                 edges_notify_edge(node, n, old, NULL, irg);
248         }
249         ARR_SHRINKLEN(node->in, arity);
250
251         /* update irg flags */
252         clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
253 }
254
255 void del_Sync_n(ir_node *n, int i)
256 {
257         del_irn_n(n, i);
258 }
259
260 int (get_irn_deps)(const ir_node *node)
261 {
262         return get_irn_deps_(node);
263 }
264
265 ir_node *(get_irn_dep)(const ir_node *node, int pos)
266 {
267         return get_irn_dep_(node, pos);
268 }
269
270 void set_irn_dep(ir_node *node, int pos, ir_node *dep)
271 {
272         ir_node *old;
273         ir_graph *irg;
274
275         assert(node->deps && "dependency array node yet allocated. use add_irn_dep()");
276         assert(pos >= 0 && pos < (int)ARR_LEN(node->deps) && "dependency index out of range");
277         assert(dep != NULL);
278         old = node->deps[pos];
279         node->deps[pos] = dep;
280         irg = get_irn_irg(node);
281         if (edges_activated_kind(irg, EDGE_KIND_DEP))
282                 edges_notify_edge_kind(node, pos, dep, old, EDGE_KIND_DEP, irg);
283 }
284
285 void add_irn_dep(ir_node *node, ir_node *dep)
286 {
287         ir_graph *irg;
288         assert(dep != NULL);
289         if (node->deps == NULL) {
290                 node->deps = NEW_ARR_F(ir_node *, 0);
291         }
292         ARR_APP1(ir_node*, node->deps, dep);
293         irg = get_irn_irg(node);
294         if (edges_activated_kind(irg, EDGE_KIND_DEP))
295                 edges_notify_edge_kind(node, ARR_LEN(node->deps)-1, dep, NULL, EDGE_KIND_DEP, irg);
296 }
297
298 void delete_irn_dep(ir_node *node, ir_node *dep)
299 {
300         size_t i;
301         size_t n_deps;
302         if (node->deps == NULL)
303                 return;
304
305         n_deps = ARR_LEN(node->deps);
306         for (i = 0; i < n_deps; ++i) {
307                 if (node->deps[i] == dep) {
308                         set_irn_dep(node, i, node->deps[n_deps-1]);
309                         edges_notify_edge(node, i, NULL, dep, get_irn_irg(node));
310                         ARR_SHRINKLEN(node->deps, n_deps-1);
311                         break;
312                 }
313         }
314 }
315
316 void add_irn_deps(ir_node *tgt, ir_node *src)
317 {
318         int i, n;
319
320         for (i = 0, n = get_irn_deps(src); i < n; ++i)
321                 add_irn_dep(tgt, get_irn_dep(src, i));
322 }
323
324
325 ir_mode *(get_irn_mode)(const ir_node *node)
326 {
327         return get_irn_mode_(node);
328 }
329
330 void (set_irn_mode)(ir_node *node, ir_mode *mode)
331 {
332         set_irn_mode_(node, mode);
333 }
334
335 ir_op *(get_irn_op)(const ir_node *node)
336 {
337         return get_irn_op_(node);
338 }
339
340 void (set_irn_op)(ir_node *node, ir_op *op)
341 {
342         set_irn_op_(node, op);
343 }
344
345 unsigned (get_irn_opcode)(const ir_node *node)
346 {
347         return get_irn_opcode_(node);
348 }
349
350 const char *get_irn_opname(const ir_node *node)
351 {
352         return get_id_str(node->op->name);
353 }
354
355 ident *get_irn_opident(const ir_node *node)
356 {
357         assert(node);
358         return node->op->name;
359 }
360
361 ir_visited_t (get_irn_visited)(const ir_node *node)
362 {
363         return get_irn_visited_(node);
364 }
365
366 void (set_irn_visited)(ir_node *node, ir_visited_t visited)
367 {
368         set_irn_visited_(node, visited);
369 }
370
371 void (mark_irn_visited)(ir_node *node)
372 {
373         mark_irn_visited_(node);
374 }
375
376 int (irn_visited)(const ir_node *node)
377 {
378         return irn_visited_(node);
379 }
380
381 int (irn_visited_else_mark)(ir_node *node)
382 {
383         return irn_visited_else_mark_(node);
384 }
385
386 void (set_irn_link)(ir_node *node, void *link)
387 {
388         set_irn_link_(node, link);
389 }
390
391 void *(get_irn_link)(const ir_node *node)
392 {
393         return get_irn_link_(node);
394 }
395
396 op_pin_state (get_irn_pinned)(const ir_node *node)
397 {
398         return get_irn_pinned_(node);
399 }
400
401 op_pin_state (is_irn_pinned_in_irg) (const ir_node *node)
402 {
403         return is_irn_pinned_in_irg_(node);
404 }
405
406 void set_irn_pinned(ir_node *node, op_pin_state state)
407 {
408         /* due to optimization an opt may be turned into a Tuple */
409         if (is_Tuple(node))
410                 return;
411
412         assert(node && get_op_pinned(get_irn_op(node)) >= op_pin_state_exc_pinned);
413         assert(state == op_pin_state_pinned || state == op_pin_state_floats);
414
415         node->attr.except.pin_state = state;
416 }
417
418 long get_irn_node_nr(const ir_node *node)
419 {
420         assert(node);
421         return node->node_nr;
422 }
423
424 void *(get_irn_generic_attr)(ir_node *node)
425 {
426         assert(is_ir_node(node));
427         return get_irn_generic_attr_(node);
428 }
429
430 const void *(get_irn_generic_attr_const)(const ir_node *node)
431 {
432         assert(is_ir_node(node));
433         return get_irn_generic_attr_const_(node);
434 }
435
436 unsigned (get_irn_idx)(const ir_node *node)
437 {
438         assert(is_ir_node(node));
439         return get_irn_idx_(node);
440 }
441
442 ir_node *(get_nodes_block)(const ir_node *node)
443 {
444         return get_nodes_block_(node);
445 }
446
447 void set_nodes_block(ir_node *node, ir_node *block)
448 {
449         assert(!is_Block(node));
450         set_irn_n(node, -1, block);
451 }
452
453 ir_type *is_frame_pointer(const ir_node *n)
454 {
455         if (is_Proj(n) && (get_Proj_proj(n) == pn_Start_P_frame_base)) {
456                 ir_node *start = get_Proj_pred(n);
457                 if (is_Start(start)) {
458                         return get_irg_frame_type(get_irn_irg(start));
459                 }
460         }
461         return NULL;
462 }
463
464 int get_Block_cfgpred_pos(const ir_node *block, const ir_node *pred)
465 {
466         int i;
467
468         for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
469                 if (get_Block_cfgpred_block(block, i) == pred)
470                         return i;
471         }
472         return -1;
473 }
474
475 ir_node *(get_Block_cfgpred_block)(const ir_node *node, int pos)
476 {
477         return get_Block_cfgpred_block_(node, pos);
478 }
479
480 int get_Block_matured(const ir_node *node)
481 {
482         assert(is_Block(node));
483         return (int)node->attr.block.is_matured;
484 }
485
486 void set_Block_matured(ir_node *node, int matured)
487 {
488         assert(is_Block(node));
489         node->attr.block.is_matured = matured;
490 }
491
492 ir_visited_t (get_Block_block_visited)(const ir_node *node)
493 {
494         return get_Block_block_visited_(node);
495 }
496
497 void (set_Block_block_visited)(ir_node *node, ir_visited_t visit)
498 {
499         set_Block_block_visited_(node, visit);
500 }
501
502 void (mark_Block_block_visited)(ir_node *node)
503 {
504         mark_Block_block_visited_(node);
505 }
506
507 int (Block_block_visited)(const ir_node *node)
508 {
509         return Block_block_visited_(node);
510 }
511
512 ir_graph *(get_Block_irg)(const ir_node *block)
513 {
514         return get_Block_irg_(block);
515 }
516
517 ir_entity *create_Block_entity(ir_node *block)
518 {
519         ir_entity *entity;
520         assert(is_Block(block));
521
522         entity = block->attr.block.entity;
523         if (entity == NULL) {
524                 ir_label_t nr = get_irp_next_label_nr();
525                 entity = new_label_entity(nr);
526                 set_entity_visibility(entity, ir_visibility_local);
527                 set_entity_linkage(entity, IR_LINKAGE_CONSTANT);
528                 set_entity_compiler_generated(entity, 1);
529
530                 block->attr.block.entity = entity;
531         }
532         return entity;
533 }
534
535 ir_node *(get_Block_phis)(const ir_node *block)
536 {
537         return get_Block_phis_(block);
538 }
539
540 void (set_Block_phis)(ir_node *block, ir_node *phi)
541 {
542         set_Block_phis_(block, phi);
543 }
544
545 void (add_Block_phi)(ir_node *block, ir_node *phi)
546 {
547         add_Block_phi_(block, phi);
548 }
549
550 unsigned (get_Block_mark)(const ir_node *block)
551 {
552         return get_Block_mark_(block);
553 }
554
555 void (set_Block_mark)(ir_node *block, unsigned mark)
556 {
557         set_Block_mark_(block, mark);
558 }
559
560 void add_End_keepalive(ir_node *end, ir_node *ka)
561 {
562         assert(is_End(end));
563         add_irn_n(end, ka);
564 }
565
566 void set_End_keepalives(ir_node *end, int n, ir_node *in[])
567 {
568         size_t e;
569         int    i;
570         ir_graph *irg = get_irn_irg(end);
571
572         /* notify that edges are deleted */
573         for (e = END_KEEPALIVE_OFFSET; e < ARR_LEN(end->in) - 1; ++e) {
574                 edges_notify_edge(end, e, NULL, end->in[e + 1], irg);
575         }
576         ARR_RESIZE(ir_node *, end->in, n + 1 + END_KEEPALIVE_OFFSET);
577
578         for (i = 0; i < n; ++i) {
579                 end->in[1 + END_KEEPALIVE_OFFSET + i] = in[i];
580                 edges_notify_edge(end, END_KEEPALIVE_OFFSET + i, end->in[1 + END_KEEPALIVE_OFFSET + i], NULL, irg);
581         }
582
583         /* update irg flags */
584         clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
585 }
586
587 void remove_End_keepalive(ir_node *end, ir_node *irn)
588 {
589         int n = get_End_n_keepalives(end);
590         int idx = -1;
591         for (int i = n;;) {
592                 if (i-- == 0)
593                         return;
594
595                 ir_node *old_ka = end->in[1 + END_KEEPALIVE_OFFSET + i];
596
597                 /* find irn */
598                 if (old_ka == irn) {
599                         idx = END_KEEPALIVE_OFFSET + i;
600                         break;
601                 }
602         }
603         assert(idx != -1);
604         del_irn_n(end, idx);
605 }
606
607 void remove_End_Bads_and_doublets(ir_node *end)
608 {
609         pset_new_t keeps;
610         int        idx, n = get_End_n_keepalives(end);
611         ir_graph   *irg;
612         bool       changed = false;
613
614         if (n <= 0)
615                 return;
616
617         irg = get_irn_irg(end);
618         pset_new_init(&keeps);
619
620         for (idx = n - 1; idx >= 0; --idx) {
621                 ir_node *ka = get_End_keepalive(end, idx);
622
623                 if (is_Bad(ka) || is_NoMem(ka) || pset_new_contains(&keeps, ka)) {
624                         changed = true;
625                         del_irn_n(end, idx - END_KEEPALIVE_OFFSET);
626                         --n;
627                 } else {
628                         pset_new_insert(&keeps, ka);
629                 }
630         }
631         pset_new_destroy(&keeps);
632
633         if (changed) {
634                 clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
635         }
636 }
637
638 void free_End(ir_node *end)
639 {
640         assert(is_End(end));
641         end->kind = k_BAD;
642         DEL_ARR_F(end->in);
643         end->in = NULL;   /* @@@ make sure we get an error if we use the
644                              in array afterwards ... */
645 }
646
647 int (is_Const_null)(const ir_node *node)
648 {
649         return is_Const_null_(node);
650 }
651
652 int (is_Const_one)(const ir_node *node)
653 {
654         return is_Const_one_(node);
655 }
656
657 int (is_Const_all_one)(const ir_node *node)
658 {
659         return is_Const_all_one_(node);
660 }
661
662
663
664 symconst_kind get_SymConst_kind(const ir_node *node)
665 {
666         assert(is_SymConst(node));
667         return node->attr.symc.kind;
668 }
669
670 void set_SymConst_kind(ir_node *node, symconst_kind kind)
671 {
672         assert(is_SymConst(node));
673         node->attr.symc.kind = kind;
674 }
675
676 ir_type *get_SymConst_type(const ir_node *node)
677 {
678         /* the cast here is annoying, but we have to compensate for
679            the skip_tip() */
680         ir_node *irn = (ir_node *)node;
681         assert(is_SymConst(node) &&
682                (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
683         return irn->attr.symc.sym.type_p;
684 }
685
686 void set_SymConst_type(ir_node *node, ir_type *tp)
687 {
688         assert(is_SymConst(node) &&
689                (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
690         node->attr.symc.sym.type_p = tp;
691 }
692
693 ir_entity *get_SymConst_entity(const ir_node *node)
694 {
695         assert(is_SymConst(node) && SYMCONST_HAS_ENT(get_SymConst_kind(node)));
696         return node->attr.symc.sym.entity_p;
697 }
698
699 void set_SymConst_entity(ir_node *node, ir_entity *ent)
700 {
701         assert(is_SymConst(node) && SYMCONST_HAS_ENT(get_SymConst_kind(node)));
702         node->attr.symc.sym.entity_p  = ent;
703 }
704
705 ir_enum_const *get_SymConst_enum(const ir_node *node)
706 {
707         assert(is_SymConst(node) && SYMCONST_HAS_ENUM(get_SymConst_kind(node)));
708         return node->attr.symc.sym.enum_p;
709 }
710
711 void set_SymConst_enum(ir_node *node, ir_enum_const *ec)
712 {
713         assert(is_SymConst(node) && SYMCONST_HAS_ENUM(get_SymConst_kind(node)));
714         node->attr.symc.sym.enum_p  = ec;
715 }
716
717 union symconst_symbol
718 get_SymConst_symbol(const ir_node *node)
719 {
720         assert(is_SymConst(node));
721         return node->attr.symc.sym;
722 }
723
724 void set_SymConst_symbol(ir_node *node, union symconst_symbol sym)
725 {
726         assert(is_SymConst(node));
727         node->attr.symc.sym = sym;
728 }
729
730 const char *get_builtin_kind_name(ir_builtin_kind kind)
731 {
732 #define X(a)    case a: return #a
733         switch (kind) {
734                 X(ir_bk_trap);
735                 X(ir_bk_debugbreak);
736                 X(ir_bk_return_address);
737                 X(ir_bk_frame_address);
738                 X(ir_bk_prefetch);
739                 X(ir_bk_ffs);
740                 X(ir_bk_clz);
741                 X(ir_bk_ctz);
742                 X(ir_bk_popcount);
743                 X(ir_bk_parity);
744                 X(ir_bk_bswap);
745                 X(ir_bk_inport);
746                 X(ir_bk_outport);
747                 X(ir_bk_inner_trampoline);
748         }
749         return "<unknown>";
750 #undef X
751 }
752
753
754 int Call_has_callees(const ir_node *node)
755 {
756         assert(is_Call(node));
757         return ((get_irg_callee_info_state(get_irn_irg(node)) != irg_callee_info_none) &&
758                 (node->attr.call.callee_arr != NULL));
759 }
760
761 size_t get_Call_n_callees(const ir_node *node)
762 {
763   assert(is_Call(node) && node->attr.call.callee_arr);
764   return ARR_LEN(node->attr.call.callee_arr);
765 }
766
767 ir_entity *get_Call_callee(const ir_node *node, size_t pos)
768 {
769         assert(pos < get_Call_n_callees(node));
770         return node->attr.call.callee_arr[pos];
771 }
772
773 void set_Call_callee_arr(ir_node *node, size_t n, ir_entity ** arr)
774 {
775         assert(is_Call(node));
776         if (node->attr.call.callee_arr == NULL || get_Call_n_callees(node) != n) {
777                 ir_graph *const irg = get_irn_irg(node);
778                 node->attr.call.callee_arr = NEW_ARR_D(ir_entity*, get_irg_obstack(irg), n);
779         }
780         memcpy(node->attr.call.callee_arr, arr, n * sizeof(ir_entity *));
781 }
782
783 void remove_Call_callee_arr(ir_node *node)
784 {
785         assert(is_Call(node));
786         node->attr.call.callee_arr = NULL;
787 }
788
789 int (is_unop)(const ir_node *node)
790 {
791         return is_unop_(node);
792 }
793
794 ir_node *get_unop_op(const ir_node *node)
795 {
796         if (node->op->opar == oparity_unary)
797                 return get_irn_n(node, node->op->op_index);
798
799         assert(node->op->opar == oparity_unary);
800         return NULL;
801 }
802
803 void set_unop_op(ir_node *node, ir_node *op)
804 {
805         if (node->op->opar == oparity_unary)
806                 set_irn_n(node, node->op->op_index, op);
807
808         assert(node->op->opar == oparity_unary);
809 }
810
811 int (is_binop)(const ir_node *node)
812 {
813         return is_binop_(node);
814 }
815
816 ir_node *get_binop_left(const ir_node *node)
817 {
818         assert(node->op->opar == oparity_binary);
819         return get_irn_n(node, node->op->op_index);
820 }
821
822 void set_binop_left(ir_node *node, ir_node *left)
823 {
824         assert(node->op->opar == oparity_binary);
825         set_irn_n(node, node->op->op_index, left);
826 }
827
828 ir_node *get_binop_right(const ir_node *node)
829 {
830         assert(node->op->opar == oparity_binary);
831         return get_irn_n(node, node->op->op_index + 1);
832 }
833
834 void set_binop_right(ir_node *node, ir_node *right)
835 {
836         assert(node->op->opar == oparity_binary);
837         set_irn_n(node, node->op->op_index + 1, right);
838 }
839
840 ir_node *(get_Phi_next)(const ir_node *phi)
841 {
842         return get_Phi_next_(phi);
843 }
844
845 void (set_Phi_next)(ir_node *phi, ir_node *next)
846 {
847         set_Phi_next_(phi, next);
848 }
849
850 int is_memop(const ir_node *node)
851 {
852         return is_op_uses_memory(get_irn_op(node));
853 }
854
855 ir_node *get_memop_mem(const ir_node *node)
856 {
857         const ir_op *op = get_irn_op(node);
858         assert(is_memop(node));
859         return get_irn_n(node, op->memory_index);
860 }
861
862 void set_memop_mem(ir_node *node, ir_node *mem)
863 {
864         const ir_op *op = get_irn_op(node);
865         assert(is_memop(node));
866         set_irn_n(node, op->memory_index, mem);
867 }
868
869 void add_Sync_pred(ir_node *node, ir_node *pred)
870 {
871         assert(is_Sync(node));
872         add_irn_n(node, pred);
873 }
874
875 int (is_arg_Proj)(const ir_node *node)
876 {
877         return is_arg_Proj_(node);
878 }
879
880 int is_x_except_Proj(const ir_node *node)
881 {
882         ir_node *pred;
883         if (!is_Proj(node))
884                 return false;
885         pred = get_Proj_pred(node);
886         if (!is_fragile_op(pred))
887                 return false;
888         return get_Proj_proj(node) == pred->op->pn_x_except;
889 }
890
891 int is_x_regular_Proj(const ir_node *node)
892 {
893         ir_node *pred;
894         if (!is_Proj(node))
895                 return false;
896         pred = get_Proj_pred(node);
897         if (!is_fragile_op(pred))
898                 return false;
899         return get_Proj_proj(node) == pred->op->pn_x_regular;
900 }
901
902 void ir_set_throws_exception(ir_node *node, int throws_exception)
903 {
904         except_attr *attr = &node->attr.except;
905         assert(is_fragile_op(node));
906         attr->throws_exception = throws_exception;
907 }
908
909 int ir_throws_exception(const ir_node *node)
910 {
911         const except_attr *attr = &node->attr.except;
912         assert(is_fragile_op(node));
913         return attr->throws_exception;
914 }
915
916 size_t get_ASM_n_output_constraints(const ir_node *node)
917 {
918         assert(is_ASM(node));
919         return ARR_LEN(node->attr.assem.output_constraints);
920 }
921
922 size_t get_ASM_n_clobbers(const ir_node *node)
923 {
924         assert(is_ASM(node));
925         return ARR_LEN(node->attr.assem.clobbers);
926 }
927
928 ir_graph *(get_irn_irg)(const ir_node *node)
929 {
930         return get_irn_irg_(node);
931 }
932
933 ir_node *skip_Proj(ir_node *node)
934 {
935         /* don't assert node !!! */
936         if (node == NULL)
937                 return NULL;
938
939         if (is_Proj(node))
940                 node = get_Proj_pred(node);
941
942         return node;
943 }
944
945 const ir_node *
946 skip_Proj_const(const ir_node *node)
947 {
948         /* don't assert node !!! */
949         if (node == NULL)
950                 return NULL;
951
952         if (is_Proj(node))
953                 node = get_Proj_pred(node);
954
955         return node;
956 }
957
958 ir_node *skip_Tuple(ir_node *node)
959 {
960   ir_node *pred;
961
962 restart:
963         if (is_Proj(node)) {
964             pred = get_Proj_pred(node);
965
966                 if (is_Proj(pred)) { /* nested Tuple ? */
967                     pred = skip_Tuple(pred);
968
969                         if (is_Tuple(pred)) {
970                                 node = get_Tuple_pred(pred, get_Proj_proj(node));
971                                 goto restart;
972                         }
973                 } else if (is_Tuple(pred)) {
974                         node = get_Tuple_pred(pred, get_Proj_proj(node));
975                         goto restart;
976                 }
977         }
978         return node;
979 }
980
981 ir_node *skip_Pin(ir_node *node)
982 {
983         if (is_Pin(node))
984                 return get_Pin_op(node);
985         return node;
986 }
987
988 ir_node *skip_Confirm(ir_node *node)
989 {
990         if (is_Confirm(node))
991                 return get_Confirm_value(node);
992         return node;
993 }
994
995 ir_node *skip_HighLevel_ops(ir_node *node)
996 {
997         while (is_op_highlevel(get_irn_op(node))) {
998                 node = get_irn_n(node, 0);
999         }
1000         return node;
1001 }
1002
1003
1004 ir_node *skip_Id(ir_node *node)
1005 {
1006         /* This should compact Id-cycles to self-cycles. It has the same (or less?) complexity
1007          * than any other approach, as Id chains are resolved and all point to the real node, or
1008          * all id's are self loops.
1009          *
1010          * Note: This function takes 10% of mostly ANY the compiler run, so it's
1011          * a little bit "hand optimized".
1012          */
1013         ir_node *pred;
1014         /* don't assert node !!! */
1015
1016         if (!node || (node->op != op_Id)) return node;
1017
1018         /* Don't use get_Id_pred():  We get into an endless loop for
1019            self-referencing Ids. */
1020         pred = node->in[0+1];
1021
1022         if (pred->op != op_Id) return pred;
1023
1024         if (node != pred) {  /* not a self referencing Id. Resolve Id chain. */
1025                 ir_node *rem_pred, *res;
1026
1027                 if (pred->op != op_Id) return pred; /* shortcut */
1028                 rem_pred = pred;
1029
1030                 assert(get_irn_arity (node) > 0);
1031
1032                 node->in[0+1] = node;   /* turn us into a self referencing Id:  shorten Id cycles. */
1033                 res = skip_Id(rem_pred);
1034                 if (is_Id(res)) /* self-loop */ return node;
1035
1036                 node->in[0+1] = res;    /* Turn Id chain into Ids all referencing the chain end. */
1037                 return res;
1038         } else {
1039                 return node;
1040         }
1041 }
1042
1043 int (is_SymConst_addr_ent)(const ir_node *node)
1044 {
1045         return is_SymConst_addr_ent_(node);
1046 }
1047
1048 int is_cfop(const ir_node *node)
1049 {
1050         if (is_fragile_op(node) && ir_throws_exception(node))
1051                 return true;
1052
1053         return is_op_cfopcode(get_irn_op(node));
1054 }
1055
1056 int is_unknown_jump(const ir_node *node)
1057 {
1058         return is_op_unknown_jump(get_irn_op(node));
1059 }
1060
1061 int is_fragile_op(const ir_node *node)
1062 {
1063         return is_op_fragile(get_irn_op(node));
1064 }
1065
1066 int (is_irn_forking)(const ir_node *node)
1067 {
1068         return is_irn_forking_(node);
1069 }
1070
1071 void (copy_node_attr)(ir_graph *irg, const ir_node *old_node, ir_node *new_node)
1072 {
1073         copy_node_attr_(irg, old_node, new_node);
1074 }
1075
1076 ir_type *(get_irn_type_attr)(ir_node *node)
1077 {
1078         return get_irn_type_attr_(node);
1079 }
1080
1081 ir_entity *(get_irn_entity_attr)(ir_node *node)
1082 {
1083         return get_irn_entity_attr_(node);
1084 }
1085
1086 int (is_irn_constlike)(const ir_node *node)
1087 {
1088         return is_irn_constlike_(node);
1089 }
1090
1091 int (is_irn_keep)(const ir_node *node)
1092 {
1093         return is_irn_keep_(node);
1094 }
1095
1096 int (is_irn_start_block_placed)(const ir_node *node)
1097 {
1098         return is_irn_start_block_placed_(node);
1099 }
1100
1101 int (is_irn_cse_neutral)(const ir_node *node)
1102 {
1103         return is_irn_cse_neutral_(node);
1104 }
1105
1106 const char *get_cond_jmp_predicate_name(cond_jmp_predicate pred)
1107 {
1108 #define X(a)    case a: return #a
1109         switch (pred) {
1110                 X(COND_JMP_PRED_NONE);
1111                 X(COND_JMP_PRED_TRUE);
1112                 X(COND_JMP_PRED_FALSE);
1113         }
1114         return "<unknown>";
1115 #undef X
1116 }
1117
1118 /** Return the attribute type of a SymConst node if exists */
1119 static ir_type *get_SymConst_attr_type(const ir_node *self)
1120 {
1121         symconst_kind kind = get_SymConst_kind(self);
1122         if (SYMCONST_HAS_TYPE(kind))
1123                 return get_SymConst_type(self);
1124         return NULL;
1125 }
1126
1127 /** Return the attribute entity of a SymConst node if exists */
1128 static ir_entity *get_SymConst_attr_entity(const ir_node *self)
1129 {
1130         symconst_kind kind = get_SymConst_kind(self);
1131         if (SYMCONST_HAS_ENT(kind))
1132                 return get_SymConst_entity(self);
1133         return NULL;
1134 }
1135
1136 static void register_get_type_func(ir_op *op, get_type_attr_func func)
1137 {
1138         op->ops.get_type_attr = func;
1139 }
1140
1141 static void register_get_entity_func(ir_op *op, get_entity_attr_func func)
1142 {
1143         op->ops.get_entity_attr = func;
1144 }
1145
1146 void ir_register_getter_ops(void)
1147 {
1148         register_get_type_func(op_Alloc,    get_Alloc_type);
1149         register_get_type_func(op_Builtin,  get_Builtin_type);
1150         register_get_type_func(op_Call,     get_Call_type);
1151         register_get_type_func(op_CopyB,    get_CopyB_type);
1152         register_get_type_func(op_Free,     get_Free_type);
1153         register_get_type_func(op_InstOf,   get_InstOf_type);
1154         register_get_type_func(op_SymConst, get_SymConst_attr_type);
1155
1156         register_get_entity_func(op_SymConst, get_SymConst_attr_entity);
1157         register_get_entity_func(op_Sel,      get_Sel_entity);
1158         register_get_entity_func(op_Block,    get_Block_entity);
1159 }
1160
1161 void (set_irn_dbg_info)(ir_node *n, dbg_info *db)
1162 {
1163         set_irn_dbg_info_(n, db);
1164 }
1165
1166 dbg_info *(get_irn_dbg_info)(const ir_node *n)
1167 {
1168         return get_irn_dbg_info_(n);
1169 }
1170
1171 ir_switch_table *ir_new_switch_table(ir_graph *irg, size_t n_entries)
1172 {
1173         struct obstack *obst = get_irg_obstack(irg);
1174         ir_switch_table *res = OALLOCFZ(obst, ir_switch_table, entries, n_entries);
1175         res->n_entries = n_entries;
1176         return res;
1177 }
1178
1179 void ir_switch_table_set(ir_switch_table *table, size_t n,
1180                          ir_tarval *min, ir_tarval *max, long pn)
1181 {
1182         ir_switch_table_entry *entry = ir_switch_table_get_entry(table, n);
1183         entry->min = min;
1184         entry->max = max;
1185         entry->pn  = pn;
1186 }
1187
1188 size_t (ir_switch_table_get_n_entries)(const ir_switch_table *table)
1189 {
1190         return ir_switch_table_get_n_entries_(table);
1191 }
1192
1193 ir_tarval *ir_switch_table_get_max(const ir_switch_table *table, size_t e)
1194 {
1195         return ir_switch_table_get_entry_const(table, e)->max;
1196 }
1197
1198 ir_tarval *ir_switch_table_get_min(const ir_switch_table *table, size_t e)
1199 {
1200         return ir_switch_table_get_entry_const(table, e)->min;
1201 }
1202
1203 long ir_switch_table_get_pn(const ir_switch_table *table, size_t e)
1204 {
1205         return ir_switch_table_get_entry_const(table, e)->pn;
1206 }
1207
1208 ir_switch_table *ir_switch_table_duplicate(ir_graph *irg,
1209                                            const ir_switch_table *table)
1210 {
1211         size_t n_entries = ir_switch_table_get_n_entries(table);
1212         size_t e;
1213         ir_switch_table *res = ir_new_switch_table(irg, n_entries);
1214         for (e = 0; e < n_entries; ++e) {
1215                 const ir_switch_table_entry *entry
1216                         = ir_switch_table_get_entry_const(table, e);
1217                 ir_switch_table_entry *new_entry = ir_switch_table_get_entry(res, e);
1218                 *new_entry = *entry;
1219         }
1220         return res;
1221 }
1222
1223 bool only_used_by_keepalive(const ir_node *node)
1224 {
1225         foreach_out_edge(node, edge) {
1226                 ir_node *succ = get_edge_src_irn(edge);
1227                 if (is_End(succ))
1228                         continue;
1229                 if (is_Proj(succ) && only_used_by_keepalive(succ))
1230                         return true;
1231                 /* found a real user */
1232                 return false;
1233         }
1234         return true;
1235 }
1236
1237 /* include generated code */
1238 #include "gen_irnode.c.inl"