benode.c 39.2 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
 *
Sebastian Hack's avatar
Sebastian Hack committed
10
11
12
 * Copyright (C) 2005 Universitaet Karlsruhe
 * 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
92
typedef struct {
	be_node_attr_t node_attr;
	int offset;           /**< The offset by which the stack shall be increased/decreased. */
93
	be_stack_dir_t dir;   /**< The direction in which the stack shall be modified (expand or shrink). */
Sebastian Hack's avatar
Sebastian Hack committed
94
95
} be_stack_attr_t;

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

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

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

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

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

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

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

151

Michael Beck's avatar
Michael Beck committed
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
180
/**
 * 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);

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
202
203
204
205
206
207
208
209
210
211
212
213
214
	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);
	op_be_Call       = new_ir_op(beo_base + beo_Call,       "be_Call",       op_pin_state_pinned,     N, oparity_variable, 0, sizeof(be_call_attr_t),    &be_node_op_ops);
	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);
215
216
217
218

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

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

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

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

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

Sebastian Hack's avatar
Sebastian Hack committed
253
254
255
		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
256
257
			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
258
259
260
261
262
		}
	}

	return a;
}
263

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

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

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

	if(is_Proj(n)) {
279
280
		ir_node *irn;

Sebastian Hack's avatar
Sebastian Hack committed
281
		assert(pos == -1 && "Illegal pos for a Proj");
282
283
284
285
286
		*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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
		return get_Proj_proj(n);
	}

	return 0;
}

static void
be_node_set_irn_reg(const void *_self, ir_node *irn, const arch_register_t *reg)
{
	int out_pos;
	be_node_attr_t *a;

	out_pos = redir_proj((const ir_node **) &irn, -1);
	a       = get_irn_attr(irn);

	assert(is_be_node(irn));
Sebastian Hack's avatar
Sebastian Hack committed
303
	assert(out_pos < a->max_reg_data && "position too high");
Sebastian Hack's avatar
Sebastian Hack committed
304
305
306
307
	a->reg_data[out_pos].reg = reg;
}


Matthias Braun's avatar
Matthias Braun committed
308
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)
309
{
Matthias Braun's avatar
Matthias Braun committed
310
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
311
	ir_node *in[2];
Sebastian Hack's avatar
Sebastian Hack committed
312
	ir_node *res;
313

Sebastian Hack's avatar
Sebastian Hack committed
314
315
	in[0] = frame;
	in[1] = to_spill;
316
	res   = new_ir_node(NULL, irg, bl, op_be_Spill, mode_M, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
317
	a     = init_node_attr(res, 2);
Matthias Braun's avatar
Matthias Braun committed
318
319
	a->ent = NULL;
	a->offset = 0;
Sebastian Hack's avatar
Sebastian Hack committed
320
321
322

	be_node_set_reg_class(res, 0, cls_frame);
	be_node_set_reg_class(res, 1, cls);
Sebastian Hack's avatar
Sebastian Hack committed
323
324
	return res;
}
325

Sebastian Hack's avatar
Sebastian Hack committed
326
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)
327
{
Sebastian Hack's avatar
Sebastian Hack committed
328
	ir_node *in[2];
Sebastian Hack's avatar
Sebastian Hack committed
329
	ir_node *res;
330

Sebastian Hack's avatar
Sebastian Hack committed
331
332
	in[0] = frame;
	in[1] = mem;
333
	res   = new_ir_node(NULL, irg, bl, op_be_Reload, mode, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
334
335
336
	init_node_attr(res, 2);
	be_node_set_reg_class(res, 0, cls_frame);
	be_node_set_reg_class(res, -1, cls);
Sebastian Hack's avatar
Sebastian Hack committed
337
338
	return res;
}
339

340
ir_node *be_get_Reload_mem(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
341
342
{
	assert(be_is_Reload(irn));
Daniel Grund's avatar
Daniel Grund committed
343
	return get_irn_n(irn, be_pos_Reload_mem);
Sebastian Hack's avatar
Sebastian Hack committed
344
345
}

346
347
348
349
350
351
ir_node *be_get_Reload_frame(const ir_node *irn)
{
	assert(be_is_Reload(irn));
	return get_irn_n(irn, be_pos_Reload_frame);
}

Sebastian Hack's avatar
Sebastian Hack committed
352
353
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
354
	int i;
355
	ir_node *irn = new_ir_node(NULL, irg, bl, op_be_Perm, mode_T, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
356
357
358
359
360
361
	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
362
363
	return irn;
}
364

Matthias Braun's avatar
Matthias Braun committed
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
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);
	ir_node *irn = new_ir_node(NULL, irg, bl, op_be_MemPerm, mode_T, n, in);
	be_memperm_attr_t *attr;

	init_node_attr(irn, n);
	for(i = 0; i < n; ++i) {
		be_node_set_reg_class(irn, i, cls_frame);
		be_node_set_reg_class(irn, OUT_POS(i), cls_frame);
	}

	attr = get_irn_attr(irn);

	attr->in_entities = obstack_alloc(irg->obst, n*sizeof(attr->in_entities[0]));
	memset(attr->in_entities, 0, n*sizeof(attr->in_entities[0]));
	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
390
391
392
393
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;
394

Sebastian Hack's avatar
Sebastian Hack committed
395
	in[0] = op;
396
	res   = new_ir_node(NULL, irg, bl, op_be_Copy, get_irn_mode(op), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
397
398
399
	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
400
	return res;
401
402
}

403
404
405
406
ir_node *be_get_Copy_op(const ir_node *cpy) {
	return get_irn_n(cpy, be_pos_Copy_op);
}

407
408
409
410
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
411
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
412
{
Sebastian Hack's avatar
Sebastian Hack committed
413
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
414
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
415

416
	irn = new_ir_node(NULL, irg, bl, op_be_Keep, mode_ANY, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
417
418
419
420
	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
421
422
	keep_alive(irn);
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
423
424
}

425
426
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
427
{
428
429
	be_call_attr_t *a;
	int real_n = be_pos_Call_first_arg + n;
Sebastian Hack's avatar
Sebastian Hack committed
430
431
	ir_node *irn;
	ir_node **real_in;
Sebastian Hack's avatar
Sebastian Hack committed
432

433
434
435
436
437
	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
438

439
	irn = new_ir_node(dbg, irg, bl, op_be_Call, mode_T, real_n, real_in);
440
441
442
	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
443
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
444
445
}

446
447
/* Gets the call entity or NULL if this is no static call. */
entity *be_Call_get_entity(const ir_node *call) {
448
449
450
451
452
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	return a->ent;
}

453
454
/* Sets the call entity. */
void be_Call_set_entity(ir_node *call, entity *ent) {
455
456
457
458
459
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	a->ent = ent;
}

460
461
462
463
464
465
466
467
468
469
470
471
472
473
/* 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;
}

474
475
/* 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
476
{
477
	be_return_attr_t *a;
478
	ir_node *irn = new_ir_node(dbg, irg, bl, op_be_Return, mode_X, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
479
	init_node_attr(irn, n);
480
481
	a = get_irn_attr(irn);
	a->num_ret_vals = n_res;
Sebastian Hack's avatar
Sebastian Hack committed
482
483
484
485

	return irn;
}

486
487
488
489
490
491
492
/* 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;
}

493
ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *mem, unsigned offset, be_stack_dir_t dir)
Sebastian Hack's avatar
Sebastian Hack committed
494
{
Sebastian Hack's avatar
Sebastian Hack committed
495
496
	be_stack_attr_t *a;
	ir_node *irn;
497
	ir_node *in[2];
Sebastian Hack's avatar
Sebastian Hack committed
498
499

	in[0]     = old_sp;
500
	in[1]     = mem;
501
	irn       = new_ir_node(NULL, irg, bl, op_be_IncSP, sp->reg_class->mode, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
502
	a         = init_node_attr(irn, 1);
Sebastian Hack's avatar
Sebastian Hack committed
503
504
505
	a->dir    = dir;
	a->offset = offset;

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

Sebastian Hack's avatar
Sebastian Hack committed
508
	/* Set output constraint to stack register. */
Sebastian Hack's avatar
Sebastian Hack committed
509
	be_node_set_reg_class(irn, 0, sp->reg_class);
510
	be_set_constr_single_reg(irn, BE_OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
511
	be_node_set_irn_reg(NULL, irn, sp);
Sebastian Hack's avatar
Sebastian Hack committed
512
513

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
514
}
Sebastian Hack's avatar
Sebastian Hack committed
515

Sebastian Hack's avatar
Sebastian Hack committed
516
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
517
{
Sebastian Hack's avatar
Sebastian Hack committed
518
	be_node_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
519
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
520
	ir_node *in[be_pos_AddSP_last];
Sebastian Hack's avatar
Sebastian Hack committed
521

Sebastian Hack's avatar
Sebastian Hack committed
522
523
	in[be_pos_AddSP_old_sp] = old_sp;
	in[be_pos_AddSP_size]   = sz;
Sebastian Hack's avatar
Sebastian Hack committed
524

525
526
	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
527

528
	be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
529
530

	/* Set output constraint to stack register. */
531
532
	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
533
	be_set_constr_single_reg(irn, OUT_POS(0), sp);
534
	a->reg_data[pn_be_AddSP_res].reg = sp;
Sebastian Hack's avatar
Sebastian Hack committed
535
536
537
538
539
540
541
542
543
544
545
546
547

	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;
548
	irn      = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
549
550
	a        = init_node_attr(irn, 3);

551
	be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
552
553
554
555
556

	/* Set output constraint to stack register. */
	be_set_constr_single_reg(irn, OUT_POS(0), sp);
	be_node_set_reg_class(irn, 1, sp->reg_class);
	be_node_set_reg_class(irn, 2, sp->reg_class);
Sebastian Hack's avatar
Sebastian Hack committed
557
	be_node_set_irn_reg(NULL, irn, sp);
Sebastian Hack's avatar
Sebastian Hack committed
558
559

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
560
}
Sebastian Hack's avatar
Sebastian Hack committed
561

Sebastian Hack's avatar
Sebastian Hack committed
562
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
563
{
564
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
565
566
567
	ir_node *irn;
	ir_node *in[1];

568
	in[0] = frame_pointer;
569
	irn = new_ir_node(NULL, irg, bl, op_be_StackParam, mode, 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
570
	a = init_node_attr(irn, 1);
571
	a->ent = ent;
Sebastian Hack's avatar
Sebastian Hack committed
572
573
574

	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
575
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
576
}
Sebastian Hack's avatar
Sebastian Hack committed
577

578
ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs)
Sebastian Hack's avatar
Sebastian Hack committed
579
580
581
582
{
	ir_node *irn;
	ir_node *in[1];

583
	irn = new_ir_node(NULL, irg, bl, op_be_RegParams, mode_T, 0, in);
Sebastian Hack's avatar
Sebastian Hack committed
584
	init_node_attr(irn, n_outs);
Sebastian Hack's avatar
Sebastian Hack committed
585
586
587
	return irn;
}

588
589
590
591
592
593
594
595
596
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;
597
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameLoad, mode_T, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
598
	a      = init_node_attr(irn, 3);
599
600
601
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 1, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
602
	be_node_set_reg_class(irn, OUT_POS(pn_Load_res), cls_data);
603
604
605
606
607
608
609
610
611
612
613
614
615
	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;
616
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameStore, mode_T, 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
617
	a      = init_node_attr(irn, 3);
618
619
620
621
622
623
624
625
	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
626
{
627
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
628
629
630
	ir_node *irn;
	ir_node *in[1];

631
	in[0]  = frame;
632
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameAddr, get_irn_mode(frame), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
633
	a      = init_node_attr(irn, 1);
634
635
636
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 0, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
637
	be_node_set_reg_class(irn, OUT_POS(0), cls_frame);
Michael Beck's avatar
Michael Beck committed
638
639

	return optimize_node(irn);
Sebastian Hack's avatar
Sebastian Hack committed
640
641
}

Sebastian Hack's avatar
Sebastian Hack committed
642
643
644
645
646
647
648
649
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
650
	init_node_attr(irn, n + 1);
Sebastian Hack's avatar
Sebastian Hack committed
651
652
653
654
655
656
657
658
659
660
661
662
663
664
	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);
}

665
666
667
668
669
670
671
672
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);
}

673
ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
674
675
676
{
	ir_node *irn;

677
	irn = new_ir_node(NULL, irg, bl, op_be_Barrier, mode_T, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
678
679
680
681
	init_node_attr(irn, n);
	return irn;
}

Sebastian Hack's avatar
Sebastian Hack committed
682
683
684
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
685
int be_is_CopyKeep      (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_CopyKeep       ; }
Sebastian Hack's avatar
Sebastian Hack committed
686
int be_is_Perm          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Perm           ; }
Matthias Braun's avatar
Matthias Braun committed
687
int be_is_MemPerm       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_MemPerm        ; }
Sebastian Hack's avatar
Sebastian Hack committed
688
689
690
691
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
692
int be_is_SetSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SetSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
693
int be_is_AddSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_AddSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
694
695
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     ; }
696
697
698
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     ; }
699
int be_is_Barrier       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Barrier        ; }
700
701
702
703
704
705

int be_has_frame_entity(const ir_node *irn)
{
	switch(be_get_irn_opcode(irn)) {
	case beo_StackParam:
	case beo_Spill:
706
	case beo_Reload:
707
708
709
710
	case beo_FrameStore:
	case beo_FrameLoad:
	case beo_FrameAddr:
		return 1;
711
712
	default:
		return 0;
713
714
715
	}
}

716
entity *be_get_frame_entity(const ir_node *irn)
717
718
719
720
721
722
723
{
	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
724

Matthias Braun's avatar
Matthias Braun committed
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
void be_set_frame_entity(const ir_node *irn, entity* ent)
{
	be_frame_attr_t *a;

	assert(be_has_frame_entity(irn));

	a = get_irn_attr(irn);
	a->ent = ent;
}

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));
	assert(n < get_irn_arity(irn));

	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));
	assert(n < get_irn_arity(irn));

	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));
	assert(n < get_irn_arity(irn));

	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));
	assert(n < get_irn_arity(irn));

	return attr->out_entities[n];
}

Sebastian Hack's avatar
Sebastian Hack committed
775
static void be_limited(void *data, bitset_t *bs)
Sebastian Hack's avatar
Sebastian Hack committed
776
{
Sebastian Hack's avatar
Sebastian Hack committed
777
778
	be_req_t *req = data;

Sebastian Hack's avatar
Sebastian Hack committed
779
780
781
782
783
784
785
786
787
788
789
790
	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
791
792
}

Sebastian Hack's avatar
Sebastian Hack committed
793
static INLINE be_req_t *get_req(ir_node *irn, int pos)
Sebastian Hack's avatar
Sebastian Hack committed
794
{
Michael Beck's avatar
Michael Beck committed
795
	int idx           = pos < 0 ? -(pos + 1) : pos;
Sebastian Hack's avatar
Sebastian Hack committed
796
797
798
799
800
801
	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
802
	assert(!(pos < 0)  || -(pos + 1) <= a->max_reg_data);
Sebastian Hack's avatar
Sebastian Hack committed
803

Sebastian Hack's avatar
Sebastian Hack committed
804
805
806
807
808
809
810
	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
811
812
813
814
815
816
817
818
	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;
}

819
820
void be_set_constr_limited(ir_node *irn, int pos, const arch_register_req_t *req)
{
Sebastian Hack's avatar
Sebastian Hack committed
821
	be_req_t *r = get_req(irn, pos);
822
823
824
825
826
827
828
829
830
831
832
833
834

	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
835
836
837
838
839
840
841
842
843
844
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
845
846
	if(r->req.type == arch_register_req_type_none)
		r->req.type = arch_register_req_type_normal;
Sebastian Hack's avatar
Sebastian Hack committed
847
848
}

849
850
851
852
853
854
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
855
856
857
858
859
ir_node *be_get_IncSP_pred(ir_node *irn) {
	assert(be_is_IncSP(irn));
	return get_irn_n(irn, 0);
}

860
void be_set_IncSP_pred(ir_node *incsp, ir_node *pred) {
861
862
863
864
	assert(be_is_IncSP(incsp));
	set_irn_n(incsp, 0, pred);
}

Michael Beck's avatar
Michael Beck committed
865
866
867
868
869
ir_node *be_get_IncSP_mem(ir_node *irn) {
	assert(be_is_IncSP(irn));
	return get_irn_n(irn, 1);
}

Sebastian Hack's avatar
Sebastian Hack committed
870
871
872
873
874
875
void be_set_IncSP_offset(ir_node *irn, unsigned offset)
{
	be_stack_attr_t *a = get_irn_attr(irn);
	assert(be_is_IncSP(irn));
	a->offset = offset;
}
876

877
unsigned be_get_IncSP_offset(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
878
{
Sebastian Hack's avatar
Sebastian Hack committed
879
880
881
882
	be_stack_attr_t *a = get_irn_attr(irn);
	assert(be_is_IncSP(irn));
	return a->offset;
}
Sebastian Hack's avatar
Sebastian Hack committed
883

Sebastian Hack's avatar
Sebastian Hack committed
884
885
886
887
888
void be_set_IncSP_direction(ir_node *irn, be_stack_dir_t dir)
{
	be_stack_attr_t *a = get_irn_attr(irn);
	assert(be_is_IncSP(irn));
	a->dir = dir;
Sebastian Hack's avatar
Sebastian Hack committed
889
890
}

891
be_stack_dir_t be_get_IncSP_direction(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
892
{
Sebastian Hack's avatar
Sebastian Hack committed
893
894
895
	be_stack_attr_t *a = get_irn_attr(irn);
	assert(be_is_IncSP(irn));
	return a->dir;
Sebastian Hack's avatar
Sebastian Hack committed
896
897
}

Matthias Braun's avatar
Matthias Braun committed
898
ir_node *be_spill(const arch_env_t *arch_env, ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
899
{
900
901
902
	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
903
	ir_node *spill;
Sebastian Hack's avatar
Sebastian Hack committed
904

Sebastian Hack's avatar
Sebastian Hack committed
905
906
907
	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
908
	spill = be_new_Spill(cls, cls_frame, irg, bl, frame, irn);
Christian Würdig's avatar
Christian Würdig committed
909
	return spill;
Sebastian Hack's avatar
Sebastian Hack committed
910
911
}

912
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
913
914
915
{
	ir_node *reload;

916
	ir_node *bl    = is_Block(insert) ? insert : get_nodes_block(insert);
Sebastian Hack's avatar
Sebastian Hack committed
917
918
919
	ir_graph *irg  = get_irn_irg(bl);
	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
920

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

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

925
926
927
928
929
930
931
932
	if(is_Block(insert)) {
		insert = sched_skip(insert, 0, sched_skip_cf_predicator, (void *) arch_env);
		sched_add_after(insert, reload);
	}

	else
		sched_add_before(insert, reload);

Christian Würdig's avatar
Christian Würdig committed
933
	return reload;
Sebastian Hack's avatar
Sebastian Hack committed
934
}
Sebastian Hack's avatar
Sebastian Hack committed
935

Sebastian Hack's avatar
Sebastian Hack committed
936
937
938
939
940
941
942
943
944
945
946
/*
  ____              ____
 |  _ \ ___  __ _  |  _ \ ___  __ _ ___
 | |_) / _ \/ _` | | |_) / _ \/ _` / __|
 |  _ <  __/ (_| | |  _ <  __/ (_| \__ \
 |_| \_\___|\__, | |_| \_\___|\__, |___/
            |___/                |_|

*/


Sebastian Hack's avatar
Sebastian Hack committed
947
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
948
{
Sebastian Hack's avatar
Sebastian Hack committed
949
	const be_node_attr_t *a = get_irn_attr(irn);
Daniel Grund's avatar
Daniel Grund committed
950

Sebastian Hack's avatar
Sebastian Hack committed
951
	if(out_pos < a->max_reg_data) {
Sebastian Hack's avatar
Sebastian Hack committed
952
		memcpy(req, &a->reg_data[out_pos].req, sizeof(req[0]));
Sebastian Hack's avatar
Sebastian Hack committed
953
954
955

		if(be_is_Copy(irn)) {
			req->type |= arch_register_req_type_should_be_same;
956
			req->other_same = be_get_Copy_op(irn);
Sebastian Hack's avatar
Sebastian Hack committed
957
958
		}
	}
Sebastian Hack's avatar
Sebastian Hack committed
959
960
961
	else {
		req->type = arch_register_req_type_none;
		req->cls  = NULL;
Sebastian Hack's avatar
Sebastian Hack committed
962
	}
Sebastian Hack's avatar
Sebastian Hack committed
963

Sebastian Hack's avatar
Sebastian Hack committed
964
	return req;
Sebastian Hack's avatar
Sebastian Hack committed
965
966
}

Sebastian Hack's avatar
Sebastian Hack committed
967
static void *put_in_reg_req(arch_register_req_t *req, const ir_node *irn, int pos)
968
{
Sebastian Hack's avatar
Sebastian Hack committed
969
970
	const be_node_attr_t *a = get_irn_attr(irn);

Sebastian Hack's avatar
Sebastian Hack committed
971
	if(pos < get_irn_arity(irn) && pos < a->max_reg_data)
Sebastian Hack's avatar
Sebastian Hack committed
972
973
974
975
		memcpy(req, &a->reg_data[pos].in_req, sizeof(req[0]));
	else {
		req->type = arch_register_req_type_none;
		req->cls  = NULL;
Sebastian Hack's avatar
Sebastian Hack committed
976
977
978
	}

	return req;
979
980
}

Sebastian Hack's avatar
Sebastian Hack committed
981
static const arch_register_req_t *
982
be_node_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos)
Sebastian Hack's avatar
Sebastian Hack committed
983
{
Sebastian Hack's avatar
Sebastian Hack committed
984
	int out_pos = pos;
Sebastian Hack's avatar
Sebastian Hack committed
985

Sebastian Hack's avatar
Sebastian Hack committed
986
987
988
	if(pos < 0) {
		if(get_irn_mode(irn) == mode_T)
			return NULL;
Daniel Grund's avatar
Daniel Grund committed
989

Sebastian Hack's avatar
Sebastian Hack committed
990
991
992
993
		out_pos = redir_proj((const ir_node **) &irn, pos);
		assert(is_be_node(irn));
		return put_out_reg_req(req, irn, out_pos);
	}
Daniel Grund's avatar
Daniel Grund committed
994

Sebastian Hack's avatar
Sebastian Hack committed
995
996
997
	else {
		return is_be_node(irn) ? put_in_reg_req(req, irn, pos) : NULL;
	}
Daniel Grund's avatar
Daniel Grund committed
998

Sebastian Hack's avatar
Sebastian Hack committed
999
	return req;
Sebastian Hack's avatar
Sebastian Hack committed
1000
}
For faster browsing, not all history is shown. View entire blame