Fixed more size_t related warnings.
[libfirm] / ir / ana / irloop.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    Loop datastructure and access functions -- private stuff.
23  * @author   Goetz Lindenmaier
24  * @date     7.2002
25  * @version  $Id: irloop_t.h 17143 2008-01-02 20:56:33Z beck $
26  */
27 # include "config.h"
28
29 #include <string.h>
30 #include <stdlib.h>
31
32 #include "irloop_t.h"
33 #include "irprog_t.h"
34 #include "error.h"
35
36 void add_loop_son(ir_loop *loop, ir_loop *son)
37 {
38         loop_element lson;
39         assert(loop && loop->kind == k_ir_loop);
40         assert(get_kind(son) == k_ir_loop);
41         lson.son = son;
42         ARR_APP1(loop_element, loop->children, lson);
43         ++loop->n_sons;
44         loop->flags |= loop_outer_loop;
45 }
46
47 void add_loop_node(ir_loop *loop, ir_node *n)
48 {
49         loop_element ln;
50         ln.node = n;
51         assert(loop && loop->kind == k_ir_loop);
52         ARR_APP1(loop_element, loop->children, ln);
53         loop->n_nodes++;
54 }
55
56 void add_loop_irg(ir_loop *loop, ir_graph *irg)
57 {
58         loop_element ln;
59         ln.irg = irg;
60         assert(loop && loop->kind == k_ir_loop);
61         ARR_APP1(loop_element, loop->children, ln);
62         loop->n_nodes++;
63 }
64
65 /**
66  * Mature all loops by removing the flexible arrays of a loop.
67  *
68  * @param loop  the loop to mature
69  * @param obst  an obstack, where the new arrays are allocated on
70  */
71 void mature_loops(ir_loop *loop, struct obstack *obst)
72 {
73         loop_element *new_children = DUP_ARR_D(loop_element, obst, loop->children);
74         DEL_ARR_F(loop->children);
75         loop->children = new_children;
76
77         if (loop->n_sons > 0) {
78                 /* we have child loops, mature them */
79                 int i;
80
81                 for (i = ARR_LEN(new_children) - 1; i >= 0; --i) {
82                         loop_element child = new_children[i];
83
84                         if (*child.kind == k_ir_loop) {
85                                 mature_loops(child.son, obst);
86                         }
87                 }
88         }
89 }
90
91 /* Returns outer loop, itself if outermost. */
92 ir_loop *(get_loop_outer_loop)(const ir_loop *loop)
93 {
94         return _get_loop_outer_loop(loop);
95 }
96
97 /* Returns nesting depth of this loop */
98 int (get_loop_depth)(const ir_loop *loop)
99 {
100         return _get_loop_depth(loop);
101 }
102
103 /* Returns the number of inner loops */
104 int (get_loop_n_sons)(const ir_loop *loop)
105 {
106         return _get_loop_n_sons(loop);
107 }
108
109 /* Returns the pos`th loop_node-child              *
110  * TODO: This method isn`t very efficient !        *
111  * Returns NULL if there isn`t a pos`th loop_node */
112 ir_loop *get_loop_son(ir_loop *loop, int pos)
113 {
114         size_t child_nr = 0;
115         int loop_nr = -1;
116
117         assert(loop && loop->kind == k_ir_loop);
118         for (child_nr = 0; child_nr < ARR_LEN(loop->children); ++child_nr) {
119                 if (*(loop->children[child_nr].kind) == k_ir_loop)
120                         loop_nr++;
121                 if (loop_nr == pos)
122                         return loop->children[child_nr].son;
123         }
124         return NULL;
125 }
126
127 /* Returns the number of nodes in the loop */
128 int get_loop_n_nodes(const ir_loop *loop)
129 {
130         assert(loop); assert(loop->kind == k_ir_loop);
131         return loop->n_nodes;
132 }
133
134 /* Returns the pos'th ir_node-child                *
135  * TODO: This method isn't very efficient !        *
136  * Returns NULL if there isn't a pos'th ir_node   */
137 ir_node *get_loop_node(const ir_loop *loop, int pos)
138 {
139         size_t child_nr;
140         int node_nr = -1;
141
142         assert(loop && loop->kind == k_ir_loop);
143         assert(pos < get_loop_n_nodes(loop));
144
145         for (child_nr = 0; child_nr < ARR_LEN(loop->children); ++child_nr) {
146                 if (*(loop->children[child_nr].kind) == k_ir_node)
147                         node_nr++;
148                 if (node_nr == pos)
149                         return loop -> children[child_nr].node;
150         }
151
152         panic("no child at pos found");
153 }
154
155 /* Returns the number of elements contained in loop.  */
156 int get_loop_n_elements(const ir_loop *loop)
157 {
158         assert(loop && loop->kind == k_ir_loop);
159         return(ARR_LEN(loop->children));
160 }
161
162 /*
163 Returns the pos`th loop element.
164 This may be a loop_node or a ir_node. The caller of this function has
165 to check the *(loop_element.kind) field for "k_ir_node" or "k_ir_loop"
166 and then select the appropriate "loop_element.node" or "loop_element.son".
167 */
168 loop_element get_loop_element(const ir_loop *loop, int pos)
169 {
170         assert(loop && loop->kind == k_ir_loop && pos < ARR_LEN(loop->children));
171         return(loop -> children[pos]);
172 }
173
174 int get_loop_element_pos(const ir_loop *loop, void *le)
175 {
176         int i, n;
177         assert(loop && loop->kind == k_ir_loop);
178
179         n = get_loop_n_elements(loop);
180         for (i = 0; i < n; i++)
181                 if (get_loop_element(loop, i).node == le)
182                         return i;
183         return -1;
184 }
185
186
187 /**
188  * Sets the loop for a node.
189  */
190 void set_irn_loop(ir_node *n, ir_loop *loop)
191 {
192         n->loop = loop;
193 }
194
195 ir_loop *(get_irn_loop)(const ir_node *n)
196 {
197         return _get_irn_loop(n);
198 }
199
200 int get_loop_loop_nr(const ir_loop *loop)
201 {
202         assert(loop && loop->kind == k_ir_loop);
203 #ifdef DEBUG_libfirm
204         return loop->loop_nr;
205 #else
206         return (int)loop;
207 #endif
208 }
209
210 void set_loop_link(ir_loop *loop, void *link)
211 {
212         assert(loop && loop->kind == k_ir_loop);
213         loop->link = link;
214 }
215
216 void *get_loop_link(const ir_loop *loop)
217 {
218         assert(loop && loop->kind == k_ir_loop);
219         return loop->link;
220 }
221
222 int (is_ir_loop)(const void *thing)
223 {
224         return _is_ir_loop(thing);
225 }
226
227 /* The outermost loop is remarked in the surrounding graph. */
228 void (set_irg_loop)(ir_graph *irg, ir_loop *loop)
229 {
230         _set_irg_loop(irg, loop);
231 }
232
233 /* Returns the root loop info (if exists) for an irg. */
234 ir_loop *(get_irg_loop)(const ir_graph *irg)
235 {
236         return _get_irg_loop(irg);
237 }
238
239 /*
240  * Allocates a new loop as son of father on the given obstack.
241  * If father is equal NULL, a new root loop is created.
242  */
243 ir_loop *alloc_loop(ir_loop *father, struct obstack *obst)
244 {
245         ir_loop *son;
246
247         son = OALLOCZ(obst, ir_loop);
248         son->kind     = k_ir_loop;
249         son->children = NEW_ARR_F(loop_element, 0);
250         son->n_nodes  = 0;
251         son->n_sons   = 0;
252         son->link     = NULL;
253         if (father) {
254                 son->outer_loop = father;
255                 add_loop_son(father, son);
256                 son->depth = father->depth + 1;
257         } else {  /* The root loop */
258                 son->outer_loop = son;
259                 son->depth      = 0;
260         }
261
262 #ifdef DEBUG_libfirm
263         son->loop_nr = get_irp_new_node_nr();
264 #endif
265
266         return son;
267 }