benode.c 40.6 KB
Newer Older
Sebastian Hack's avatar
Sebastian Hack committed
1
2
3
4
5
6
7
/**
 * @file   benode.c
 * @date   17.05.2005
 * @author Sebastian Hack
 *
 * Backend node support.
 *
Michael Beck's avatar
Michael Beck committed
8
 * This file provides Perm, Copy, Spill and Reload nodes.
9
 *
10
 * Copyright (C) 2005-2006 Universitaet Karlsruhe
Sebastian Hack's avatar
Sebastian Hack committed
11
12
 * Released under the GPL
 */
13

Michael Beck's avatar
Michael Beck committed
14
15
16
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
Sebastian Hack's avatar
Sebastian Hack committed
17
18
19
20
21
22

#include <stdlib.h>

#include "obst.h"
#include "set.h"
#include "pmap.h"
23
#include "util.h"
Sebastian Hack's avatar
Sebastian Hack committed
24
#include "debug.h"
25
#include "fourcc.h"
Sebastian Hack's avatar
Sebastian Hack committed
26
#include "offset.h"
Sebastian Hack's avatar
Sebastian Hack committed
27
#include "bitfiddle.h"
Sebastian Hack's avatar
Sebastian Hack committed
28
29
30
31

#include "irop_t.h"
#include "irmode_t.h"
#include "irnode_t.h"
32
#include "ircons_t.h"
33
#include "irprintf.h"
Sebastian Hack's avatar
Sebastian Hack committed
34
#include "irgwalk.h"
Michael Beck's avatar
Michael Beck committed
35
#include "iropt_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
36

37
38
39
#include "be_t.h"
#include "belive_t.h"
#include "besched_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
40
41
#include "benode_t.h"

42
43
#include "beirgmod.h"

Sebastian Hack's avatar
Sebastian Hack committed
44
45
#define OUT_POS(x) (-((x) + 1))

Sebastian Hack's avatar
Sebastian Hack committed
46
47
/* Sometimes we want to put const nodes into get_irn_generic_attr ... */
#define get_irn_attr(irn) get_irn_generic_attr((ir_node *) (irn))
Daniel Grund's avatar
Daniel Grund committed
48

Sebastian Hack's avatar
Sebastian Hack committed
49
static unsigned be_node_tag = FOURCC('B', 'E', 'N', 'O');
50

Sebastian Hack's avatar
Sebastian Hack committed
51
52
53
54
55
56
typedef enum {
	be_req_kind_old_limited,
	be_req_kind_negate_old_limited,
	be_req_kind_single_reg
} be_req_kind_t;

Sebastian Hack's avatar
Sebastian Hack committed
57
58
typedef struct {
	arch_register_req_t req;
Sebastian Hack's avatar
Sebastian Hack committed
59
	be_req_kind_t       kind;
Sebastian Hack's avatar
Sebastian Hack committed
60
	arch_irn_flags_t    flags;
Sebastian Hack's avatar
Sebastian Hack committed
61
62
63
64
65
66
67
68
	union {
		struct {
			void (*old_limited)(void *ptr, bitset_t *bs);
			void *old_limited_env;
		} old_limited;

		const arch_register_t *single_reg;
	} x;
Sebastian Hack's avatar
Sebastian Hack committed
69
70
} be_req_t;

71
typedef struct {
72
	const arch_register_t *reg;
Sebastian Hack's avatar
Sebastian Hack committed
73
	be_req_t              req;
Sebastian Hack's avatar
Sebastian Hack committed
74
	be_req_t              in_req;
75
76
} be_reg_data_t;

77
/** The generic be nodes attribute type. */
78
typedef struct {
79
80
	int                   max_reg_data;
	be_reg_data_t         *reg_data;
81
82
} be_node_attr_t;

83
84
85
86
87
88
/** The be_Return nodes attribute type. */
typedef struct {
	be_node_attr_t node_attr;
	int            num_ret_vals;  /**< number of return values */
} be_return_attr_t;

89
/** The be_Stack attribute type. */
Sebastian Hack's avatar
Sebastian Hack committed
90
91
typedef struct {
	be_node_attr_t node_attr;
92
	int offset;           /**< The offset by which the stack shall be expanded/shrinked. */
Sebastian Hack's avatar
Sebastian Hack committed
93
94
} be_stack_attr_t;

95
/** The be_Frame attribute type. */
96
97
98
99
100
101
typedef struct {
	be_node_attr_t node_attr;
	entity *ent;
	int offset;
} be_frame_attr_t;

102
/** The be_Call attribute type. */
103
104
typedef struct {
	be_node_attr_t node_attr;
105
106
	entity *ent;         /**< The called entity if this is a static call. */
	ir_type *call_tp;    /**< The call type, copied from the original Call node. */
107
108
} be_call_attr_t;

109
typedef struct {
Matthias Braun's avatar
Matthias Braun committed
110
111
112
113
	be_node_attr_t node_attr;
	entity **in_entities;
	entity **out_entities;
} be_memperm_attr_t;
114

115
116
117
ir_op *op_be_Spill;
ir_op *op_be_Reload;
ir_op *op_be_Perm;
Matthias Braun's avatar
Matthias Braun committed
118
ir_op *op_be_MemPerm;
119
120
ir_op *op_be_Copy;
ir_op *op_be_Keep;
Sebastian Hack's avatar
Sebastian Hack committed
121
ir_op *op_be_CopyKeep;
122
123
124
ir_op *op_be_Call;
ir_op *op_be_Return;
ir_op *op_be_IncSP;
Sebastian Hack's avatar
Sebastian Hack committed
125
ir_op *op_be_AddSP;
126
127
128
129
130
131
ir_op *op_be_SetSP;
ir_op *op_be_RegParams;
ir_op *op_be_StackParam;
ir_op *op_be_FrameAddr;
ir_op *op_be_FrameLoad;
ir_op *op_be_FrameStore;
132
ir_op *op_be_Barrier;
Sebastian Hack's avatar
Sebastian Hack committed
133

Sebastian Hack's avatar
Sebastian Hack committed
134
static int beo_base = -1;
Sebastian Hack's avatar
Sebastian Hack committed
135

Sebastian Hack's avatar
Sebastian Hack committed
136
static const ir_op_ops be_node_op_ops;
Sebastian Hack's avatar
Sebastian Hack committed
137

138
139
140
141
142
143
144
145
146
147
#define N   irop_flag_none
#define L   irop_flag_labeled
#define C   irop_flag_commutative
#define X   irop_flag_cfopcode
#define I   irop_flag_ip_cfopcode
#define F   irop_flag_fragile
#define Y   irop_flag_forking
#define H   irop_flag_highlevel
#define c   irop_flag_constlike
#define K   irop_flag_keep
148
149
#define M   irop_flag_machine

150

Michael Beck's avatar
Michael Beck committed
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/**
 * Compare two node attributes.
 *
 * @return zero if both attributes are identically
 */
static int cmp_node_attr(be_node_attr_t *a, be_node_attr_t *b) {
	if (a->max_reg_data == b->max_reg_data) {
		int i;

		for (i = 0; i < a->max_reg_data; ++i) {
			if (a->reg_data[i].reg    != b->reg_data[i].reg ||
			    memcmp(&a->reg_data[i].in_req, &b->reg_data[i].in_req, sizeof(b->reg_data[i].in_req)) ||
			    memcmp(&a->reg_data[i].req,    &b->reg_data[i].req,    sizeof(a->reg_data[i].req)))
				return 1;
		}
		return 0;
	}
	return 1;
}

/**
 * Compare the attributes of two FrameAddr nodes.
 *
 * @return zero if both attributes are identically
 */
static int FrameAddr_cmp_attr(ir_node *a, ir_node *b) {
	be_frame_attr_t *a_attr = get_irn_attr(a);
	be_frame_attr_t *b_attr = get_irn_attr(b);

180
181
182
	if (a_attr->ent == b_attr->ent && a_attr->offset == b_attr->offset)
		return cmp_node_attr(&a_attr->node_attr, &b_attr->node_attr);
	return 1;
Michael Beck's avatar
Michael Beck committed
183
184
}

Sebastian Hack's avatar
Sebastian Hack committed
185
186
void be_node_init(void) {
	static int inited = 0;
Sebastian Hack's avatar
Sebastian Hack committed
187

Sebastian Hack's avatar
Sebastian Hack committed
188
189
	if(inited)
		return;
Sebastian Hack's avatar
Sebastian Hack committed
190

Sebastian Hack's avatar
Sebastian Hack committed
191
	inited = 1;
Sebastian Hack's avatar
Sebastian Hack committed
192

193
194
	/* Acquire all needed opcodes. */
	beo_base = get_next_ir_opcodes(beo_Last - 1);
Sebastian Hack's avatar
Sebastian Hack committed
195

Matthias Braun's avatar
Matthias Braun committed
196
197
198
199
200
201
202
	op_be_Spill      = new_ir_op(beo_base + beo_Spill,      "be_Spill",      op_pin_state_mem_pinned, N, oparity_unary,    0, sizeof(be_frame_attr_t),   &be_node_op_ops);
	op_be_Reload     = new_ir_op(beo_base + beo_Reload,     "be_Reload",     op_pin_state_mem_pinned, N, oparity_zero,     0, sizeof(be_frame_attr_t),   &be_node_op_ops);
	op_be_Perm       = new_ir_op(beo_base + beo_Perm,       "be_Perm",       op_pin_state_pinned,     N, oparity_variable, 0, sizeof(be_node_attr_t),    &be_node_op_ops);
	op_be_MemPerm    = new_ir_op(beo_base + beo_MemPerm,    "be_MemPerm",    op_pin_state_mem_pinned, N, oparity_variable, 0, sizeof(be_memperm_attr_t), &be_node_op_ops);
	op_be_Copy       = new_ir_op(beo_base + beo_Copy,       "be_Copy",       op_pin_state_floats,     N, oparity_unary,    0, sizeof(be_node_attr_t),    &be_node_op_ops);
	op_be_Keep       = new_ir_op(beo_base + beo_Keep,       "be_Keep",       op_pin_state_pinned,     K, oparity_variable, 0, sizeof(be_node_attr_t),    &be_node_op_ops);
	op_be_CopyKeep   = new_ir_op(beo_base + beo_CopyKeep,   "be_CopyKeep",   op_pin_state_pinned,     K, oparity_variable, 0, sizeof(be_node_attr_t),    &be_node_op_ops);
203
	op_be_Call       = new_ir_op(beo_base + beo_Call,       "be_Call",       op_pin_state_pinned,     F, oparity_variable, 0, sizeof(be_call_attr_t),    &be_node_op_ops);
Matthias Braun's avatar
Matthias Braun committed
204
205
206
207
208
209
210
211
212
213
	op_be_Return     = new_ir_op(beo_base + beo_Return,     "be_Return",     op_pin_state_pinned,     X, oparity_variable, 0, sizeof(be_return_attr_t),  &be_node_op_ops);
	op_be_AddSP      = new_ir_op(beo_base + beo_AddSP,      "be_AddSP",      op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_node_attr_t),    &be_node_op_ops);
	op_be_SetSP      = new_ir_op(beo_base + beo_SetSP,      "be_SetSP",      op_pin_state_pinned,     N, oparity_binary,   0, sizeof(be_stack_attr_t),   &be_node_op_ops);
	op_be_IncSP      = new_ir_op(beo_base + beo_IncSP,      "be_IncSP",      op_pin_state_pinned,     N, oparity_binary,   0, sizeof(be_stack_attr_t),   &be_node_op_ops);
	op_be_RegParams  = new_ir_op(beo_base + beo_RegParams,  "be_RegParams",  op_pin_state_pinned,     N, oparity_zero,     0, sizeof(be_node_attr_t),    &be_node_op_ops);
	op_be_StackParam = new_ir_op(beo_base + beo_StackParam, "be_StackParam", op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_frame_attr_t),   &be_node_op_ops);
	op_be_FrameAddr  = new_ir_op(beo_base + beo_FrameAddr,  "be_FrameAddr",  op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_frame_attr_t),   &be_node_op_ops);
	op_be_FrameLoad  = new_ir_op(beo_base + beo_FrameLoad,  "be_FrameLoad",  op_pin_state_pinned,     N, oparity_any,      0, sizeof(be_frame_attr_t),   &be_node_op_ops);
	op_be_FrameStore = new_ir_op(beo_base + beo_FrameStore, "be_FrameStore", op_pin_state_pinned,     N, oparity_any,      0, sizeof(be_frame_attr_t),   &be_node_op_ops);
	op_be_Barrier    = new_ir_op(beo_base + beo_Barrier,    "be_Barrier",    op_pin_state_pinned,     N, oparity_any,      0, sizeof(be_node_attr_t),    &be_node_op_ops);
214
215
216
217

	set_op_tag(op_be_Spill,      &be_node_tag);
	set_op_tag(op_be_Reload,     &be_node_tag);
	set_op_tag(op_be_Perm,       &be_node_tag);
Matthias Braun's avatar
Matthias Braun committed
218
	set_op_tag(op_be_MemPerm,    &be_node_tag);
219
220
	set_op_tag(op_be_Copy,       &be_node_tag);
	set_op_tag(op_be_Keep,       &be_node_tag);
Sebastian Hack's avatar
Sebastian Hack committed
221
	set_op_tag(op_be_CopyKeep,   &be_node_tag);
222
223
	set_op_tag(op_be_Call,       &be_node_tag);
	set_op_tag(op_be_Return,     &be_node_tag);
Sebastian Hack's avatar
Sebastian Hack committed
224
	set_op_tag(op_be_AddSP,      &be_node_tag);
225
226
227
228
229
230
231
	set_op_tag(op_be_SetSP,      &be_node_tag);
	set_op_tag(op_be_IncSP,      &be_node_tag);
	set_op_tag(op_be_RegParams,  &be_node_tag);
	set_op_tag(op_be_StackParam, &be_node_tag);
	set_op_tag(op_be_FrameLoad,  &be_node_tag);
	set_op_tag(op_be_FrameStore, &be_node_tag);
	set_op_tag(op_be_FrameAddr,  &be_node_tag);
232
	set_op_tag(op_be_Barrier,    &be_node_tag);
Michael Beck's avatar
Michael Beck committed
233
234

	op_be_FrameAddr->ops.node_cmp_attr = FrameAddr_cmp_attr;
Sebastian Hack's avatar
Sebastian Hack committed
235
}
236

237
238
239
/**
 * Initializes the generic attribute of all be nodes and return ir.
 */
Sebastian Hack's avatar
Sebastian Hack committed
240
static void *init_node_attr(ir_node* irn, int max_reg_data)
Sebastian Hack's avatar
Sebastian Hack committed
241
{
Sebastian Hack's avatar
Sebastian Hack committed
242
	ir_graph *irg     = get_irn_irg(irn);
Sebastian Hack's avatar
Sebastian Hack committed
243
244
	be_node_attr_t *a = get_irn_attr(irn);

245
	memset(a, 0, sizeof(get_op_attr_size(get_irn_op(irn))));
Sebastian Hack's avatar
Sebastian Hack committed
246
247
	a->max_reg_data = max_reg_data;
	a->reg_data     = NULL;
Sebastian Hack's avatar
Sebastian Hack committed
248

Sebastian Hack's avatar
Sebastian Hack committed
249
	if(max_reg_data > 0) {
Sebastian Hack's avatar
Sebastian Hack committed
250
251
		int i;

Sebastian Hack's avatar
Sebastian Hack committed
252
253
254
		a->reg_data = NEW_ARR_D(be_reg_data_t, get_irg_obstack(irg), max_reg_data);
		memset(a->reg_data, 0, max_reg_data * sizeof(a->reg_data[0]));
		for(i = 0; i < max_reg_data; ++i) {
Sebastian Hack's avatar
Sebastian Hack committed
255
256
			a->reg_data[i].req.req.cls  = NULL;
			a->reg_data[i].req.req.type = arch_register_req_type_none;
Sebastian Hack's avatar
Sebastian Hack committed
257
258
259
260
261
		}
	}

	return a;
}
262

263
int is_be_node(const ir_node *irn)
264
{
Sebastian Hack's avatar
Sebastian Hack committed
265
	return get_op_tag(get_irn_op(irn)) == &be_node_tag;
266
267
}

Sebastian Hack's avatar
Sebastian Hack committed
268
be_opcode_t be_get_irn_opcode(const ir_node *irn)
269
{
Sebastian Hack's avatar
Sebastian Hack committed
270
	return is_be_node(irn) ? get_irn_opcode(irn) - beo_base : beo_NoBeOp;
271
272
}

Sebastian Hack's avatar
Sebastian Hack committed
273
274
275
276
277
static int redir_proj(const ir_node **node, int pos)
{
	const ir_node *n = *node;

	if(is_Proj(n)) {
278
279
280
281
282
283
284
		ir_node *irn;

		*node = irn = get_Proj_pred(n);
		if(is_Proj(irn)) {
			assert(get_irn_mode(irn) == mode_T);
			*node = get_Proj_pred(irn);
		}
Sebastian Hack's avatar
Sebastian Hack committed
285
286
287
288
289
290
		return get_Proj_proj(n);
	}

	return 0;
}

Sebastian Hack's avatar
Sebastian Hack committed
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
static be_node_attr_t *retrieve_irn_attr(const ir_node *irn, int *the_pos)
{
	int dummy;
	be_node_attr_t *res = NULL;
	int *pos = the_pos ? the_pos : &dummy;

	*pos = -1;
	if(is_Proj(irn)) {
		ir_node *pred = get_Proj_pred(irn);
		int p         = get_Proj_proj(irn);

		if(is_be_node(pred)) {
			assert(get_irn_mode(pred) == mode_T);
			*pos = p;
			res = get_irn_attr(pred);
			assert(p >= 0 && p < res->max_reg_data && "illegal proj number");
		}
	}

	else if(is_be_node(irn) && get_irn_mode(irn) != mode_T) {
		be_node_attr_t *a = get_irn_attr(irn);
		if(a->max_reg_data > 0) {
			res  = a;
			*pos = 0;
		}
	}

	return res;
}

static be_reg_data_t *retrieve_reg_data(const ir_node *irn)
{
	int pos;
	be_node_attr_t *a = retrieve_irn_attr(irn, &pos);
	return a ? &a->reg_data[pos] : NULL;
}

Sebastian Hack's avatar
Sebastian Hack committed
328
329
330
static void
be_node_set_irn_reg(const void *_self, ir_node *irn, const arch_register_t *reg)
{
Sebastian Hack's avatar
Sebastian Hack committed
331
	be_reg_data_t *r = retrieve_reg_data(irn);
Sebastian Hack's avatar
Sebastian Hack committed
332

Sebastian Hack's avatar
Sebastian Hack committed
333
334
	if(r)
		r->reg = reg;
Sebastian Hack's avatar
Sebastian Hack committed
335
336
337
}


Matthias Braun's avatar
Matthias Braun committed
338
ir_node *be_new_Spill(const arch_register_class_t *cls, const arch_register_class_t *cls_frame, ir_graph *irg, ir_node *bl, ir_node *frame, ir_node *to_spill)
339
{
Matthias Braun's avatar
Matthias Braun committed
340
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
341
	ir_node *in[2];
Sebastian Hack's avatar
Sebastian Hack committed
342
	ir_node *res;
343

Sebastian Hack's avatar
Sebastian Hack committed
344
345
	in[0] = frame;
	in[1] = to_spill;
346
	res   = new_ir_node(NULL, irg, bl, op_be_Spill, mode_M, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
347
	a     = init_node_attr(res, 2);
Matthias Braun's avatar
Matthias Braun committed
348
349
	a->ent = NULL;
	a->offset = 0;
Sebastian Hack's avatar
Sebastian Hack committed
350
351
352

	be_node_set_reg_class(res, 0, cls_frame);
	be_node_set_reg_class(res, 1, cls);
Sebastian Hack's avatar
Sebastian Hack committed
353
354
	return res;
}
355

Sebastian Hack's avatar
Sebastian Hack committed
356
ir_node *be_new_Reload(const arch_register_class_t *cls, const arch_register_class_t *cls_frame, ir_graph *irg, ir_node *bl, ir_node *frame, ir_node *mem, ir_mode *mode)
357
{
Sebastian Hack's avatar
Sebastian Hack committed
358
	ir_node *in[2];
Sebastian Hack's avatar
Sebastian Hack committed
359
	ir_node *res;
360

Sebastian Hack's avatar
Sebastian Hack committed
361
362
	in[0] = frame;
	in[1] = mem;
363
	res   = new_ir_node(NULL, irg, bl, op_be_Reload, mode, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
364
365
366
	init_node_attr(res, 2);
	be_node_set_reg_class(res, 0, cls_frame);
	be_node_set_reg_class(res, -1, cls);
367
	be_node_set_flags(res, -1, arch_irn_flags_rematerializable);
Sebastian Hack's avatar
Sebastian Hack committed
368
369
	return res;
}
370

371
ir_node *be_get_Reload_mem(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
372
373
{
	assert(be_is_Reload(irn));
Daniel Grund's avatar
Daniel Grund committed
374
	return get_irn_n(irn, be_pos_Reload_mem);
Sebastian Hack's avatar
Sebastian Hack committed
375
376
}

377
378
379
380
381
382
ir_node *be_get_Reload_frame(const ir_node *irn)
{
	assert(be_is_Reload(irn));
	return get_irn_n(irn, be_pos_Reload_frame);
}

383
384
385
386
387
388
389
390
391
392
393
394
ir_node *be_get_Spill_val(const ir_node *irn)
{
	assert(be_is_Spill(irn));
	return get_irn_n(irn, be_pos_Spill_val);
}

ir_node *be_get_Spill_frame(const ir_node *irn)
{
	assert(be_is_Spill(irn));
	return get_irn_n(irn, be_pos_Spill_frame);
}

Sebastian Hack's avatar
Sebastian Hack committed
395
396
ir_node *be_new_Perm(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, int n, ir_node *in[])
{
Sebastian Hack's avatar
Sebastian Hack committed
397
	int i;
398
	ir_node *irn = new_ir_node(NULL, irg, bl, op_be_Perm, mode_T, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
399
400
401
402
403
404
	init_node_attr(irn, n);
	for(i = 0; i < n; ++i) {
		be_node_set_reg_class(irn, i, cls);
		be_node_set_reg_class(irn, OUT_POS(i), cls);
	}

Sebastian Hack's avatar
Sebastian Hack committed
405
406
	return irn;
}
407

Matthias Braun's avatar
Matthias Braun committed
408
409
410
411
412
ir_node *be_new_MemPerm(const arch_env_t *arch_env, ir_graph *irg, ir_node *bl, int n, ir_node *in[])
{
	int i;
	ir_node *frame = get_irg_frame(irg);
	const arch_register_class_t *cls_frame = arch_get_irn_reg_class(arch_env, frame, -1);
413
414
	ir_node *irn;
	const arch_register_t *sp = arch_env->isa->sp;
Matthias Braun's avatar
Matthias Braun committed
415
	be_memperm_attr_t *attr;
416
	ir_node **real_in;
Matthias Braun's avatar
Matthias Braun committed
417

418
419
420
421
422
423
424
425
	real_in = alloca((n+1) * sizeof(real_in[0]));
	real_in[0] = frame;
	memcpy(&real_in[1], in, n * sizeof(real_in[0]));

	irn =  new_ir_node(NULL, irg, bl, op_be_MemPerm, mode_T, n+1, real_in);

	init_node_attr(irn, n + 1);
	be_node_set_reg_class(irn, 0, sp->reg_class);
Matthias Braun's avatar
Matthias Braun committed
426
	for(i = 0; i < n; ++i) {
427
		be_node_set_reg_class(irn, i + 1, cls_frame);
Matthias Braun's avatar
Matthias Braun committed
428
429
430
431
432
		be_node_set_reg_class(irn, OUT_POS(i), cls_frame);
	}

	attr = get_irn_attr(irn);

433
434
	attr->in_entities = obstack_alloc(irg->obst, n * sizeof(attr->in_entities[0]));
	memset(attr->in_entities, 0, n * sizeof(attr->in_entities[0]));
Matthias Braun's avatar
Matthias Braun committed
435
436
437
438
439
440
441
	attr->out_entities = obstack_alloc(irg->obst, n*sizeof(attr->out_entities[0]));
	memset(attr->out_entities, 0, n*sizeof(attr->out_entities[0]));

	return irn;
}


Sebastian Hack's avatar
Sebastian Hack committed
442
443
444
445
ir_node *be_new_Copy(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, ir_node *op)
{
	ir_node *in[1];
	ir_node *res;
446

Sebastian Hack's avatar
Sebastian Hack committed
447
	in[0] = op;
448
	res   = new_ir_node(NULL, irg, bl, op_be_Copy, get_irn_mode(op), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
449
450
451
	init_node_attr(res, 1);
	be_node_set_reg_class(res, 0, cls);
	be_node_set_reg_class(res, OUT_POS(0), cls);
Sebastian Hack's avatar
Sebastian Hack committed
452
	return res;
453
454
}

455
456
457
458
ir_node *be_get_Copy_op(const ir_node *cpy) {
	return get_irn_n(cpy, be_pos_Copy_op);
}

459
460
461
462
void be_set_Copy_op(ir_node *cpy, ir_node *op) {
	set_irn_n(cpy, be_pos_Copy_op, op);
}

Sebastian Hack's avatar
Sebastian Hack committed
463
ir_node *be_new_Keep(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
464
{
Sebastian Hack's avatar
Sebastian Hack committed
465
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
466
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
467

468
	irn = new_ir_node(NULL, irg, bl, op_be_Keep, mode_ANY, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
469
470
471
472
	init_node_attr(irn, n);
	for(i = 0; i < n; ++i) {
		be_node_set_reg_class(irn, i, cls);
	}
Sebastian Hack's avatar
Sebastian Hack committed
473
474
	keep_alive(irn);
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
475
476
}

477
478
ir_node *be_new_Call(dbg_info *dbg, ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *sp, ir_node *ptr,
                     int n_outs, int n, ir_node *in[], ir_type *call_tp)
Sebastian Hack's avatar
Sebastian Hack committed
479
{
480
481
	be_call_attr_t *a;
	int real_n = be_pos_Call_first_arg + n;
Sebastian Hack's avatar
Sebastian Hack committed
482
483
	ir_node *irn;
	ir_node **real_in;
Sebastian Hack's avatar
Sebastian Hack committed
484

485
486
487
488
489
	NEW_ARR_A(ir_node *, real_in, real_n);
	real_in[be_pos_Call_mem] = mem;
	real_in[be_pos_Call_sp]  = sp;
	real_in[be_pos_Call_ptr] = ptr;
	memcpy(&real_in[be_pos_Call_first_arg], in, n * sizeof(in[0]));
Sebastian Hack's avatar
Sebastian Hack committed
490

491
	irn = new_ir_node(dbg, irg, bl, op_be_Call, mode_T, real_n, real_in);
492
493
494
	a = init_node_attr(irn, (n_outs > real_n ? n_outs : real_n));
	a->ent     = NULL;
	a->call_tp = call_tp;
Sebastian Hack's avatar
Sebastian Hack committed
495
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
496
497
}

498
499
/* Gets the call entity or NULL if this is no static call. */
entity *be_Call_get_entity(const ir_node *call) {
500
501
502
503
504
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	return a->ent;
}

505
506
/* Sets the call entity. */
void be_Call_set_entity(ir_node *call, entity *ent) {
507
508
509
510
511
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	a->ent = ent;
}

512
513
514
515
516
517
518
519
520
521
522
523
524
525
/* Gets the call type. */
ir_type *be_Call_get_type(ir_node *call) {
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	return a->call_tp;
}

/* Sets the call type. */
void be_Call_set_type(ir_node *call, ir_type *call_tp) {
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	a->call_tp = call_tp;
}

526
527
/* Construct a new be_Return. */
ir_node *be_new_Return(dbg_info *dbg, ir_graph *irg, ir_node *bl, int n_res, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
528
{
529
	be_return_attr_t *a;
530
	ir_node *irn = new_ir_node(dbg, irg, bl, op_be_Return, mode_X, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
531
	init_node_attr(irn, n);
532
533
	a = get_irn_attr(irn);
	a->num_ret_vals = n_res;
Sebastian Hack's avatar
Sebastian Hack committed
534
535
536
537

	return irn;
}

538
539
540
541
542
543
544
/* Returns the number of real returns values */
int be_Return_get_n_rets(ir_node *ret)
{
	be_return_attr_t *a = get_irn_attr(ret);
	return a->num_ret_vals;
}

Sebastian Hack's avatar
Sebastian Hack committed
545
ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, int offset)
Sebastian Hack's avatar
Sebastian Hack committed
546
{
Sebastian Hack's avatar
Sebastian Hack committed
547
548
	be_stack_attr_t *a;
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
549
	ir_node *in[1];
Sebastian Hack's avatar
Sebastian Hack committed
550
551

	in[0]     = old_sp;
Sebastian Hack's avatar
Sebastian Hack committed
552
	irn       = new_ir_node(NULL, irg, bl, op_be_IncSP, sp->reg_class->mode, sizeof(in) / sizeof(in[0]), in);
Sebastian Hack's avatar
Sebastian Hack committed
553
	a         = init_node_attr(irn, 1);
Sebastian Hack's avatar
Sebastian Hack committed
554
555
	a->offset = offset;

556
	be_node_set_flags(irn, -1, arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
557

Sebastian Hack's avatar
Sebastian Hack committed
558
	/* Set output constraint to stack register. */
Sebastian Hack's avatar
Sebastian Hack committed
559
	be_node_set_reg_class(irn, 0, sp->reg_class);
560
	be_set_constr_single_reg(irn, BE_OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
561
	be_node_set_irn_reg(NULL, irn, sp);
Sebastian Hack's avatar
Sebastian Hack committed
562
563

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
564
}
Sebastian Hack's avatar
Sebastian Hack committed
565

Sebastian Hack's avatar
Sebastian Hack committed
566
ir_node *be_new_AddSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *sz)
Sebastian Hack's avatar
Sebastian Hack committed
567
{
Sebastian Hack's avatar
Sebastian Hack committed
568
	be_node_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
569
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
570
	ir_node *in[be_pos_AddSP_last];
Sebastian Hack's avatar
Sebastian Hack committed
571

Sebastian Hack's avatar
Sebastian Hack committed
572
573
	in[be_pos_AddSP_old_sp] = old_sp;
	in[be_pos_AddSP_size]   = sz;
Sebastian Hack's avatar
Sebastian Hack committed
574

575
576
	irn = new_ir_node(NULL, irg, bl, op_be_AddSP, mode_T, be_pos_AddSP_last, in);
	a   = init_node_attr(irn, be_pos_AddSP_last);
Sebastian Hack's avatar
Sebastian Hack committed
577

Sebastian Hack's avatar
Sebastian Hack committed
578
	be_node_set_flags(irn, OUT_POS(pn_be_AddSP_res), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
579
580

	/* Set output constraint to stack register. */
581
582
	be_set_constr_single_reg(irn, be_pos_AddSP_old_sp, sp);
	be_node_set_reg_class(irn, be_pos_AddSP_size, arch_register_get_class(sp));
Sebastian Hack's avatar
Sebastian Hack committed
583
	be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_res), sp);
584
	a->reg_data[pn_be_AddSP_res].reg = sp;
Sebastian Hack's avatar
Sebastian Hack committed
585
586
587
588
589
590
591
592
593
594
595
596
597

	return irn;
}

ir_node *be_new_SetSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *op, ir_node *mem)
{
	be_node_attr_t *a;
	ir_node *irn;
	ir_node *in[3];

	in[0]    = mem;
	in[1]    = old_sp;
	in[2]    = op;
598
	irn      = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
599
600
	a        = init_node_attr(irn, 3);

601
	be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
602
603
604

	/* Set output constraint to stack register. */
	be_set_constr_single_reg(irn, OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
605
606
	be_node_set_reg_class(irn, be_pos_AddSP_size, sp->reg_class);
	be_node_set_reg_class(irn, be_pos_AddSP_old_sp, sp->reg_class);
Sebastian Hack's avatar
Sebastian Hack committed
607
608

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
609
}
Sebastian Hack's avatar
Sebastian Hack committed
610

Sebastian Hack's avatar
Sebastian Hack committed
611
ir_node *be_new_StackParam(const arch_register_class_t *cls, const arch_register_class_t *cls_frame, ir_graph *irg, ir_node *bl, ir_mode *mode, ir_node *frame_pointer, entity *ent)
Sebastian Hack's avatar
Sebastian Hack committed
612
{
613
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
614
615
616
	ir_node *irn;
	ir_node *in[1];

617
	in[0] = frame_pointer;
618
	irn = new_ir_node(NULL, irg, bl, op_be_StackParam, mode, 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
619
	a = init_node_attr(irn, 1);
620
	a->ent = ent;
Sebastian Hack's avatar
Sebastian Hack committed
621
622
623

	be_node_set_reg_class(irn, 0, cls_frame);
	be_node_set_reg_class(irn, OUT_POS(0), cls);
Sebastian Hack's avatar
Sebastian Hack committed
624
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
625
}
Sebastian Hack's avatar
Sebastian Hack committed
626

627
ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs)
Sebastian Hack's avatar
Sebastian Hack committed
628
629
630
631
{
	ir_node *irn;
	ir_node *in[1];

632
	irn = new_ir_node(NULL, irg, bl, op_be_RegParams, mode_T, 0, in);
Sebastian Hack's avatar
Sebastian Hack committed
633
	init_node_attr(irn, n_outs);
Sebastian Hack's avatar
Sebastian Hack committed
634
635
636
	return irn;
}

637
638
639
640
641
642
643
644
645
ir_node *be_new_FrameLoad(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
						  ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, entity *ent)
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[2];

	in[0]  = mem;
	in[1]  = frame;
646
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameLoad, mode_T, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
647
	a      = init_node_attr(irn, 3);
648
649
650
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 1, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
651
	be_node_set_reg_class(irn, OUT_POS(pn_Load_res), cls_data);
652
653
654
655
656
657
658
659
660
661
662
663
664
	return irn;
}

ir_node *be_new_FrameStore(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
						   ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_node *data, entity *ent)
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[3];

	in[0]  = mem;
	in[1]  = frame;
	in[2]  = data;
665
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameStore, mode_T, 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
666
	a      = init_node_attr(irn, 3);
667
668
669
670
671
672
673
674
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 1, cls_frame);
	be_node_set_reg_class(irn, 2, cls_data);
	return irn;
}

ir_node *be_new_FrameAddr(const arch_register_class_t *cls_frame, ir_graph *irg, ir_node *bl, ir_node *frame, entity *ent)
Sebastian Hack's avatar
Sebastian Hack committed
675
{
676
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
677
678
679
	ir_node *irn;
	ir_node *in[1];

680
	in[0]  = frame;
681
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameAddr, get_irn_mode(frame), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
682
	a      = init_node_attr(irn, 1);
683
684
685
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 0, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
686
	be_node_set_reg_class(irn, OUT_POS(0), cls_frame);
Michael Beck's avatar
Michael Beck committed
687
688

	return optimize_node(irn);
Sebastian Hack's avatar
Sebastian Hack committed
689
690
}

Sebastian Hack's avatar
Sebastian Hack committed
691
692
693
694
695
696
697
698
ir_node *be_new_CopyKeep(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, ir_node *src, int n, ir_node *in_keep[], ir_mode *mode)
{
	ir_node *irn;
	ir_node **in = (ir_node **) alloca((n + 1) * sizeof(in[0]));

	in[0] = src;
	memcpy(&in[1], in_keep, n * sizeof(in[0]));
	irn   = new_ir_node(NULL, irg, bl, op_be_CopyKeep, mode, n + 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
699
	init_node_attr(irn, n + 1);
Sebastian Hack's avatar
Sebastian Hack committed
700
701
702
703
704
705
706
707
708
709
710
711
712
713
	be_node_set_reg_class(irn, OUT_POS(0), cls);
	be_node_set_reg_class(irn, 0, cls);

	return irn;
}

ir_node *be_new_CopyKeep_single(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, ir_node *src, ir_node *keep, ir_mode *mode)
{
	ir_node *in[1];

	in[0] = keep;
	return be_new_CopyKeep(cls, irg, bl, src, 1, in, mode);
}

714
715
716
717
718
719
720
721
ir_node *be_get_CopyKeep_op(const ir_node *cpy) {
	return get_irn_n(cpy, be_pos_CopyKeep_op);
}

void be_set_CopyKeep_op(ir_node *cpy, ir_node *op) {
	set_irn_n(cpy, be_pos_CopyKeep_op, op);
}

722
ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
723
724
725
{
	ir_node *irn;

726
	irn = new_ir_node(NULL, irg, bl, op_be_Barrier, mode_T, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
727
728
729
730
	init_node_attr(irn, n);
	return irn;
}

Sebastian Hack's avatar
Sebastian Hack committed
731
732
733
int be_is_Spill         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Spill          ; }
int be_is_Reload        (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Reload         ; }
int be_is_Copy          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Copy           ; }
Sebastian Hack's avatar
Sebastian Hack committed
734
int be_is_CopyKeep      (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_CopyKeep       ; }
Sebastian Hack's avatar
Sebastian Hack committed
735
int be_is_Perm          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Perm           ; }
Matthias Braun's avatar
Matthias Braun committed
736
int be_is_MemPerm       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_MemPerm        ; }
Sebastian Hack's avatar
Sebastian Hack committed
737
738
739
740
int be_is_Keep          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Keep           ; }
int be_is_Call          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Call           ; }
int be_is_Return        (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Return         ; }
int be_is_IncSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_IncSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
741
int be_is_SetSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SetSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
742
int be_is_AddSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_AddSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
743
744
int be_is_RegParams     (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_RegParams      ; }
int be_is_StackParam    (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_StackParam     ; }
745
746
747
int be_is_FrameAddr     (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_FrameAddr      ; }
int be_is_FrameLoad     (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_FrameLoad      ; }
int be_is_FrameStore    (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_FrameStore     ; }
748
int be_is_Barrier       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Barrier        ; }
749
750
751
752
753
754

int be_has_frame_entity(const ir_node *irn)
{
	switch(be_get_irn_opcode(irn)) {
	case beo_StackParam:
	case beo_Spill:
755
	case beo_Reload:
756
757
758
759
	case beo_FrameStore:
	case beo_FrameLoad:
	case beo_FrameAddr:
		return 1;
760
761
	default:
		return 0;
762
763
764
	}
}

765
entity* be_get_frame_entity(const ir_node *irn)
766
767
768
769
770
771
772
{
	if(be_has_frame_entity(irn)) {
		be_frame_attr_t *a = get_irn_attr(irn);
		return a->ent;
	}
	return NULL;
}
Sebastian Hack's avatar
Sebastian Hack committed
773

Matthias Braun's avatar
Matthias Braun committed
774
775
776
777
778
void be_set_MemPerm_in_entity(const ir_node *irn, int n, entity *ent)
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
779
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
780
781
782
783
784
785
786
787
788

	attr->in_entities[n] = ent;
}

entity* be_get_MemPerm_in_entity(const ir_node* irn, int n)
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
789
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
790
791
792
793
794
795
796
797
798

	return attr->in_entities[n];
}

void be_set_MemPerm_out_entity(const ir_node *irn, int n, entity *ent)
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
799
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
800
801
802
803
804
805
806
807
808

	attr->out_entities[n] = ent;
}

entity* be_get_MemPerm_out_entity(const ir_node* irn, int n)
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
809
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
810
811
812
813

	return attr->out_entities[n];
}

814
815
816
817
818
int be_get_MemPerm_entity_arity(const ir_node *irn)
{
	return get_irn_arity(irn) - 1;
}

Sebastian Hack's avatar
Sebastian Hack committed
819
static void be_limited(void *data, bitset_t *bs)
Sebastian Hack's avatar
Sebastian Hack committed
820
{
Sebastian Hack's avatar
Sebastian Hack committed
821
822
	be_req_t *req = data;

Sebastian Hack's avatar
Sebastian Hack committed
823
824
825
826
827
828
829
830
831
832
833
834
	switch(req->kind) {
	case be_req_kind_negate_old_limited:
	case be_req_kind_old_limited:
		req->x.old_limited.old_limited(req->x.old_limited.old_limited_env, bs);
		if(req->kind == be_req_kind_negate_old_limited)
			bitset_flip_all(bs);
		break;
	case be_req_kind_single_reg:
		bitset_clear_all(bs);
		bitset_set(bs, req->x.single_reg->index);
		break;
	}
Sebastian Hack's avatar
Sebastian Hack committed
835
836
}

Sebastian Hack's avatar
Sebastian Hack committed
837
static INLINE be_req_t *get_req(ir_node *irn, int pos)
Sebastian Hack's avatar
Sebastian Hack committed
838
{
Michael Beck's avatar
Michael Beck committed
839
	int idx           = pos < 0 ? -(pos + 1) : pos;
Sebastian Hack's avatar
Sebastian Hack committed
840
841
842
843
844
845
	be_node_attr_t *a = get_irn_attr(irn);
	be_reg_data_t *rd = &a->reg_data[idx];
	be_req_t       *r = pos < 0 ? &rd->req : &rd->in_req;

	assert(is_be_node(irn));
	assert(!(pos >= 0) || pos < get_irn_arity(irn));
Sebastian Hack's avatar
Sebastian Hack committed
846
	assert(!(pos < 0)  || -(pos + 1) <= a->max_reg_data);
Sebastian Hack's avatar
Sebastian Hack committed
847

Sebastian Hack's avatar
Sebastian Hack committed
848
849
850
851
852
853
854
	return r;
}

void be_set_constr_single_reg(ir_node *irn, int pos, const arch_register_t *reg)
{
	be_req_t *r = get_req(irn, pos);

Sebastian Hack's avatar
Sebastian Hack committed
855
856
857
858
859
860
861
862
	r->kind            = be_req_kind_single_reg;
	r->x.single_reg    = reg;
	r->req.limited     = be_limited;
	r->req.limited_env = r;
	r->req.type        = arch_register_req_type_limited;
	r->req.cls         = reg->reg_class;
}

863
864
void be_set_constr_limited(ir_node *irn, int pos, const arch_register_req_t *req)
{
Sebastian Hack's avatar
Sebastian Hack committed
865
	be_req_t *r = get_req(irn, pos);
866
867
868
869
870
871
872
873
874
875
876
877
878

	assert(arch_register_req_is(req, limited));

	r->kind            = be_req_kind_old_limited;
	r->req.limited     = be_limited;
	r->req.limited_env = r;
	r->req.type        = arch_register_req_type_limited;
	r->req.cls         = req->cls;

	r->x.old_limited.old_limited     = req->limited;
	r->x.old_limited.old_limited_env = req->limited_env;
}

Sebastian Hack's avatar
Sebastian Hack committed
879
880
881
882
883
884
885
886
887
888
void be_node_set_flags(ir_node *irn, int pos, arch_irn_flags_t flags)
{
	be_req_t *r = get_req(irn, pos);
	r->flags = flags;
}

void be_node_set_reg_class(ir_node *irn, int pos, const arch_register_class_t *cls)
{
	be_req_t *r = get_req(irn, pos);
	r->req.cls = cls;
Sebastian Hack's avatar
Sebastian Hack committed
889
890
	if(r->req.type == arch_register_req_type_none)
		r->req.type = arch_register_req_type_normal;
Sebastian Hack's avatar
Sebastian Hack committed
891
892
}

893
894
895
896
897
898
void be_node_set_req_type(ir_node *irn, int pos, arch_register_req_type_t type)
{
	be_req_t *r = get_req(irn, pos);
	r->req.type = type;
}

Michael Beck's avatar
BugFix:    
Michael Beck committed
899
900
901
902
903
ir_node *be_get_IncSP_pred(ir_node *irn) {
	assert(be_is_IncSP(irn));
	return get_irn_n(irn, 0);
}

904
void be_set_IncSP_pred(ir_node *incsp, ir_node *pred) {
905
906
907
908
	assert(be_is_IncSP(incsp));
	set_irn_n(incsp, 0, pred);
}

Michael Beck's avatar
Michael Beck committed
909
910
911
912
913
ir_node *be_get_IncSP_mem(ir_node *irn) {
	assert(be_is_IncSP(irn));
	return get_irn_n(irn, 1);
}

914
void be_set_IncSP_offset(ir_node *irn, int offset)
Sebastian Hack's avatar
Sebastian Hack committed
915
916
917
918
919
{
	be_stack_attr_t *a = get_irn_attr(irn);
	assert(be_is_IncSP(irn));
	a->offset = offset;
}
920

921
int be_get_IncSP_offset(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
922
{
Sebastian Hack's avatar
Sebastian Hack committed
923
924
925
926
	be_stack_attr_t *a = get_irn_attr(irn);
	assert(be_is_IncSP(irn));
	return a->offset;
}
Sebastian Hack's avatar
Sebastian Hack committed
927

Matthias Braun's avatar
Matthias Braun committed
928
ir_node *be_spill(const arch_env_t *arch_env, ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
929
{
930
931
932
	ir_node *bl     = get_nodes_block(irn);
	ir_graph *irg   = get_irn_irg(bl);
	ir_node *frame  = get_irg_frame(irg);
Sebastian Hack's avatar
Sebastian Hack committed
933
	ir_node *spill;
Sebastian Hack's avatar
Sebastian Hack committed
934

Sebastian Hack's avatar
Sebastian Hack committed
935
936
937
	const arch_register_class_t *cls       = arch_get_irn_reg_class(arch_env, irn, -1);
	const arch_register_class_t *cls_frame = arch_get_irn_reg_class(arch_env, frame, -1);

Matthias Braun's avatar
Matthias Braun committed
938
	spill = be_new_Spill(cls, cls_frame, irg, bl, frame, irn);
Christian Würdig's avatar
Christian Würdig committed
939
	return spill;
Sebastian Hack's avatar
Sebastian Hack committed
940
941
}

942
ir_node *be_reload(const arch_env_t *arch_env, const arch_register_class_t *cls, ir_node *insert, ir_mode *mode, ir_node *spill)
Sebastian Hack's avatar
Sebastian Hack committed
943
944
945
{
	ir_node *reload;

946
947
	ir_node *bl    = is_Block(insert) ? insert : get_nodes_block(insert);
	ir_graph *irg  = get_irn_irg(bl);
Sebastian Hack's avatar
Sebastian Hack committed
948
949
	ir_node *frame = get_irg_frame(irg);
	const arch_register_class_t *cls_frame = arch_get_irn_reg_class(arch_env, frame, -1);
Sebastian Hack's avatar
Sebastian Hack committed
950

Sebastian Hack's avatar
Sebastian Hack committed
951
	assert(be_is_Spill(spill) || (is_Phi(spill) && get_irn_mode(spill) == mode_M));
Sebastian Hack's avatar
Sebastian Hack committed
952

953
	reload = be_new_Reload(cls, cls_frame, irg, bl, frame, spill, mode);
Sebastian Hack's avatar
Sebastian Hack committed
954

955
956
957
958
	if(is_Block(insert)) {
		insert = sched_skip(insert, 0, sched_skip_cf_predicator, (void *) arch_env);
		sched_add_after(insert, reload);
	}
959

960
961
	else
		sched_add_before(insert, reload);
962

Christian Würdig's avatar
Christian Würdig committed
963
	return reload;
Sebastian Hack's avatar
Sebastian Hack committed
964
}
Sebastian Hack's avatar
Sebastian Hack committed
965

Sebastian Hack's avatar
Sebastian Hack committed
966
967
968
969
970
971
972
973
974
975
976
/*
  ____              ____
 |  _ \ ___  __ _  |  _ \ ___  __ _ ___
 | |_) / _ \/ _` | | |_) / _ \/ _` / __|
 |  _ <  __/ (_| | |  _ <  __/ (_| \__ \
 |_| \_\___|\__, | |_| \_\___|\__, |___/
            |___/                |_|

*/


Sebastian Hack's avatar
Sebastian Hack committed
977
static void *put_out_reg_req(arch_register_req_t *req, const ir_node *irn, int out_pos)
Sebastian Hack's avatar
Sebastian Hack committed
978
{
Sebastian Hack's avatar
Sebastian Hack committed
979
	const be_node_attr_t *a = get_irn_attr(irn);
Daniel Grund's avatar
Daniel Grund committed
980

Sebastian Hack's avatar
Sebastian Hack committed
981
	if(out_pos < a->max_reg_data) {
Sebastian Hack's avatar
Sebastian Hack committed
982
		memcpy(req, &a->reg_data[out_pos].req, sizeof(req[0]));
Sebastian Hack's avatar
Sebastian Hack committed
983
984
985

		if(be_is_Copy(irn)) {
			req->type |= arch_register_req_type_should_be_same;
986
			req->other_same = be_get_Copy_op(irn);
Sebastian Hack's avatar
Sebastian Hack committed
987
988
		}
	}
Sebastian Hack's avatar
Sebastian Hack committed
989
990
991
	else {
		req->type = arch_register_req_type_none;
		req->cls  = NULL;
Sebastian Hack's avatar
Sebastian Hack committed
992
	}
Sebastian Hack's avatar
Sebastian Hack committed
993

Sebastian Hack's avatar
Sebastian Hack committed
994
	return req;
Sebastian Hack's avatar
Sebastian Hack committed
995
996
}

Sebastian Hack's avatar
Sebastian Hack committed
997
static void *put_in_reg_req(arch_register_req_t *req, const ir_node *irn, int pos)
998
{
Sebastian Hack's avatar
Sebastian Hack committed
999
1000
	const be_node_attr_t *a = get_irn_attr(irn);