returns after assert(0) inserted
[libfirm] / ir / ana / irbackedge.c
1 /* Copyright (C) 2002 by Universitaet Karlsruhe
2 * All rights reserved.
3 *
4 * Authors:  Goetz Lindenmaier
5 *
6 * irbackedges.c  Access function for backedges.
7 *
8 */
9
10 /* $Id$ */
11
12 #include "irnode_t.h"
13 #include "array.h"
14 #include "irbackedge_t.h"
15
16 /*--------------------------------------------------------------------*/
17 /* Backedge information. *                                            */
18 /*--------------------------------------------------------------------*/
19
20
21 /**
22  * Returns backarray if the node can have backedges, else returns
23  * NULL.
24  *
25  * Does not assert whether the backarray is correct -- use
26  * very careful!
27  */
28 static INLINE int *mere_get_backarray(ir_node *n) {
29   switch(get_irn_opcode(n)) {
30   case iro_Block:
31     if (!get_Block_matured(n)) return NULL;
32     if (interprocedural_view && n->attr.block.in_cg) {
33       assert(n->attr.block.cg_backedge && "backedge array not allocated!");
34       return n->attr.block.cg_backedge;
35     } else {
36       assert(n->attr.block.backedge && "backedge array not allocated!");
37       return n->attr.block.backedge;
38     }
39     break;
40   case iro_Phi:
41       assert(n->attr.phi_backedge && "backedge array not allocated!");
42     return n->attr.phi_backedge;
43     break;
44   case iro_Filter:
45     if (interprocedural_view) {
46       assert(n->attr.filter.backedge && "backedge array not allocated!");
47       return n->attr.filter.backedge;
48     }
49     break;
50   default: ;
51   }
52   return NULL;
53 }
54
55 /**
56  * Returns backarray if the node can have backedges, else returns
57  * NULL.
58  */
59 static INLINE int *get_backarray(ir_node *n) {
60   int *ba = mere_get_backarray(n);
61
62   if (ba) {
63     int bal = ARR_LEN(ba);  /* avoid makro expansion in assertion. */
64     int inl = ARR_LEN(get_irn_in(n)) -1;  /* Use get_irn_in -- sensitive to view! */
65     assert(bal == inl && "backedge array with faulty length");
66   }
67
68   return ba;
69 }
70
71 /**
72  * Returns true if node has no backarray, or
73  *              if size of backarray == size of in array.
74  */
75 static INLINE bool legal_backarray (ir_node *n) {
76   int *ba = mere_get_backarray(n);
77   if (ba && (ARR_LEN(ba) != ARR_LEN(get_irn_in(n))-1))  /* Use get_irn_in -- sensitive to view! */
78     return false;
79   return true;
80 }
81
82
83 INLINE void fix_backedges(struct obstack *obst, ir_node *n) {
84   opcode opc = get_irn_opcode(n);
85   int *arr = mere_get_backarray(n);
86   if (ARR_LEN(arr) == ARR_LEN(get_irn_in(n))-1)
87     return;
88   if (ARR_LEN(arr) != ARR_LEN(get_irn_in(n))-1) {
89     arr = new_backedge_arr(obst, ARR_LEN(get_irn_in(n))-1);
90     if (opc == iro_Phi)    n->attr.phi_backedge = arr;
91     if ((opc == iro_Block) && !interprocedural_view)
92       n->attr.block.backedge = arr;
93     if ((opc == iro_Block) && interprocedural_view)
94       n->attr.block.cg_backedge = arr;
95     if (opc == iro_Filter) n->attr.filter.backedge = arr;
96     return;
97   }
98   assert(legal_backarray(n));
99   /* @@@ more efficient in memory consumption, not possible with
100    array implementation.
101   if (ARR_LEN(arr) < ARR_LEN(get_irn_in(n))-1) {
102     ARR_SETLEN(int, arr, ARR_LEN(get_irn_in(n))-1);
103   }*/
104 }
105
106 /** Returns true if the predesessor pos is a backedge. */
107 bool is_backedge (ir_node *n, int pos) {
108   int *ba = get_backarray (n);
109   if (ba) return ba[pos];
110   return false;
111 }
112
113 /** Remarks that edge pos is a backedge. */
114 void set_backedge (ir_node *n, int pos) {
115   int *ba = get_backarray (n);
116   assert(ba && "can only set backedges at Phi, Filter, Block nodes.");
117   ba[pos] = 1;
118 }
119
120 /** Remarks that edge pos is a backedge. */
121 void set_not_backedge (ir_node *n, int pos) {
122   int *ba = get_backarray (n);
123   assert(ba && "can only set backedges at Phi, Filter, Block nodes.");
124   ba[pos] = 0;
125 }
126
127 /** Returns true if n has backedges. */
128 bool has_backedges (ir_node *n) {
129   int i;
130   int *ba = get_backarray (n);
131   if (ba)
132     for (i = 0; i < get_irn_arity(n); i++)
133       if (ba[i]) return true;
134   return false;
135 }
136
137 /** Sets all backedge information to zero. */
138 void clear_backedges (ir_node *n) {
139   int i, rem = interprocedural_view;
140   int *ba;
141   interprocedural_view = 0;
142   ba = get_backarray (n);
143   if (ba)
144     for (i = 0; i < get_irn_arity(n); i++)
145       ba[i] = 0;
146   interprocedural_view = 1;
147   ba = get_backarray (n);
148   if (ba)
149     for (i = 0; i < get_irn_arity(n); i++)
150       ba[i] = 0;
151   interprocedural_view = rem;
152 }