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