add some const qualifiers to backedges query functions
[libfirm] / ir / ana / irbackedge.c
1 /*
2  * Copyright (C) 1995-2011 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     Access function for backedges.
23  * @author    Goetz Lindenmaier
24  * @date      7.2002
25  * @version   $Id$
26  */
27 #include "config.h"
28
29 #include "irnode_t.h"
30 #include "irgraph_t.h"
31 #include "array.h"
32 #include "irbackedge_t.h"
33 #include "raw_bitset.h"
34
35 /*--------------------------------------------------------------------*/
36 /* Backedge information.                                              */
37 /*--------------------------------------------------------------------*/
38
39
40 /**
41  * Returns backarray if the node can have backedges, else returns
42  * NULL.
43  *
44  * Does not assert whether the backarray is correct -- use
45  * very careful!
46  */
47 static bitset_t *mere_get_backarray(const ir_node *n)
48 {
49         switch (get_irn_opcode(n)) {
50         case iro_Block:
51                 if (!get_Block_matured(n)) return NULL;
52
53                 assert(n->attr.block.backedge && "backedge array not allocated!");
54                 return n->attr.block.backedge;
55         case iro_Phi:
56                 assert(n->attr.phi.u.backedge && "backedge array not allocated!");
57                 return n->attr.phi.u.backedge;
58         default:
59                 break;
60         }
61         return NULL;
62 }
63
64 /**
65  * Returns backarray if the node can have backedges, else returns
66  * NULL.
67  */
68 static bitset_t *get_backarray(const ir_node *n)
69 {
70         bitset_t *ba = mere_get_backarray(n);
71
72 #ifndef NDEBUG
73         if (ba) {
74                 size_t bal = bitset_size(ba);  /* avoid macro expansion in assertion. */
75                 size_t inl = get_irn_arity(n);
76                 assert(bal == inl && "backedge array with faulty length");
77         }
78 #endif
79
80         return ba;
81 }
82
83 #ifndef NDEBUG
84 /**
85  * Returns non-zero if node has no backarray, or
86  *                  if size of backarray == size of in array.
87  */
88 static int legal_backarray(const ir_node *n)
89 {
90         bitset_t *ba = mere_get_backarray(n);
91         if (ba && (bitset_size(ba) != (unsigned) get_irn_arity(n)))
92                 return 0;
93         return 1;
94 }
95 #endif
96
97 void fix_backedges(struct obstack *obst, ir_node *n)
98 {
99         bitset_t *arr = mere_get_backarray(n);
100         unsigned opc;
101         int arity;
102
103         if (! arr)
104                 return;
105
106         arity = get_irn_arity(n);
107         if (bitset_size(arr) != (unsigned) arity) {
108                 arr = new_backedge_arr(obst, arity);
109
110                 opc = get_irn_opcode(n);
111                 if (opc == iro_Phi)
112                         n->attr.phi.u.backedge = arr;
113                 else if (opc == iro_Block) {
114                         n->attr.block.backedge = arr;
115                 }
116         }
117
118         assert(legal_backarray(n));
119 }
120
121 /* Returns non-zero if the predecessor pos is a backedge. */
122 int is_backedge(const ir_node *n, int pos)
123 {
124         bitset_t *ba = get_backarray(n);
125         if (ba)
126                 return bitset_is_set(ba, pos);
127         return 0;
128 }
129
130 /* Remarks that edge pos is a backedge. */
131 void set_backedge(ir_node *n, int pos)
132 {
133         bitset_t *ba = get_backarray(n);
134         assert(ba && "can only set backedges at Phi, Block nodes.");
135         bitset_set(ba, pos);
136 }
137
138 /* Remarks that edge pos is a backedge. */
139 void set_not_backedge(ir_node *n, int pos)
140 {
141         bitset_t *ba = get_backarray(n);
142         assert(ba && "can only set backedges at Phi, Block nodes.");
143         bitset_clear(ba, pos);
144 }
145
146 /* Returns non-zero if n has backedges. */
147 int has_backedges(const ir_node *n)
148 {
149         bitset_t *ba = get_backarray(n);
150         if (ba != NULL) {
151                 return !bitset_is_empty(ba);
152         }
153         return 0;
154 }
155
156 /** Sets all backedge information to zero. */
157 void clear_backedges(ir_node *n)
158 {
159         bitset_t *ba = get_backarray(n);
160         if (ba != NULL) {
161                 bitset_clear_all(ba);
162         }
163 }
164
165 /* Allocate a new backedge array on the obstack for given size. */
166 bitset_t *new_backedge_arr(struct obstack *obst, size_t size)
167 {
168         return bitset_obstack_alloc(obst, size);
169 }