irbackedge.c 5.37 KB
Newer Older
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Matthias Braun's avatar
Matthias Braun committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
Götz Lindenmaier's avatar
Götz Lindenmaier committed
18
 */
19

Matthias Braun's avatar
Matthias Braun committed
20
21
22
23
24
25
26
/**
 * @file
 * @brief     Access function for backedges.
 * @author    Goetz Lindenmaier
 * @date      7.2002
 * @version   $Id$
 */
27
28
#include "config.h"

29
#include "irnode_t.h"
30
#include "irgraph_t.h"
31
32
#include "array.h"
#include "irbackedge_t.h"
33
#include "raw_bitset.h"
34

Michael Beck's avatar
Michael Beck committed
35
/*--------------------------------------------------------------------*/
Götz Lindenmaier's avatar
Götz Lindenmaier committed
36
/* Backedge information.                                              */
Michael Beck's avatar
Michael Beck committed
37
38
39
40
41
42
43
44
45
46
/*--------------------------------------------------------------------*/


/**
 * Returns backarray if the node can have backedges, else returns
 * NULL.
 *
 * Does not assert whether the backarray is correct -- use
 * very careful!
 */
47
48
static unsigned *mere_get_backarray(ir_node *n)
{
49
50
51
	switch (get_irn_opcode(n)) {
	case iro_Block:
		if (!get_Block_matured(n)) return NULL;
52
#ifdef INTERPROCEDURAL_VIEW
53
54
55
56
		if (get_interprocedural_view() && n->attr.block.in_cg) {
			assert(n->attr.block.cg_backedge && "backedge array not allocated!");
			return n->attr.block.cg_backedge;
		}
57
58
59
60
#endif

		assert(n->attr.block.backedge && "backedge array not allocated!");
		return n->attr.block.backedge;
61
	case iro_Phi:
62
63
		assert(n->attr.phi.u.backedge && "backedge array not allocated!");
		return n->attr.phi.u.backedge;
64
	case iro_Filter:
65
#ifdef INTERPROCEDURAL_VIEW
66
67
68
69
		if (get_interprocedural_view()) {
			assert(n->attr.filter.backedge && "backedge array not allocated!");
			return n->attr.filter.backedge;
		}
70
71
72
#endif
		break;
	default:
73
74
75
		break;
	}
	return NULL;
76
77
}

Michael Beck's avatar
Michael Beck committed
78
79
80
81
/**
 * Returns backarray if the node can have backedges, else returns
 * NULL.
 */
82
83
static unsigned *get_backarray(ir_node *n)
{
84
	unsigned *ba = mere_get_backarray(n);
85

86
#ifndef NDEBUG
87
88
89
90
91
	if (ba) {
		int bal = rbitset_size(ba);  /* avoid macro expansion in assertion. */
		int inl = get_irn_arity(n);
		assert(bal == inl && "backedge array with faulty length");
	}
92
#endif
93

94
	return ba;
95
96
}

97
#ifndef NDEBUG
Michael Beck's avatar
Michael Beck committed
98
/**
99
 * Returns non-zero if node has no backarray, or
100
 *                  if size of backarray == size of in array.
Michael Beck's avatar
Michael Beck committed
101
 */
102
103
static int legal_backarray(ir_node *n)
{
104
	unsigned *ba = mere_get_backarray(n);
105
	if (ba && (rbitset_size(ba) != (unsigned) get_irn_arity(n)))
106
107
		return 0;
	return 1;
108
}
109
#endif
110

111
112
void fix_backedges(struct obstack *obst, ir_node *n)
{
113
114
115
116
117
118
119
120
	unsigned *arr = mere_get_backarray(n);
	ir_opcode opc;
	int arity;

	if (! arr)
		return;

	arity = get_irn_arity(n);
121
	if (rbitset_size(arr) != (unsigned) arity) {
122
123
124
125
		arr = new_backedge_arr(obst, arity);

		opc = get_irn_opcode(n);
		if (opc == iro_Phi)
126
			n->attr.phi.u.backedge = arr;
127
		else if (opc == iro_Block) {
128
#ifdef INTERPROCEDURAL_VIEW
129
130
			if (get_interprocedural_view())
				n->attr.block.cg_backedge = arr;
131
			else
132
#endif
133
				n->attr.block.backedge = arr;
134
135
136
137
138
139
		}
		else if (opc == iro_Filter)
			n->attr.filter.backedge = arr;
	}

	assert(legal_backarray(n));
140
141
}

142
#ifdef INTERPROCEDURAL_VIEW
143
144
int is_inter_backedge(ir_node *n, int pos)
{
145
146
147
148
149
150
	int res;
	int rem = get_interprocedural_view();
	set_interprocedural_view(0);
	res = is_backedge(n, pos);
	set_interprocedural_view(rem);
	return res;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
151
152
}

153
154
int is_intra_backedge(ir_node *n, int pos)
{
155
156
157
158
159
160
	int res;
	int rem = get_interprocedural_view();
	set_interprocedural_view(1);
	res = is_backedge(n, pos);
	set_interprocedural_view(rem);
	return res;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
161
}
162
#endif
Götz Lindenmaier's avatar
Götz Lindenmaier committed
163
164


165
/* Returns non-zero if the predecessor pos is a backedge. */
166
167
int is_backedge(ir_node *n, int pos)
{
168
169
170
171
	unsigned *ba = get_backarray(n);
	if (ba)
		return rbitset_is_set(ba, pos);
	return 0;
172
173
}

174
/* Remarks that edge pos is a backedge. */
175
176
void set_backedge(ir_node *n, int pos)
{
177
178
179
	unsigned *ba = get_backarray(n);
	assert(ba && "can only set backedges at Phi, Filter, Block nodes.");
	rbitset_set(ba, pos);
180
181
}

182
/* Remarks that edge pos is a backedge. */
183
184
void set_not_backedge(ir_node *n, int pos)
{
185
186
187
	unsigned *ba = get_backarray(n);
	assert(ba && "can only set backedges at Phi, Filter, Block nodes.");
	rbitset_clear(ba, pos);
188
189
}

190
/* Returns non-zero if n has backedges. */
191
192
int has_backedges(ir_node *n)
{
193
194
195
196
197
198
	unsigned *ba = get_backarray(n);
	if (ba) {
		int arity = get_irn_arity(n);
		return !rbitset_is_empty(ba, arity);
	}
	return 0;
199
200
}

Michael Beck's avatar
Michael Beck committed
201
/** Sets all backedge information to zero. */
202
203
void clear_backedges(ir_node *n)
{
204
205
	int i, arity;
	unsigned *ba;
206
#ifdef INTERPROCEDURAL_VIEW
207
208
	int rem = get_interprocedural_view();
	set_interprocedural_view(0);
209
#endif
210
211
212
213
214
215
	ba = get_backarray(n);
	if (ba) {
		arity = get_irn_arity(n);
		for (i = 0; i < arity; i++)
			rbitset_clear(ba, i);
	}
216
#ifdef INTERPROCEDURAL_VIEW
217
218
219
220
221
222
223
224
	set_interprocedural_view(1);
	ba = get_backarray (n);
	if (ba) {
		arity = get_irn_arity(n);
		for (i = 0; i < arity; i++)
			rbitset_clear(ba, i);
	}
	set_interprocedural_view(rem);
225
#endif
226
}
227

228
/* Allocate a new backedge array on the obstack for given size. */
229
230
unsigned *new_backedge_arr(struct obstack *obst, unsigned size)
{
231
	return rbitset_w_size_obstack_alloc(obst, size);
232
}