beinfo.c 5.14 KB
Newer Older
Matthias Braun's avatar
Matthias Braun committed
1
/*
Michael Beck's avatar
Michael Beck committed
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
18
19
20
21
22
23
24
25
 *
 * 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.
 */

/**
 * @file
 * @author      Matthias Braun
 */
#include "config.h"

26
27
#include <stdbool.h>

Matthias Braun's avatar
Matthias Braun committed
28
#include "beinfo.h"
29
#include "beirg.h"
30
#include "bearch.h"
31
#include "benode.h"
32
#include "besched.h"
Matthias Braun's avatar
Matthias Braun committed
33
34
#include "bedump.h"
#include "belive_t.h"
Matthias Braun's avatar
Matthias Braun committed
35
36
#include "irgwalk.h"
#include "irnode_t.h"
37
#include "irdump_t.h"
Matthias Braun's avatar
Matthias Braun committed
38
#include "irhooks.h"
Matthias Braun's avatar
Matthias Braun committed
39
40
#include "error.h"

41
static copy_attr_func old_phi_copy_attr;
Matthias Braun's avatar
Matthias Braun committed
42

43
void be_info_new_node(ir_graph *irg, ir_node *node)
Matthias Braun's avatar
Matthias Braun committed
44
{
Michael Beck's avatar
Michael Beck committed
45
46
47
	struct obstack *obst;
	backend_info_t *info;

48
	/* Projs need no be info, all info is fetched from their predecessor */
49
	if (is_Proj(node))
50
51
		return;

52
	obst = be_get_be_obst(irg);
53
	info = OALLOCZ(obst, backend_info_t);
Matthias Braun's avatar
Matthias Braun committed
54

55
56
57
	assert(node->backend_info == NULL);
	node->backend_info = info;

58
59
60
	/*
	 * Set backend info for some middleend nodes which still appear in
	 * backend graphs
61
	 */
62
63
64
	switch (get_irn_opcode(node)) {
	case iro_Block:
	case iro_Dummy:
65
	case iro_NoMem:
66
	case iro_Anchor:
67
68
	case iro_Pin:
	case iro_Sync:
69
70
71
	case iro_Bad:
	case iro_End:
	case iro_Unknown:
72
73
74
75
76
77
78
79
80
81
82
83
		info->flags |= arch_irn_flags_not_scheduled;
		info->out_infos = NEW_ARR_D(reg_out_info_t, obst, 1);
		memset(info->out_infos, 0, 1 * sizeof(info->out_infos[0]));
		info->out_infos[0].req = arch_no_register_req;
		break;
	case iro_Phi:
		info->out_infos = NEW_ARR_D(reg_out_info_t, obst, 1);
		memset(info->out_infos, 0, 1 * sizeof(info->out_infos[0]));
		info->out_infos[0].req = arch_no_register_req;
		break;
	default:
		break;
Matthias Braun's avatar
Matthias Braun committed
84
85
86
	}
}

87
static void new_phi_copy_attr(ir_graph *irg, const ir_node *old_node,
88
                              ir_node *new_node)
Matthias Braun's avatar
Matthias Braun committed
89
90
91
92
{
	backend_info_t *old_info = be_get_info(old_node);
	backend_info_t *new_info = be_get_info(new_node);

93
94
	*new_info = *old_info;

95
	old_phi_copy_attr(irg, old_node, new_node);
Matthias Braun's avatar
Matthias Braun committed
96
97
}

Michael Beck's avatar
Michael Beck committed
98
int be_nodes_equal(const ir_node *node1, const ir_node *node2)
Matthias Braun's avatar
Matthias Braun committed
99
{
100
101
	const backend_info_t *info1 = be_get_info(node1);
	const backend_info_t *info2 = be_get_info(node2);
102
	size_t                len   = ARR_LEN(info1->out_infos);
Matthias Braun's avatar
Matthias Braun committed
103
104
	int                   arity = get_irn_arity(node1);
	int                   in;
105
	size_t                i;
Matthias Braun's avatar
Matthias Braun committed
106
107

	if (ARR_LEN(info2->out_infos) != len)
108
		return false;
Matthias Braun's avatar
Matthias Braun committed
109

110
111
	assert(arity == get_irn_arity(node2));

Matthias Braun's avatar
Matthias Braun committed
112
113
	for (in = 0; in < arity; ++in) {
		if (info1->in_reqs[in] != info2->in_reqs[in])
114
115
116
			return false;
	}

Matthias Braun's avatar
Matthias Braun committed
117
118
119
120
	for (i = 0; i < len; ++i) {
		const reg_out_info_t *out1 = &info1->out_infos[i];
		const reg_out_info_t *out2 = &info2->out_infos[i];
		if (out1->reg != out2->reg)
121
			return false;
Matthias Braun's avatar
Matthias Braun committed
122
		if (!reg_reqs_equal(out1->req, out2->req))
123
			return false;
Matthias Braun's avatar
Matthias Braun committed
124
125
	}

126
127
	return true;
}
Matthias Braun's avatar
Matthias Braun committed
128
129
130

static void init_walker(ir_node *node, void *data)
{
131
	ir_graph *irg = get_irn_irg(node);
Matthias Braun's avatar
Matthias Braun committed
132
	(void) data;
133
	be_info_new_node(irg, node);
Matthias Braun's avatar
Matthias Braun committed
134
135
}

Matthias Braun's avatar
Matthias Braun committed
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
static bool         initialized = false;
static hook_entry_t hook_liveness_info;

static void dump_liveness_info_hook(void *context, FILE *F, const ir_node *node)
{
	(void)context;
	if (!is_Block(node))
		return;
	ir_graph *irg = get_irn_irg(node);
	if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND))
		return;

	be_lv_t *lv = be_get_irg_liveness(irg);
	if (lv == NULL)
		return;
	if (!lv->sets_valid)
		return;

	be_dump_liveness_block(lv, F, node);
}
Matthias Braun's avatar
Matthias Braun committed
156
157
158

void be_info_init(void)
{
159
	if (initialized)
Matthias Braun's avatar
Matthias Braun committed
160
161
162
		panic("double initialization of be_info");

	old_phi_copy_attr = op_Phi->ops.copy_attr;
163
	op_Phi->ops.copy_attr = new_phi_copy_attr;
164
165
166
167
168
	initialized = true;

	/* phis have register and register requirements now which we want to dump */
	assert(op_Phi->ops.dump_node == NULL);
	op_Phi->ops.dump_node = be_dump_phi_reg_reqs;
Matthias Braun's avatar
Matthias Braun committed
169
170
171

	hook_liveness_info.hook._hook_node_info = dump_liveness_info_hook;
	register_hook(hook_node_info, &hook_liveness_info);
Matthias Braun's avatar
Matthias Braun committed
172
173
}

174
175
176
/**
 * Edge hook to dump the schedule edges.
 */
177
static void sched_edge_hook(FILE *F, const ir_node *irn)
178
179
180
181
{
	if (get_irn_irg(irn)->be_data == NULL)
		return;

182
	if (!is_Proj(irn) && sched_is_scheduled(irn) && !is_Block(irn)) {
183
184
185
186
187
188
189
190
		ir_node *const prev = sched_prev(irn);
		if (!sched_is_begin(prev)) {
			fprintf(F, "edge:{sourcename: ");
			print_nodeid(F, irn);
			fprintf(F, " targetname: ");
			print_nodeid(F, prev);
			fprintf(F, " color:magenta}\n");
		}
191
192
193
	}
}

Matthias Braun's avatar
Matthias Braun committed
194
195
196
void be_info_init_irg(ir_graph *irg)
{
	irg_walk_anchors(irg, init_walker, NULL, NULL);
197
198

	set_dump_node_edge_hook(sched_edge_hook);
Matthias Braun's avatar
Matthias Braun committed
199
200
201
202
203
}

void be_info_free(void)
{
	if (!initialized)
204
		panic("called without prior init");
Matthias Braun's avatar
Matthias Braun committed
205

206
	assert(op_Phi->ops.copy_attr == new_phi_copy_attr);
Matthias Braun's avatar
Matthias Braun committed
207
	op_Phi->ops.copy_attr = old_phi_copy_attr;
208
209
210
211
	initialized = false;

	assert(op_Phi->ops.dump_node == be_dump_phi_reg_reqs);
	op_Phi->ops.dump_node = NULL;
Matthias Braun's avatar
Matthias Braun committed
212
213

	unregister_hook(hook_node_info, &hook_liveness_info);
Matthias Braun's avatar
Matthias Braun committed
214
}