irbackedge.c 3.92 KB
Newer Older
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1
/*
2
 * Copyright (C) 1995-2011 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
static bitset_t *mere_get_backarray(ir_node *n)
48
{
49
50
51
	switch (get_irn_opcode(n)) {
	case iro_Block:
		if (!get_Block_matured(n)) return NULL;
52
53
54

		assert(n->attr.block.backedge && "backedge array not allocated!");
		return n->attr.block.backedge;
55
	case iro_Phi:
56
57
		assert(n->attr.phi.u.backedge && "backedge array not allocated!");
		return n->attr.phi.u.backedge;
58
	default:
59
60
61
		break;
	}
	return NULL;
62
63
}

Michael Beck's avatar
Michael Beck committed
64
65
66
67
/**
 * Returns backarray if the node can have backedges, else returns
 * NULL.
 */
68
static bitset_t *get_backarray(ir_node *n)
69
{
70
	bitset_t *ba = mere_get_backarray(n);
71

72
#ifndef NDEBUG
73
	if (ba) {
74
75
		size_t bal = bitset_size(ba);  /* avoid macro expansion in assertion. */
		size_t inl = get_irn_arity(n);
76
77
		assert(bal == inl && "backedge array with faulty length");
	}
78
#endif
79

80
	return ba;
81
82
}

83
#ifndef NDEBUG
Michael Beck's avatar
Michael Beck committed
84
/**
85
 * Returns non-zero if node has no backarray, or
86
 *                  if size of backarray == size of in array.
Michael Beck's avatar
Michael Beck committed
87
 */
88
89
static int legal_backarray(ir_node *n)
{
90
91
	bitset_t *ba = mere_get_backarray(n);
	if (ba && (bitset_size(ba) != (unsigned) get_irn_arity(n)))
92
93
		return 0;
	return 1;
94
}
95
#endif
96

97
98
void fix_backedges(struct obstack *obst, ir_node *n)
{
99
	bitset_t *arr = mere_get_backarray(n);
100
	unsigned opc;
101
102
103
104
105
106
	int arity;

	if (! arr)
		return;

	arity = get_irn_arity(n);
107
	if (bitset_size(arr) != (unsigned) arity) {
108
109
110
111
		arr = new_backedge_arr(obst, arity);

		opc = get_irn_opcode(n);
		if (opc == iro_Phi)
112
			n->attr.phi.u.backedge = arr;
113
		else if (opc == iro_Block) {
114
			n->attr.block.backedge = arr;
115
116
117
118
		}
	}

	assert(legal_backarray(n));
119
120
}

121
/* Returns non-zero if the predecessor pos is a backedge. */
122
123
int is_backedge(ir_node *n, int pos)
{
124
	bitset_t *ba = get_backarray(n);
125
	if (ba)
126
		return bitset_is_set(ba, pos);
127
	return 0;
128
129
}

130
/* Remarks that edge pos is a backedge. */
131
132
void set_backedge(ir_node *n, int pos)
{
133
	bitset_t *ba = get_backarray(n);
134
	assert(ba && "can only set backedges at Phi, Block nodes.");
135
	bitset_set(ba, pos);
136
137
}

138
/* Remarks that edge pos is a backedge. */
139
140
void set_not_backedge(ir_node *n, int pos)
{
141
	bitset_t *ba = get_backarray(n);
142
	assert(ba && "can only set backedges at Phi, Block nodes.");
143
	bitset_clear(ba, pos);
144
145
}

146
/* Returns non-zero if n has backedges. */
147
148
int has_backedges(ir_node *n)
{
149
150
151
	bitset_t *ba = get_backarray(n);
	if (ba != NULL) {
		return !bitset_is_empty(ba);
152
153
	}
	return 0;
154
155
}

Michael Beck's avatar
Michael Beck committed
156
/** Sets all backedge information to zero. */
157
158
void clear_backedges(ir_node *n)
{
159
160
161
	bitset_t *ba = get_backarray(n);
	if (ba != NULL) {
		bitset_clear_all(ba);
162
	}
163
}
164

165
/* Allocate a new backedge array on the obstack for given size. */
166
bitset_t *new_backedge_arr(struct obstack *obst, unsigned size)
167
{
168
	return bitset_obstack_alloc(obst, size);
169
}