benode.c 44.5 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
 */
Michael Beck's avatar
Michael Beck committed
13
#ifdef HAVE_CONFIG_H
14
#include <config.h>
Michael Beck's avatar
Michael Beck committed
15
#endif
Sebastian Hack's avatar
Sebastian Hack committed
16
17
18
19
20
21

#include <stdlib.h>

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

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

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

41
42
#include "beirgmod.h"

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

Sebastian Hack's avatar
Sebastian Hack committed
45
46
/* 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
47

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

Sebastian Hack's avatar
Sebastian Hack committed
50
51
52
53
54
55
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
56
57
typedef struct {
	arch_register_req_t req;
Sebastian Hack's avatar
Sebastian Hack committed
58
	be_req_kind_t       kind;
Sebastian Hack's avatar
Sebastian Hack committed
59
	arch_irn_flags_t    flags;
Sebastian Hack's avatar
Sebastian Hack committed
60
61
62
63
64
65
66
67
	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
68
69
} be_req_t;

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

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

81
82
83
84
85
86
/** 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;

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

93
/** The be_Frame attribute type. */
94
95
typedef struct {
	be_node_attr_t node_attr;
96
	ir_entity *ent;
97
98
99
	int offset;
} be_frame_attr_t;

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

107
typedef struct {
Matthias Braun's avatar
Matthias Braun committed
108
	be_node_attr_t node_attr;
109
110
	ir_entity **in_entities;
	ir_entity **out_entities;
Matthias Braun's avatar
Matthias Braun committed
111
} be_memperm_attr_t;
112

113
114
115
ir_op *op_be_Spill;
ir_op *op_be_Reload;
ir_op *op_be_Perm;
Matthias Braun's avatar
Matthias Braun committed
116
ir_op *op_be_MemPerm;
117
118
ir_op *op_be_Copy;
ir_op *op_be_Keep;
Sebastian Hack's avatar
Sebastian Hack committed
119
ir_op *op_be_CopyKeep;
120
121
122
ir_op *op_be_Call;
ir_op *op_be_Return;
ir_op *op_be_IncSP;
Sebastian Hack's avatar
Sebastian Hack committed
123
ir_op *op_be_AddSP;
Michael Beck's avatar
Michael Beck committed
124
ir_op *op_be_SubSP;
125
126
127
128
129
130
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;
131
ir_op *op_be_Barrier;
Sebastian Hack's avatar
Sebastian Hack committed
132

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

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

137
138
139
140
141
142
143
144
145
146
#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
147
148
#define M   irop_flag_machine

149

Michael Beck's avatar
Michael Beck committed
150
151
152
153
154
155
/**
 * 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) {
156
157
158
159
	int i, len;

	if(ARR_LEN(a->reg_data) != ARR_LEN(b->reg_data))
		return 1;
Michael Beck's avatar
Michael Beck committed
160

161
162
163
164
	len = ARR_LEN(a->reg_data);
	for (i = 0; i < len; ++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)) ||
Michael Beck's avatar
Michael Beck committed
165
			    memcmp(&a->reg_data[i].req,    &b->reg_data[i].req,    sizeof(a->reg_data[i].req)))
166
			return 1;
Michael Beck's avatar
Michael Beck committed
167
	}
168
169

	return 0;
Michael Beck's avatar
Michael Beck committed
170
171
172
173
174
175
176
177
178
179
180
}

/**
 * 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);

181
182
183
	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
184
185
}

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

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

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

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

Matthias Braun's avatar
Matthias Braun committed
197
198
199
200
201
	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);
202
	op_be_Keep       = new_ir_op(beo_base + beo_Keep,       "be_Keep",       op_pin_state_pinned,     K, oparity_dynamic,  0, sizeof(be_node_attr_t),    &be_node_op_ops);
Matthias Braun's avatar
Matthias Braun committed
203
	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);
204
	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
205
206
	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);
Michael Beck's avatar
Michael Beck committed
207
	op_be_SubSP      = new_ir_op(beo_base + beo_SubSP,      "be_SubSP",      op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_node_attr_t),    &be_node_op_ops);
Matthias Braun's avatar
Matthias Braun committed
208
	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);
209
	op_be_IncSP      = new_ir_op(beo_base + beo_IncSP,      "be_IncSP",      op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_stack_attr_t),   &be_node_op_ops);
Matthias Braun's avatar
Matthias Braun committed
210
211
212
213
214
	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);
215
	op_be_Barrier    = new_ir_op(beo_base + beo_Barrier,    "be_Barrier",    op_pin_state_pinned,     N, oparity_dynamic,  0, sizeof(be_node_attr_t),    &be_node_op_ops);
216
217
218
219

	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
220
	set_op_tag(op_be_MemPerm,    &be_node_tag);
221
222
	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
223
	set_op_tag(op_be_CopyKeep,   &be_node_tag);
224
225
	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
226
	set_op_tag(op_be_AddSP,      &be_node_tag);
Michael Beck's avatar
Michael Beck committed
227
	set_op_tag(op_be_SubSP,      &be_node_tag);
228
229
230
231
232
233
234
	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);
235
	set_op_tag(op_be_Barrier,    &be_node_tag);
Michael Beck's avatar
Michael Beck committed
236
237

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

240
241
242
/**
 * Initializes the generic attribute of all be nodes and return ir.
 */
243
static void *init_node_attr(ir_node *node, int max_reg_data)
Sebastian Hack's avatar
Sebastian Hack committed
244
{
245
	ir_graph *irg = get_irn_irg(node);
246
	struct obstack *obst = get_irg_obstack(irg);
247
	be_node_attr_t *a = get_irn_attr(node);
Sebastian Hack's avatar
Sebastian Hack committed
248

249
	memset(a, 0, sizeof(get_op_attr_size(get_irn_op(node))));
Sebastian Hack's avatar
Sebastian Hack committed
250

251
252
	if(max_reg_data >= 0) {
		a->reg_data = NEW_ARR_D(be_reg_data_t, obst, max_reg_data);
Sebastian Hack's avatar
Sebastian Hack committed
253
		memset(a->reg_data, 0, max_reg_data * sizeof(a->reg_data[0]));
254
255
	} else {
		a->reg_data = NEW_ARR_F(be_reg_data_t, 0);
Sebastian Hack's avatar
Sebastian Hack committed
256
257
258
259
	}

	return a;
}
260

261
262
263
264
265
266
267
268
static void add_register_req(ir_node *node)
{
	be_node_attr_t *a = get_irn_attr(node);
	be_reg_data_t regreq;
	memset(&regreq, 0, sizeof(regreq));
	ARR_APP1(be_reg_data_t, a->reg_data, regreq);
}

269
int is_be_node(const ir_node *irn)
270
{
Sebastian Hack's avatar
Sebastian Hack committed
271
	return get_op_tag(get_irn_op(irn)) == &be_node_tag;
272
273
}

Sebastian Hack's avatar
Sebastian Hack committed
274
be_opcode_t be_get_irn_opcode(const ir_node *irn)
275
{
Sebastian Hack's avatar
Sebastian Hack committed
276
	return is_be_node(irn) ? get_irn_opcode(irn) - beo_base : beo_NoBeOp;
277
278
}

Michael Beck's avatar
Michael Beck committed
279
280
281
282
283
284
285
286
287
288
/**
 * Skip Proj nodes and return their Proj numbers.
 *
 * If *node is a Proj or Proj(Proj) node, skip it.
 *
 * @param node  points to the node to be skipped
 *
 * @return 0 if *node was no Proj node, its Proj number else.
 */
static int redir_proj(const ir_node **node)
Sebastian Hack's avatar
Sebastian Hack committed
289
290
291
292
{
	const ir_node *n = *node;

	if(is_Proj(n)) {
293
294
295
296
297
298
299
		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
300
301
302
303
304
305
		return get_Proj_proj(n);
	}

	return 0;
}

Sebastian Hack's avatar
Sebastian Hack committed
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
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);
321
			assert(p >= 0 && p < ARR_LEN(res->reg_data) && "illegal proj number");
Sebastian Hack's avatar
Sebastian Hack committed
322
		}
323
	} else if(is_be_node(irn) && get_irn_mode(irn) != mode_T) {
Sebastian Hack's avatar
Sebastian Hack committed
324
		be_node_attr_t *a = get_irn_attr(irn);
325
		if(ARR_LEN(a->reg_data) > 0) {
Sebastian Hack's avatar
Sebastian Hack committed
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
			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
341
342
343
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
344
	be_reg_data_t *r = retrieve_reg_data(irn);
Sebastian Hack's avatar
Sebastian Hack committed
345

Sebastian Hack's avatar
Sebastian Hack committed
346
347
	if(r)
		r->reg = reg;
Sebastian Hack's avatar
Sebastian Hack committed
348
349
350
}


351
352
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)
353
{
Matthias Braun's avatar
Matthias Braun committed
354
	be_frame_attr_t *a;
355
	ir_node         *in[2];
356
	ir_node         *res;
357

358
359
360
	in[0]     = frame;
	in[1]     = to_spill;
	res       = new_ir_node(NULL, irg, bl, op_be_Spill, mode_M, 2, in);
361
362
	a         = init_node_attr(res, 2);
	a->ent    = NULL;
Matthias Braun's avatar
Matthias Braun committed
363
	a->offset = 0;
Sebastian Hack's avatar
Sebastian Hack committed
364

365
	be_node_set_reg_class(res, be_pos_Spill_frame, cls_frame);
366
	be_node_set_reg_class(res, be_pos_Spill_val, cls);
Sebastian Hack's avatar
Sebastian Hack committed
367
368
	return res;
}
369

370
371
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)
372
{
373
374
375
376
377
378
379
	ir_node *in[2];
	ir_node *res;

	in[0] = frame;
	in[1] = mem;
	res   = new_ir_node(NULL, irg, bl, op_be_Reload, mode, 2, in);

Sebastian Hack's avatar
Sebastian Hack committed
380
381
	init_node_attr(res, 2);
	be_node_set_reg_class(res, -1, cls);
382
	be_node_set_reg_class(res, be_pos_Reload_frame, cls_frame);
383
	be_node_set_flags(res, -1, arch_irn_flags_rematerializable);
Sebastian Hack's avatar
Sebastian Hack committed
384
385
	return res;
}
386

387
ir_node *be_get_Reload_mem(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
388
389
{
	assert(be_is_Reload(irn));
Daniel Grund's avatar
Daniel Grund committed
390
	return get_irn_n(irn, be_pos_Reload_mem);
Sebastian Hack's avatar
Sebastian Hack committed
391
392
}

393
394
395
396
397
398
ir_node *be_get_Reload_frame(const ir_node *irn)
{
	assert(be_is_Reload(irn));
	return get_irn_n(irn, be_pos_Reload_frame);
}

399
400
401
402
403
ir_node *be_get_Spill_val(const ir_node *irn)
{
	assert(be_is_Spill(irn));
	return get_irn_n(irn, be_pos_Spill_val);
}
404
405
406
407
408
ir_node *be_get_Spill_frame(const ir_node *irn)
{
	assert(be_is_Spill(irn));
	return get_irn_n(irn, be_pos_Spill_frame);
}
409

Sebastian Hack's avatar
Sebastian Hack committed
410
411
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
412
	int i;
413
	ir_node *irn = new_ir_node(NULL, irg, bl, op_be_Perm, mode_T, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
414
415
416
417
418
419
	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
420
421
	return irn;
}
422

Matthias Braun's avatar
Matthias Braun committed
423
424
425
426
427
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);
428
429
	ir_node *irn;
	const arch_register_t *sp = arch_env->isa->sp;
Matthias Braun's avatar
Matthias Braun committed
430
	be_memperm_attr_t *attr;
431
	ir_node **real_in;
Matthias Braun's avatar
Matthias Braun committed
432

433
434
435
436
437
438
439
440
	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
441
	for(i = 0; i < n; ++i) {
442
		be_node_set_reg_class(irn, i + 1, cls_frame);
Matthias Braun's avatar
Matthias Braun committed
443
444
445
446
447
		be_node_set_reg_class(irn, OUT_POS(i), cls_frame);
	}

	attr = get_irn_attr(irn);

448
449
	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
450
451
452
453
454
455
456
	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
457
458
459
460
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;
461

Sebastian Hack's avatar
Sebastian Hack committed
462
	in[0] = op;
463
	res   = new_ir_node(NULL, irg, bl, op_be_Copy, get_irn_mode(op), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
464
465
466
	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
467
	return res;
468
469
}

470
471
472
473
ir_node *be_get_Copy_op(const ir_node *cpy) {
	return get_irn_n(cpy, be_pos_Copy_op);
}

474
475
476
477
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
478
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
479
{
Sebastian Hack's avatar
Sebastian Hack committed
480
	int i;
481
482
483
484
	ir_node *res;

	res = new_ir_node(NULL, irg, bl, op_be_Keep, mode_ANY, -1, NULL);
	init_node_attr(res, -1);
Sebastian Hack's avatar
Sebastian Hack committed
485

Sebastian Hack's avatar
Sebastian Hack committed
486
	for(i = 0; i < n; ++i) {
487
488
489
		add_irn_n(res, in[i]);
		add_register_req(res);
		be_node_set_reg_class(res, i, cls);
Sebastian Hack's avatar
Sebastian Hack committed
490
	}
491
492
493
494
495
496
497
498
499
500
501
502
503
	keep_alive(res);

	return res;
}

void be_Keep_add_node(ir_node *keep, const arch_register_class_t *cls, ir_node *node)
{
	int n;

	assert(be_is_Keep(keep));
	n = add_irn_n(keep, node);
	add_register_req(keep);
	be_node_set_reg_class(keep, n, cls);
Sebastian Hack's avatar
Sebastian Hack committed
504
505
}

506
507
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
508
{
509
510
	be_call_attr_t *a;
	int real_n = be_pos_Call_first_arg + n;
Sebastian Hack's avatar
Sebastian Hack committed
511
512
	ir_node *irn;
	ir_node **real_in;
Sebastian Hack's avatar
Sebastian Hack committed
513

514
515
516
517
518
	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
519

520
	irn = new_ir_node(dbg, irg, bl, op_be_Call, mode_T, real_n, real_in);
521
522
523
	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
524
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
525
526
}

527
/* Gets the call entity or NULL if this is no static call. */
528
ir_entity *be_Call_get_entity(const ir_node *call) {
529
530
531
532
533
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	return a->ent;
}

534
/* Sets the call entity. */
535
void be_Call_set_entity(ir_node *call, ir_entity *ent) {
536
537
538
539
540
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	a->ent = ent;
}

541
542
543
544
545
546
547
548
549
550
551
552
553
554
/* 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;
}

555
556
/* 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
557
{
558
	be_return_attr_t *a;
559
	ir_node *irn = new_ir_node(dbg, irg, bl, op_be_Return, mode_X, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
560
	init_node_attr(irn, n);
561
562
	a = get_irn_attr(irn);
	a->num_ret_vals = n_res;
Sebastian Hack's avatar
Sebastian Hack committed
563
564
565
566

	return irn;
}

567
568
569
570
571
572
573
/* 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
574
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
575
{
Sebastian Hack's avatar
Sebastian Hack committed
576
577
	be_stack_attr_t *a;
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
578
	ir_node *in[1];
Sebastian Hack's avatar
Sebastian Hack committed
579
580

	in[0]     = old_sp;
Sebastian Hack's avatar
Sebastian Hack committed
581
	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
582
	a         = init_node_attr(irn, 1);
Sebastian Hack's avatar
Sebastian Hack committed
583
584
	a->offset = offset;

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

Sebastian Hack's avatar
Sebastian Hack committed
587
	/* Set output constraint to stack register. */
Sebastian Hack's avatar
Sebastian Hack committed
588
	be_node_set_reg_class(irn, 0, sp->reg_class);
589
	be_set_constr_single_reg(irn, BE_OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
590
	be_node_set_irn_reg(NULL, irn, sp);
Sebastian Hack's avatar
Sebastian Hack committed
591
592

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
593
}
Sebastian Hack's avatar
Sebastian Hack committed
594

Sebastian Hack's avatar
Sebastian Hack committed
595
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
596
{
Sebastian Hack's avatar
Sebastian Hack committed
597
	be_node_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
598
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
599
	ir_node *in[be_pos_AddSP_last];
Sebastian Hack's avatar
Sebastian Hack committed
600

Sebastian Hack's avatar
Sebastian Hack committed
601
602
	in[be_pos_AddSP_old_sp] = old_sp;
	in[be_pos_AddSP_size]   = sz;
Sebastian Hack's avatar
Sebastian Hack committed
603

604
605
	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
606

Sebastian Hack's avatar
Sebastian Hack committed
607
	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
608
609

	/* Set output constraint to stack register. */
610
611
	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
612
	be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_res), sp);
613
	a->reg_data[pn_be_AddSP_res].reg = sp;
Sebastian Hack's avatar
Sebastian Hack committed
614
615
616
617

	return irn;
}

Michael Beck's avatar
Michael Beck committed
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
ir_node *be_new_SubSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *sz)
{
	be_node_attr_t *a;
	ir_node *irn;
	ir_node *in[be_pos_SubSP_last];

	in[be_pos_SubSP_old_sp] = old_sp;
	in[be_pos_SubSP_size]   = sz;

	irn = new_ir_node(NULL, irg, bl, op_be_SubSP, mode_T, be_pos_SubSP_last, in);
	a   = init_node_attr(irn, be_pos_SubSP_last);

	be_node_set_flags(irn, OUT_POS(pn_be_SubSP_res), arch_irn_flags_ignore | arch_irn_flags_modify_sp);

	/* Set output constraint to stack register. */
	be_set_constr_single_reg(irn, be_pos_SubSP_old_sp, sp);
	be_node_set_reg_class(irn, be_pos_SubSP_size, arch_register_get_class(sp));
	be_set_constr_single_reg(irn, OUT_POS(pn_be_SubSP_res), sp);
	a->reg_data[pn_be_SubSP_res].reg = sp;

	return irn;
}

Sebastian Hack's avatar
Sebastian Hack committed
641
642
643
644
645
646
647
648
649
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;
650
	irn      = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
651
652
	a        = init_node_attr(irn, 3);

653
	be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
654
655
656

	/* Set output constraint to stack register. */
	be_set_constr_single_reg(irn, OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
657
658
	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
659
660

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
661
}
Sebastian Hack's avatar
Sebastian Hack committed
662

663
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, ir_entity *ent)
Sebastian Hack's avatar
Sebastian Hack committed
664
{
665
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
666
667
668
	ir_node *irn;
	ir_node *in[1];

669
	in[0] = frame_pointer;
670
	irn = new_ir_node(NULL, irg, bl, op_be_StackParam, mode, 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
671
	a = init_node_attr(irn, 1);
672
	a->ent = ent;
Sebastian Hack's avatar
Sebastian Hack committed
673
674
675

	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
676
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
677
}
Sebastian Hack's avatar
Sebastian Hack committed
678

679
ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs)
Sebastian Hack's avatar
Sebastian Hack committed
680
{
681
682
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
683

684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
	res = new_ir_node(NULL, irg, bl, op_be_RegParams, mode_T, 0, NULL);
	init_node_attr(res, -1);
	for(i = 0; i < n_outs; ++i)
		add_register_req(res);

	return res;
}

ir_node *be_RegParams_append_out_reg(ir_node *regparams,
                                     const arch_env_t *arch_env,
                                     const arch_register_t *reg)
{
	ir_graph *irg = get_irn_irg(regparams);
	ir_node *block = get_nodes_block(regparams);
	be_node_attr_t *attr = get_irn_attr(regparams);
	const arch_register_class_t *cls = arch_register_get_class(reg);
	ir_mode *mode = arch_register_class_mode(cls);
	int n = ARR_LEN(attr->reg_data);

	assert(be_is_RegParams(regparams));
	ir_node *proj = new_r_Proj(irg, block, regparams, mode, n);
	add_register_req(regparams);
	be_set_constr_single_reg(regparams, n, reg);
	arch_set_irn_register(arch_env, proj, reg);

	/* TODO decide, whether we need to set ignore/modifysp flags here? */

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
712
713
}

714
ir_node *be_new_FrameLoad(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
715
						  ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_entity *ent)
716
717
718
719
720
721
722
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[2];

	in[0]  = mem;
	in[1]  = frame;
723
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameLoad, mode_T, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
724
	a      = init_node_attr(irn, 3);
725
726
727
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 1, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
728
	be_node_set_reg_class(irn, OUT_POS(pn_Load_res), cls_data);
729
730
731
732
	return irn;
}

ir_node *be_new_FrameStore(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
733
						   ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_node *data, ir_entity *ent)
734
735
736
737
738
739
740
741
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[3];

	in[0]  = mem;
	in[1]  = frame;
	in[2]  = data;
742
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameStore, mode_T, 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
743
	a      = init_node_attr(irn, 3);
744
745
746
747
748
749
750
	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;
}

751
ir_node *be_new_FrameAddr(const arch_register_class_t *cls_frame, ir_graph *irg, ir_node *bl, ir_node *frame, ir_entity *ent)
Sebastian Hack's avatar
Sebastian Hack committed
752
{
753
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
754
755
756
	ir_node *irn;
	ir_node *in[1];

757
	in[0]  = frame;
758
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameAddr, get_irn_mode(frame), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
759
	a      = init_node_attr(irn, 1);
760
761
762
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 0, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
763
	be_node_set_reg_class(irn, OUT_POS(0), cls_frame);
Michael Beck's avatar
Michael Beck committed
764
765

	return optimize_node(irn);
Sebastian Hack's avatar
Sebastian Hack committed
766
767
}

Sebastian Hack's avatar
Sebastian Hack committed
768
769
770
771
772
773
774
775
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
776
	init_node_attr(irn, n + 1);
Sebastian Hack's avatar
Sebastian Hack committed
777
778
779
780
781
782
783
784
785
786
787
788
789
790
	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);
}

791
792
793
794
795
796
797
798
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);
}

799
ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
800
{
801
802
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
803

804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
	res = new_ir_node(NULL, irg, bl, op_be_Barrier, mode_T, -1, NULL);
	init_node_attr(res, -1);
	for(i = 0; i < n; ++i) {
		add_irn_n(res, in[i]);
		add_register_req(res);
	}

	return res;
}

ir_node *be_Barrier_append_node(ir_node *barrier, ir_node *node)
{
	ir_graph *irg = get_irn_irg(barrier);
	ir_node *block = get_nodes_block(barrier);
	ir_mode *mode = get_irn_mode(node);
	int n = add_irn_n(barrier, node);
	ir_node *proj = new_r_Proj(irg, block, barrier, mode, n);
	add_register_req(barrier);

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
824
825
}

Sebastian Hack's avatar
Sebastian Hack committed
826
827
828
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
829
int be_is_CopyKeep      (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_CopyKeep       ; }
Sebastian Hack's avatar
Sebastian Hack committed
830
int be_is_Perm          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Perm           ; }
Matthias Braun's avatar
Matthias Braun committed
831
int be_is_MemPerm       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_MemPerm        ; }
Sebastian Hack's avatar
Sebastian Hack committed
832
833
834
835
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
836
int be_is_SetSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SetSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
837
int be_is_AddSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_AddSP          ; }
838
int be_is_SubSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SubSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
839
840
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     ; }
841
842
843
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     ; }
844
int be_is_Barrier       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Barrier        ; }
845
846
847
848
849
850

int be_has_frame_entity(const ir_node *irn)
{
	switch(be_get_irn_opcode(irn)) {
	case beo_StackParam:
	case beo_Spill:
851
	case beo_Reload:
852
853
854
855
	case beo_FrameStore:
	case beo_FrameLoad:
	case beo_FrameAddr:
		return 1;
856
857
	default:
		return 0;
858
859
860
	}
}

861
ir_entity *be_get_frame_entity(const ir_node *irn)
862
{
863
	if (be_has_frame_entity(irn)) {
864
865
866
867
868
		be_frame_attr_t *a = get_irn_attr(irn);
		return a->ent;
	}
	return NULL;
}
Sebastian Hack's avatar
Sebastian Hack committed
869

870
871
872
873
874
875
876
877
878
879
int be_get_frame_offset(const ir_node *irn)
{
	assert(is_be_node(irn));
	if (be_has_frame_entity(irn)) {
		be_frame_attr_t *a = get_irn_attr(irn);
		return a->offset;
	}
	return 0;
}

880
void be_set_MemPerm_in_entity(const ir_node *irn, int n, ir_entity *ent)
Matthias Braun's avatar
Matthias Braun committed
881
882
883
884
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
885
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
886
887
888
889

	attr->in_entities[n] = ent;
}

890
ir_entity* be_get_MemPerm_in_entity(const ir_node* irn, int n)
Matthias Braun's avatar
Matthias Braun committed
891
892
893
894
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
895
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
896
897
898
899

	return attr->in_entities[n];
}

900
void be_set_MemPerm_out_entity(const ir_node *irn, int n, ir_entity *ent)
Matthias Braun's avatar
Matthias Braun committed
901
902
903
904
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
905
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
906
907
908
909

	attr->out_entities[n] = ent;
}

910
ir_entity* be_get_MemPerm_out_entity(const ir_node* irn, int n)
Matthias Braun's avatar
Matthias Braun committed
911
912
913
914
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
915
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
916
917
918
919

	return attr->out_entities[n];
}

920
921
922
923
924
int be_get_MemPerm_entity_arity(const ir_node *irn)
{
	return get_irn_arity(irn) - 1;
}

Sebastian Hack's avatar
Sebastian Hack committed
925
static void be_limited(void *data, bitset_t *bs)
Sebastian Hack's avatar
Sebastian Hack committed
926
{
Sebastian Hack's avatar
Sebastian Hack committed
927
928
	be_req_t *req = data;

Sebastian Hack's avatar
Sebastian Hack committed
929
930
931
932
933
934
935
936
937
938
939
940
	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
941
942
}

Sebastian Hack's avatar
Sebastian Hack committed
943
static INLINE be_req_t *get_req(ir_node *irn, int pos)
Sebastian Hack's avatar
Sebastian Hack committed
944
{
Michael Beck's avatar
Michael Beck committed
945
	int idx           = pos < 0 ? -(pos + 1) : pos;
Sebastian Hack's avatar
Sebastian Hack committed
946
947
948
949
950
951
	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));
952
	assert(!(pos < 0)  || -(pos + 1) <= ARR_LEN(a->reg_data));
Sebastian Hack's avatar
Sebastian Hack committed
953

Sebastian Hack's avatar
Sebastian Hack committed
954
955
956
957
958
959
960
	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
961
962
963
964
965
966
967
968
	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;
}

969
970
void be_set_constr_limited(ir_node *irn, int pos, const arch_register_req_t *req)
{
Sebastian Hack's avatar
Sebastian Hack committed
971
	be_req_t *r = get_req(irn, pos);
972
973
974
975
976
977
978
979
980
981
982
983
984

	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
985
986
987
988
989
990
991
992
993
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);
994

Sebastian Hack's avatar
Sebastian Hack committed
995
	r->req.cls = cls;
996

997
	if (cls == NULL) {
998
		r->req.type = arch_register_req_type_none;
999
	} else if (r->req.type == arch_register_req_type_none) {
Sebastian Hack's avatar
Sebastian Hack committed
1000
		r->req.type = arch_register_req_type_normal;
For faster browsing, not all history is shown. View entire blame