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  */
26 #include "config.h"
27 
28 #include <string.h>
29 #include <stdlib.h>
30 
31 #include "irloop_t.h"
32 #include "irprog_t.h"
33 #include "error.h"
34 
add_loop_son(ir_loop * loop,ir_loop * son)35 void add_loop_son(ir_loop *loop, ir_loop *son)
36 {
37 	loop_element lson;
38 	assert(loop && loop->kind == k_ir_loop);
39 	assert(get_kind(son) == k_ir_loop);
40 	lson.son = son;
41 	ARR_APP1(loop_element, loop->children, lson);
42 	loop->flags |= loop_outer_loop;
43 }
44 
add_loop_node(ir_loop * loop,ir_node * n)45 void add_loop_node(ir_loop *loop, ir_node *n)
46 {
47 	loop_element ln;
48 	ln.node = n;
49 	assert(loop && loop->kind == k_ir_loop);
50 	ARR_APP1(loop_element, loop->children, ln);
51 }
52 
add_loop_irg(ir_loop * loop,ir_graph * irg)53 void add_loop_irg(ir_loop *loop, ir_graph *irg)
54 {
55 	loop_element ln;
56 	ln.irg = irg;
57 	assert(loop && loop->kind == k_ir_loop);
58 	ARR_APP1(loop_element, loop->children, ln);
59 }
60 
mature_loops(ir_loop * loop,struct obstack * obst)61 void mature_loops(ir_loop *loop, struct obstack *obst)
62 {
63 	size_t i;
64 
65 	loop_element *new_children = DUP_ARR_D(loop_element, obst, loop->children);
66 	DEL_ARR_F(loop->children);
67 	loop->children = new_children;
68 
69 	/* mature child loops */
70 	for (i = ARR_LEN(new_children); i > 0;) {
71 		loop_element child = new_children[--i];
72 
73 		if (*child.kind == k_ir_loop) {
74 			mature_loops(child.son, obst);
75 		}
76 	}
77 }
78 
79 ir_loop *(get_loop_outer_loop)(const ir_loop *loop)
80 {
81 	return _get_loop_outer_loop(loop);
82 }
83 
84 unsigned (get_loop_depth)(const ir_loop *loop)
85 {
86 	return _get_loop_depth(loop);
87 }
88 
get_loop_n_elements(const ir_loop * loop)89 size_t get_loop_n_elements(const ir_loop *loop)
90 {
91 	assert(loop && loop->kind == k_ir_loop);
92 	return(ARR_LEN(loop->children));
93 }
94 
get_loop_element(const ir_loop * loop,size_t pos)95 loop_element get_loop_element(const ir_loop *loop, size_t pos)
96 {
97 	assert(loop && loop->kind == k_ir_loop && pos < ARR_LEN(loop->children));
98 	return(loop -> children[pos]);
99 }
100 
set_irn_loop(ir_node * n,ir_loop * loop)101 void set_irn_loop(ir_node *n, ir_loop *loop)
102 {
103 	n->loop = loop;
104 }
105 
106 ir_loop *(get_irn_loop)(const ir_node *n)
107 {
108 	return _get_irn_loop(n);
109 }
110 
get_loop_loop_nr(const ir_loop * loop)111 long get_loop_loop_nr(const ir_loop *loop)
112 {
113 	assert(loop && loop->kind == k_ir_loop);
114 #ifdef DEBUG_libfirm
115 	return loop->loop_nr;
116 #else
117 	return (long)loop;
118 #endif
119 }
120 
set_loop_link(ir_loop * loop,void * link)121 void set_loop_link(ir_loop *loop, void *link)
122 {
123 	assert(loop && loop->kind == k_ir_loop);
124 	loop->link = link;
125 }
126 
get_loop_link(const ir_loop * loop)127 void *get_loop_link(const ir_loop *loop)
128 {
129 	assert(loop && loop->kind == k_ir_loop);
130 	return loop->link;
131 }
132 
133 int (is_ir_loop)(const void *thing)
134 {
135 	return _is_ir_loop(thing);
136 }
137 
138 void (set_irg_loop)(ir_graph *irg, ir_loop *loop)
139 {
140 	_set_irg_loop(irg, loop);
141 }
142 
143 ir_loop *(get_irg_loop)(const ir_graph *irg)
144 {
145 	return _get_irg_loop(irg);
146 }
147 
alloc_loop(ir_loop * father,struct obstack * obst)148 ir_loop *alloc_loop(ir_loop *father, struct obstack *obst)
149 {
150 	ir_loop *son;
151 
152 	son = OALLOCZ(obst, ir_loop);
153 	son->kind     = k_ir_loop;
154 	son->children = NEW_ARR_F(loop_element, 0);
155 	son->link     = NULL;
156 	if (father) {
157 		son->outer_loop = father;
158 		add_loop_son(father, son);
159 		son->depth = father->depth + 1;
160 	} else {  /* The root loop */
161 		son->outer_loop = son;
162 		son->depth      = 0;
163 	}
164 
165 #ifdef DEBUG_libfirm
166 	son->loop_nr = get_irp_new_node_nr();
167 #endif
168 
169 	return son;
170 }
171