2 * Copyright (C) 1995-2008 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 $
41 void add_loop_son(ir_loop *loop, ir_loop *son) {
43 assert(loop && loop->kind == k_ir_loop);
44 assert(get_kind(son) == k_ir_loop);
46 ARR_APP1(loop_element, loop->children, lson);
50 void add_loop_node(ir_loop *loop, ir_node *n) {
53 assert(loop && loop->kind == k_ir_loop);
54 assert(get_kind(n) == k_ir_node || get_kind(n) == k_ir_graph); /* used in callgraph.c */
55 ARR_APP1(loop_element, loop->children, ln);
60 * Mature all loops by removing the flexible arrays of a loop.
62 void mature_loops(ir_loop *loop, struct obstack *obst) {
63 loop_element *new_children = DUP_ARR_D(loop_element, obst, loop->children);
64 DEL_ARR_F(loop->children);
65 loop->children = new_children;
67 if (loop->n_sons > 0) {
68 /* we have child loops, mature them */
71 for (i = ARR_LEN(new_children) - 1; i >= 0; --i) {
72 loop_element child = new_children[i];
74 if (*child.kind == k_ir_loop) {
75 mature_loops(child.son, obst);
81 /* Returns outer loop, itself if outermost. */
82 ir_loop *(get_loop_outer_loop)(const ir_loop *loop) {
83 return _get_loop_outer_loop(loop);
86 /* Returns nesting depth of this loop */
87 int (get_loop_depth)(const ir_loop *loop) {
88 return _get_loop_depth(loop);
91 /* Returns the number of inner loops */
92 int (get_loop_n_sons)(const ir_loop *loop) {
93 return _get_loop_n_sons(loop);
96 /* Returns the pos`th loop_node-child *
97 * TODO: This method isn`t very efficient ! *
98 * Returns NULL if there isn`t a pos`th loop_node */
99 ir_loop *get_loop_son(ir_loop *loop, int pos) {
100 int child_nr = 0, loop_nr = -1;
102 assert(loop && loop->kind == k_ir_loop);
103 while (child_nr < ARR_LEN(loop->children)) {
104 if (*(loop->children[child_nr].kind) == k_ir_loop)
107 return loop->children[child_nr].son;
113 /* Returns the number of nodes in the loop */
114 int get_loop_n_nodes(ir_loop *loop) {
115 assert(loop); assert(loop->kind == k_ir_loop);
116 return loop->n_nodes;
119 /* Returns the pos'th ir_node-child *
120 * TODO: This method isn't very efficient ! *
121 * Returns NULL if there isn't a pos'th ir_node */
122 ir_node *get_loop_node(ir_loop *loop, int pos) {
123 int child_nr, node_nr = -1;
125 assert(loop && loop->kind == k_ir_loop);
126 assert(pos < get_loop_n_nodes(loop));
128 for (child_nr = 0; child_nr < ARR_LEN(loop->children); child_nr++) {
129 if (*(loop->children[child_nr].kind) == k_ir_node)
132 return loop -> children[child_nr].node;
135 assert(0 && "no child at pos found");
139 /* Returns the number of elements contained in loop. */
140 int get_loop_n_elements(const ir_loop *loop) {
141 assert(loop && loop->kind == k_ir_loop);
142 return(ARR_LEN(loop->children));
146 Returns the pos`th loop element.
147 This may be a loop_node or a ir_node. The caller of this function has
148 to check the *(loop_element.kind) field for "k_ir_node" or "k_ir_loop"
149 and then select the appropriate "loop_element.node" or "loop_element.son".
151 loop_element get_loop_element(const ir_loop *loop, int pos) {
152 assert(loop && loop->kind == k_ir_loop && pos < ARR_LEN(loop->children));
153 return(loop -> children[pos]);
156 int get_loop_element_pos(const ir_loop *loop, void *le) {
158 assert(loop && loop->kind == k_ir_loop);
160 n = get_loop_n_elements(loop);
161 for (i = 0; i < n; i++)
162 if (get_loop_element(loop, i).node == le)
169 * Sets the loop for a node.
171 void set_irn_loop(ir_node *n, ir_loop *loop) {
175 /* Uses temporary information to get the loop */
176 ir_loop *(get_irn_loop)(const ir_node *n) {
177 return _get_irn_loop(n);
180 int get_loop_loop_nr(const ir_loop *loop) {
181 assert(loop && loop->kind == k_ir_loop);
183 return loop->loop_nr;
189 /** A field to connect additional information to a loop. Only valid
190 if libfirm_debug is set. */
191 void set_loop_link(ir_loop *loop, void *link) {
192 assert(loop && loop->kind == k_ir_loop);
195 void *get_loop_link(const ir_loop *loop) {
196 assert(loop && loop->kind == k_ir_loop);
200 int (is_ir_loop)(const void *thing) {
201 return _is_ir_loop(thing);
204 /* The outermost loop is remarked in the surrounding graph. */
205 void (set_irg_loop)(ir_graph *irg, ir_loop *loop) {
206 _set_irg_loop(irg, loop);
209 /* Returns the root loop info (if exists) for an irg. */
210 ir_loop *(get_irg_loop)(ir_graph *irg) {
211 return _get_irg_loop(irg);
215 * Allocates a new loop as son of father on the given obstack.
216 * If father is equal NULL, a new root loop is created.
218 ir_loop *alloc_loop(ir_loop *father, struct obstack *obst) {
221 son = obstack_alloc(obst, sizeof(*son));
222 memset(son, 0, sizeof(*son));
223 son->kind = k_ir_loop;
224 son->children = NEW_ARR_F(loop_element, 0);
229 son->outer_loop = father;
230 add_loop_son(father, son);
231 son->depth = father->depth + 1;
232 } else { /* The root loop */
233 son->outer_loop = son;
238 son->loop_nr = get_irp_new_node_nr();