2 * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief Loop datastructure and access functions -- private stuff.
23 * @author Goetz Lindenmaier
25 * @version $Id: irloop_t.h 17143 2008-01-02 20:56:33Z beck $
36 void add_loop_son(ir_loop *loop, ir_loop *son)
39 assert(loop && loop->kind == k_ir_loop);
40 assert(get_kind(son) == k_ir_loop);
42 ARR_APP1(loop_element, loop->children, lson);
44 loop->flags |= loop_outer_loop;
47 void add_loop_node(ir_loop *loop, ir_node *n)
51 assert(loop && loop->kind == k_ir_loop);
52 ARR_APP1(loop_element, loop->children, ln);
56 void add_loop_irg(ir_loop *loop, ir_graph *irg)
60 assert(loop && loop->kind == k_ir_loop);
61 ARR_APP1(loop_element, loop->children, ln);
66 * Mature all loops by removing the flexible arrays of a loop.
68 * @param loop the loop to mature
69 * @param obst an obstack, where the new arrays are allocated on
71 void mature_loops(ir_loop *loop, struct obstack *obst)
73 loop_element *new_children = DUP_ARR_D(loop_element, obst, loop->children);
74 DEL_ARR_F(loop->children);
75 loop->children = new_children;
77 if (loop->n_sons > 0) {
78 /* we have child loops, mature them */
81 for (i = ARR_LEN(new_children); i > 0;) {
82 loop_element child = new_children[--i];
84 if (*child.kind == k_ir_loop) {
85 mature_loops(child.son, obst);
91 /* Returns outer loop, itself if outermost. */
92 ir_loop *(get_loop_outer_loop)(const ir_loop *loop)
94 return _get_loop_outer_loop(loop);
97 /* Returns nesting depth of this loop */
98 unsigned (get_loop_depth)(const ir_loop *loop)
100 return _get_loop_depth(loop);
103 /* Returns the number of inner loops */
104 size_t (get_loop_n_sons)(const ir_loop *loop)
106 return _get_loop_n_sons(loop);
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, size_t pos)
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)
122 return loop->children[child_nr].son;
128 /* Returns the number of nodes in the loop */
129 size_t get_loop_n_nodes(const ir_loop *loop)
132 assert(loop->kind == k_ir_loop);
133 return loop->n_nodes;
136 /* Returns the pos'th ir_node-child *
137 * TODO: This method isn't very efficient ! *
138 * Returns NULL if there isn't a pos'th ir_node */
139 ir_node *get_loop_node(const ir_loop *loop, size_t pos)
144 assert(loop && loop->kind == k_ir_loop);
145 assert(pos < get_loop_n_nodes(loop));
147 for (child_nr = 0; child_nr < ARR_LEN(loop->children); ++child_nr) {
148 if (*(loop->children[child_nr].kind) != k_ir_node)
151 return loop -> children[child_nr].node;
154 panic("no child at pos found");
157 /* Returns the number of elements contained in loop. */
158 size_t get_loop_n_elements(const ir_loop *loop)
160 assert(loop && loop->kind == k_ir_loop);
161 return(ARR_LEN(loop->children));
164 loop_element get_loop_element(const ir_loop *loop, size_t pos)
166 assert(loop && loop->kind == k_ir_loop && pos < ARR_LEN(loop->children));
167 return(loop -> children[pos]);
170 size_t get_loop_element_pos(const ir_loop *loop, void *le)
174 assert(loop && loop->kind == k_ir_loop);
176 n = get_loop_n_elements(loop);
177 for (i = 0; i < n; i++)
178 if (get_loop_element(loop, i).node == le)
180 return INVALID_LOOP_POS;
185 * Sets the loop for a node.
187 void set_irn_loop(ir_node *n, ir_loop *loop)
192 ir_loop *(get_irn_loop)(const ir_node *n)
194 return _get_irn_loop(n);
197 long get_loop_loop_nr(const ir_loop *loop)
199 assert(loop && loop->kind == k_ir_loop);
201 return loop->loop_nr;
207 void set_loop_link(ir_loop *loop, void *link)
209 assert(loop && loop->kind == k_ir_loop);
213 void *get_loop_link(const ir_loop *loop)
215 assert(loop && loop->kind == k_ir_loop);
219 int (is_ir_loop)(const void *thing)
221 return _is_ir_loop(thing);
224 /* The outermost loop is remarked in the surrounding graph. */
225 void (set_irg_loop)(ir_graph *irg, ir_loop *loop)
227 _set_irg_loop(irg, loop);
230 /* Returns the root loop info (if exists) for an irg. */
231 ir_loop *(get_irg_loop)(const ir_graph *irg)
233 return _get_irg_loop(irg);
237 * Allocates a new loop as son of father on the given obstack.
238 * If father is equal NULL, a new root loop is created.
240 ir_loop *alloc_loop(ir_loop *father, struct obstack *obst)
244 son = OALLOCZ(obst, ir_loop);
245 son->kind = k_ir_loop;
246 son->children = NEW_ARR_F(loop_element, 0);
251 son->outer_loop = father;
252 add_loop_son(father, son);
253 son->depth = father->depth + 1;
254 } else { /* The root loop */
255 son->outer_loop = son;
260 son->loop_nr = get_irp_new_node_nr();