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