irnode.c 75.3 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

Matthias Braun's avatar
Matthias Braun committed
20
21
22
23
24
/**
 * @file
 * @brief   Representation of an intermediate operation.
 * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Michael Beck
 * @version $Id$
Götz Lindenmaier's avatar
Götz Lindenmaier committed
25
 */
Boris Boesler's avatar
added    
Boris Boesler committed
26
#ifdef HAVE_CONFIG_H
Michael Beck's avatar
Michael Beck committed
27
28
29
30
31
# include "config.h"
#endif

#ifdef HAVE_STRING_H
# include <string.h>
Boris Boesler's avatar
added    
Boris Boesler committed
32
33
#endif

34
#include "ident.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
35
#include "irnode_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
36
#include "irgraph_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
37
#include "irmode_t.h"
38
#include "irbackedge_t.h"
39
#include "irdump.h"
40
#include "irop_t.h"
41
#include "irprog_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
42
#include "iredgekinds.h"
Sebastian Hack's avatar
Sebastian Hack committed
43
#include "iredges_t.h"
Matthias Braun's avatar
Matthias Braun committed
44
#include "ircons.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
45

46
#include "irhooks.h"
47
#include "irtools.h"
Michael Beck's avatar
Michael Beck committed
48

Götz Lindenmaier's avatar
Götz Lindenmaier committed
49
50
/* some constants fixing the positions of nodes predecessors
   in the in array */
Michael Beck's avatar
Michael Beck committed
51
52
53
54
55
#define CALL_PARAM_OFFSET     2
#define FUNCCALL_PARAM_OFFSET 1
#define SEL_INDEX_OFFSET      2
#define RETURN_RESULT_OFFSET  1  /* mem is not a result */
#define END_KEEPALIVE_OFFSET  0
Götz Lindenmaier's avatar
Götz Lindenmaier committed
56

57
static const char *pnc_name_arr [] = {
58
59
60
61
	"pn_Cmp_False", "pn_Cmp_Eq", "pn_Cmp_Lt", "pn_Cmp_Le",
	"pn_Cmp_Gt", "pn_Cmp_Ge", "pn_Cmp_Lg", "pn_Cmp_Leg",
	"pn_Cmp_Uo", "pn_Cmp_Ue", "pn_Cmp_Ul", "pn_Cmp_Ule",
	"pn_Cmp_Ug", "pn_Cmp_Uge", "pn_Cmp_Ne", "pn_Cmp_True"
62
};
Christian Schäfer's avatar
Christian Schäfer committed
63

Michael Beck's avatar
Michael Beck committed
64
65
66
/**
 * returns the pnc name from an pnc constant
 */
67
const char *get_pnc_string(int pnc) {
68
69
	assert(pnc >= 0 && pnc <
			(int) (sizeof(pnc_name_arr)/sizeof(pnc_name_arr[0])));
70
	return pnc_name_arr[pnc];
Christian Schäfer's avatar
Christian Schäfer committed
71
72
}

Michael Beck's avatar
Michael Beck committed
73
/*
74
 * Calculates the negated (Complement(R)) pnc condition.
Michael Beck's avatar
Michael Beck committed
75
 */
76
pn_Cmp get_negated_pnc(long pnc, ir_mode *mode) {
77
	pnc ^= pn_Cmp_True;
78

79
80
81
	/* do NOT add the Uo bit for non-floating point values */
	if (! mode_is_float(mode))
		pnc &= ~pn_Cmp_Uo;
82

83
	return (pn_Cmp) pnc;
Christian Schäfer's avatar
Christian Schäfer committed
84
85
}

86
/* Calculates the inversed (R^-1) pnc condition, i.e., "<" --> ">" */
87
88
89
90
pn_Cmp get_inversed_pnc(long pnc) {
	long code    = pnc & ~(pn_Cmp_Lt|pn_Cmp_Gt);
	long lesser  = pnc & pn_Cmp_Lt;
	long greater = pnc & pn_Cmp_Gt;
Michael Beck's avatar
Michael Beck committed
91

92
	code |= (lesser ? pn_Cmp_Gt : 0) | (greater ? pn_Cmp_Lt : 0);
Michael Beck's avatar
Michael Beck committed
93

94
	return (pn_Cmp) code;
Michael Beck's avatar
Michael Beck committed
95
96
}

97
98
99
100
101
102
103
104
105
106
/**
 * Indicates, whether additional data can be registered to ir nodes.
 * If set to 1, this is not possible anymore.
 */
static int forbid_new_data = 0;

/**
 * The amount of additional space for custom data to be allocated upon
 * creating a new node.
 */
107
unsigned firm_add_node_size = 0;
108
109


110
/* register new space for every node */
111
unsigned firm_register_additional_node_data(unsigned size) {
112
	assert(!forbid_new_data && "Too late to register additional node data");
113

114
115
	if (forbid_new_data)
		return 0;
116

117
	return firm_add_node_size += size;
118
119
120
}


121
void init_irnode(void) {
122
123
	/* Forbid the addition of new data to an ir node. */
	forbid_new_data = 1;
Christian Schäfer's avatar
Christian Schäfer committed
124
125
}

126
/*
127
128
129
 * irnode constructor.
 * Create a new irnode in irg, with an op, mode, arity and
 * some incoming irnodes.
130
131
 * If arity is negative, a node with a dynamic array is created.
 */
132
ir_node *
133
134
new_ir_node(dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mode,
            int arity, ir_node **in)
Christian Schäfer's avatar
Christian Schäfer committed
135
{
136
137
138
	ir_node *res;
	size_t node_size = offsetof(ir_node, attr) + op->attr_size + firm_add_node_size;
	char *p;
139
	int i;
140
141

	assert(irg && op && mode);
142
	p = obstack_alloc(irg->obst, node_size);
143
	memset(p, 0, node_size);
144
	res = (ir_node *)(p + firm_add_node_size);
145
146
147
148
149
150
151
152
153
154

	res->kind     = k_ir_node;
	res->op       = op;
	res->mode     = mode;
	res->visited  = 0;
	res->node_idx = irg_register_node_idx(irg, res);
	res->link     = NULL;
	res->deps     = NULL;

	if (arity < 0) {
155
		res->in = NEW_ARR_F(ir_node *, 1);  /* 1: space for block */
156
	} else {
157
158
		/* not nice but necessary: End and Sync must always have a flexible array */
		if (op == op_End || op == op_Sync)
159
160
161
			res->in = NEW_ARR_F(ir_node *, (arity+1));
		else
			res->in = NEW_ARR_D(ir_node *, irg->obst, (arity+1));
162
		memcpy(&res->in[1], in, sizeof(ir_node *) * arity);
163
164
165
166
167
	}

	res->in[0] = block;
	set_irn_dbg_info(res, db);
	res->out = NULL;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
168
169

#ifdef DEBUG_libfirm
170
	res->node_nr = get_irp_new_node_nr();
Götz Lindenmaier's avatar
Götz Lindenmaier committed
171
172
#endif

173
	for (i = 0; i < EDGE_KIND_LAST; ++i)
174
		INIT_LIST_HEAD(&res->edge_info[i].outs_head);
175

176
	/* don't put this into the for loop, arity is -1 for some nodes! */
177
178
	edges_notify_edge(res, -1, res->in[0], NULL, irg);
	for (i = 1; i <= arity; ++i)
179
		edges_notify_edge(res, i - 1, res->in[i], NULL, irg);
Sebastian Hack's avatar
Sebastian Hack committed
180

181
	hook_new_node(irg, res);
Michael Beck's avatar
Michael Beck committed
182

183
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
184
185
}

Michael Beck's avatar
Michael Beck committed
186
/*-- getting some parameters from ir_nodes --*/
Christian Schäfer's avatar
Christian Schäfer committed
187

188
int (is_ir_node)(const void *thing) {
189
	return _is_ir_node(thing);
Sebastian Felis's avatar
Sebastian Felis committed
190
191
}

192
int (get_irn_intra_arity)(const ir_node *node) {
193
	return _get_irn_intra_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
194
195
}

196
int (get_irn_inter_arity)(const ir_node *node) {
197
	return _get_irn_inter_arity(node);
198
199
}

200
int (*_get_irn_arity)(const ir_node *node) = _get_irn_intra_arity;
201

202
int (get_irn_arity)(const ir_node *node) {
203
	return _get_irn_arity(node);
204
205
}

206
207
208
209
210
211
/* Returns the array with ins. This array is shifted with respect to the
   array accessed by get_irn_n: The block operand is at position 0 not -1.
   (@@@ This should be changed.)
   The order of the predecessors in this array is not guaranteed, except that
   lists of operands as predecessors of Block or arguments of a Call are
   consecutive. */
212
ir_node **get_irn_in(const ir_node *node) {
213
	assert(node);
214
#ifdef INTERPROCEDURAL_VIEW
215
216
217
218
219
220
221
222
223
	if (get_interprocedural_view()) { /* handle Filter and Block specially */
		if (get_irn_opcode(node) == iro_Filter) {
			assert(node->attr.filter.in_cg);
			return node->attr.filter.in_cg;
		} else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
			return node->attr.block.in_cg;
		}
		/* else fall through */
	}
224
#endif /* INTERPROCEDURAL_VIEW */
225
226
227
	return node->in;
}

228
void set_irn_in(ir_node *node, int arity, ir_node **in) {
229
	int i;
Michael Beck's avatar
Michael Beck committed
230
	ir_node *** pOld_in;
231
	ir_graph *irg = current_ir_graph;
232

233
	assert(node);
234
#ifdef INTERPROCEDURAL_VIEW
235
	if (get_interprocedural_view()) { /* handle Filter and Block specially */
Michael Beck's avatar
Michael Beck committed
236
237
		ir_opcode code = get_irn_opcode(node);
		if (code  == iro_Filter) {
238
			assert(node->attr.filter.in_cg);
Michael Beck's avatar
Michael Beck committed
239
240
241
			pOld_in = &node->attr.filter.in_cg;
		} else if (code == iro_Block && node->attr.block.in_cg) {
			pOld_in = &node->attr.block.in_cg;
242
		} else {
Michael Beck's avatar
Michael Beck committed
243
			pOld_in = &node->in;
244
		}
245
246
	} else
#endif /* INTERPROCEDURAL_VIEW */
Michael Beck's avatar
Michael Beck committed
247
		pOld_in = &node->in;
248

249
250

	for (i = 0; i < arity; i++) {
Michael Beck's avatar
Michael Beck committed
251
252
		if (i < ARR_LEN(*pOld_in)-1)
			edges_notify_edge(node, i, in[i], (*pOld_in)[i+1], irg);
253
		else
Michael Beck's avatar
Michael Beck committed
254
			edges_notify_edge(node, i, in[i], NULL,            irg);
255
	}
Michael Beck's avatar
Michael Beck committed
256
257
	for (;i < ARR_LEN(*pOld_in)-1; i++) {
		edges_notify_edge(node, i, NULL, (*pOld_in)[i+1], irg);
258
259
	}

Michael Beck's avatar
Michael Beck committed
260
261
262
263
	if (arity != ARR_LEN(*pOld_in) - 1) {
		ir_node * block = (*pOld_in)[0];
		*pOld_in = NEW_ARR_D(ir_node *, irg->obst, arity + 1);
		(*pOld_in)[0] = block;
264
265
266
	}
	fix_backedges(irg->obst, node);

Michael Beck's avatar
Michael Beck committed
267
	memcpy((*pOld_in) + 1, in, sizeof(ir_node *) * arity);
268
269
}

270
ir_node *(get_irn_intra_n)(const ir_node *node, int n) {
271
	return _get_irn_intra_n (node, n);
272
273
}

274
ir_node *(get_irn_inter_n)(const ir_node *node, int n) {
275
	return _get_irn_inter_n (node, n);
276
277
}

278
ir_node *(*_get_irn_n)(const ir_node *node, int n) = _get_irn_intra_n;
279

280
ir_node *(get_irn_n)(const ir_node *node, int n) {
281
	return _get_irn_n(node, n);
Christian Schäfer's avatar
Christian Schäfer committed
282
283
}

284
void set_irn_n(ir_node *node, int n, ir_node *in) {
285
286
287
288
289
290
291
292
293
294
295
296
	assert(node && node->kind == k_ir_node);
	assert(-1 <= n);
	assert(n < get_irn_arity(node));
	assert(in && in->kind == k_ir_node);

	if ((n == -1) && (get_irn_opcode(node) == iro_Filter)) {
		/* Change block pred in both views! */
		node->in[n + 1] = in;
		assert(node->attr.filter.in_cg);
		node->attr.filter.in_cg[n + 1] = in;
		return;
	}
297
#ifdef INTERPROCEDURAL_VIEW
298
299
300
301
302
303
304
305
306
307
308
	if (get_interprocedural_view()) { /* handle Filter and Block specially */
		if (get_irn_opcode(node) == iro_Filter) {
			assert(node->attr.filter.in_cg);
			node->attr.filter.in_cg[n + 1] = in;
			return;
		} else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
			node->attr.block.in_cg[n + 1] = in;
			return;
		}
		/* else fall through */
	}
309
#endif /* INTERPROCEDURAL_VIEW */
310
311
312
313
314
315
316
317

	/* Call the hook */
	hook_set_irn_n(node, n, in, node->in[n + 1]);

	/* Here, we rely on src and tgt being in the current ir graph */
	edges_notify_edge(node, n, in, node->in[n + 1], current_ir_graph);

	node->in[n + 1] = in;
Christian Schäfer's avatar
Christian Schäfer committed
318
319
}

320
int add_irn_n(ir_node *node, ir_node *in) {
321
322
323
324
325
326
327
328
	int pos;
	ir_graph *irg = get_irn_irg(node);

	assert(node->op->opar == oparity_dynamic);
	pos = ARR_LEN(node->in) - 1;
	ARR_APP1(ir_node *, node->in, in);
	edges_notify_edge(node, pos, node->in[pos + 1], NULL, irg);

329
330
331
	/* Call the hook */
	hook_set_irn_n(node, pos, node->in[pos + 1], NULL);

332
333
334
	return pos;
}

Christoph Mallon's avatar
Christoph Mallon committed
335
336
337
338
339
340
341
342
343
void del_Sync_n(ir_node *n, int i)
{
	int      arity     = get_Sync_n_preds(n);
	ir_node *last_pred = get_Sync_pred(n, arity - 1);
	set_Sync_pred(n, i, last_pred);
	edges_notify_edge(n, arity - 1, NULL, last_pred, get_irn_irg(n));
	ARR_SHRINKLEN(get_irn_in(n), arity);
}

344
int (get_irn_deps)(const ir_node *node) {
Sebastian Hack's avatar
Sebastian Hack committed
345
346
347
	return _get_irn_deps(node);
}

348
ir_node *(get_irn_dep)(const ir_node *node, int pos) {
Sebastian Hack's avatar
Sebastian Hack committed
349
350
351
	return _get_irn_dep(node, pos);
}

352
void (set_irn_dep)(ir_node *node, int pos, ir_node *dep) {
Sebastian Hack's avatar
Sebastian Hack committed
353
354
355
	_set_irn_dep(node, pos, dep);
}

356
int add_irn_dep(ir_node *node, ir_node *dep) {
Sebastian Hack's avatar
Sebastian Hack committed
357
358
	int res = 0;

359
360
	/* DEP edges are only allowed in backend phase */
	assert(get_irg_phase_state(get_irn_irg(node)) == phase_backend);
Sebastian Hack's avatar
Sebastian Hack committed
361
362
363
	if (node->deps == NULL) {
		node->deps = NEW_ARR_F(ir_node *, 1);
		node->deps[0] = dep;
364
	} else {
Sebastian Hack's avatar
Sebastian Hack committed
365
366
367
368
369
370
371
372
373
374
375
		int i, n;
		int first_zero = -1;

		for(i = 0, n = ARR_LEN(node->deps); i < n; ++i) {
			if(node->deps[i] == NULL)
				first_zero = i;

			if(node->deps[i] == dep)
				return i;
		}

376
		if (first_zero >= 0) {
Sebastian Hack's avatar
Sebastian Hack committed
377
378
			node->deps[first_zero] = dep;
			res = first_zero;
379
		} else {
Sebastian Hack's avatar
Sebastian Hack committed
380
381
382
383
384
385
386
387
388
389
			ARR_APP1(ir_node *, node->deps, dep);
			res = n;
		}
	}

	edges_notify_edge_kind(node, res, dep, NULL, EDGE_KIND_DEP, get_irn_irg(node));

	return res;
}

390
void add_irn_deps(ir_node *tgt, ir_node *src) {
Sebastian Hack's avatar
Sebastian Hack committed
391
392
	int i, n;

393
	for (i = 0, n = get_irn_deps(src); i < n; ++i)
Sebastian Hack's avatar
Sebastian Hack committed
394
395
396
397
		add_irn_dep(tgt, get_irn_dep(src, i));
}


398
ir_mode *(get_irn_mode)(const ir_node *node) {
399
	return _get_irn_mode(node);
Christian Schäfer's avatar
Christian Schäfer committed
400
401
}

402
void (set_irn_mode)(ir_node *node, ir_mode *mode) {
403
	_set_irn_mode(node, mode);
Till Riedel's avatar
Till Riedel committed
404
405
}

406
ir_modecode get_irn_modecode(const ir_node *node) {
407
408
	assert(node);
	return node->mode->code;
Christian Schäfer's avatar
Christian Schäfer committed
409
410
}

411
/** Gets the string representation of the mode .*/
412
const char *get_irn_modename(const ir_node *node) {
413
414
	assert(node);
	return get_mode_name(node->mode);
415
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
416

417
ident *get_irn_modeident(const ir_node *node) {
418
419
	assert(node);
	return get_mode_ident(node->mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
420
421
}

422
ir_op *(get_irn_op)(const ir_node *node) {
423
	return _get_irn_op(node);
Christian Schäfer's avatar
Christian Schäfer committed
424
425
426
}

/* should be private to the library: */
427
void (set_irn_op)(ir_node *node, ir_op *op) {
428
	_set_irn_op(node, op);
Christian Schäfer's avatar
Christian Schäfer committed
429
430
}

431
unsigned (get_irn_opcode)(const ir_node *node) {
432
	return _get_irn_opcode(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
433
434
}

435
const char *get_irn_opname(const ir_node *node) {
436
	assert(node);
437
	if (is_Phi0(node)) return "Phi0";
438
	return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
439
440
}

441
ident *get_irn_opident(const ir_node *node) {
442
443
	assert(node);
	return node->op->name;
444
445
}

446
unsigned long (get_irn_visited)(const ir_node *node) {
447
	return _get_irn_visited(node);
448
449
}

450
void (set_irn_visited)(ir_node *node, unsigned long visited) {
451
	_set_irn_visited(node, visited);
Christian Schäfer's avatar
Christian Schäfer committed
452
}
453

454
void (mark_irn_visited)(ir_node *node) {
455
	_mark_irn_visited(node);
456
457
}

458
int (irn_not_visited)(const ir_node *node) {
459
	return _irn_not_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
460
461
}

462
int (irn_visited)(const ir_node *node) {
463
	return _irn_visited(node);
464
465
}

466
void (set_irn_link)(ir_node *node, void *link) {
467
	_set_irn_link(node, link);
Christian Schäfer's avatar
Christian Schäfer committed
468
469
}

470
void *(get_irn_link)(const ir_node *node) {
471
	return _get_irn_link(node);
Christian Schäfer's avatar
Christian Schäfer committed
472
473
}

474
op_pin_state (get_irn_pinned)(const ir_node *node) {
475
	return _get_irn_pinned(node);
476
477
}

478
op_pin_state (is_irn_pinned_in_irg) (const ir_node *node) {
479
	return _is_irn_pinned_in_irg(node);
480
481
}

Michael Beck's avatar
Michael Beck committed
482
void set_irn_pinned(ir_node *node, op_pin_state state) {
483
484
485
	/* due to optimization an opt may be turned into a Tuple */
	if (get_irn_op(node) == op_Tuple)
		return;
Michael Beck's avatar
Michael Beck committed
486

487
488
	assert(node && get_op_pinned(get_irn_op(node)) >= op_pin_state_exc_pinned);
	assert(state == op_pin_state_pinned || state == op_pin_state_floats);
Michael Beck's avatar
Michael Beck committed
489

490
	node->attr.except.pin_state = state;
Michael Beck's avatar
Michael Beck committed
491
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
492
493
494
495
496

#ifdef DO_HEAPANALYSIS
/* Access the abstract interpretation information of a node.
   Returns NULL if no such information is available. */
struct abstval *get_irn_abst_value(ir_node *n) {
497
	return n->av;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
498
499
500
}
/* Set the abstract interpretation information of a node. */
void set_irn_abst_value(ir_node *n, struct abstval *os) {
501
	n->av = os;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
502
503
}
struct section *firm_get_irn_section(ir_node *n) {
504
	return n->sec;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
505
506
}
void firm_set_irn_section(ir_node *n, struct section *s) {
507
	n->sec = s;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
508
}
509
510
#else
/* Dummies needed for firmjni. */
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
struct abstval *get_irn_abst_value(ir_node *n) {
	(void) n;
	return NULL;
}
void set_irn_abst_value(ir_node *n, struct abstval *os) {
	(void) n;
	(void) os;
}
struct section *firm_get_irn_section(ir_node *n) {
	(void) n;
	return NULL;
}
void firm_set_irn_section(ir_node *n, struct section *s) {
	(void) n;
	(void) s;
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
527
528
529
#endif /* DO_HEAPANALYSIS */


Götz Lindenmaier's avatar
Götz Lindenmaier committed
530
/* Outputs a unique number for this node */
531
long get_irn_node_nr(const ir_node *node) {
532
	assert(node);
533
#ifdef DEBUG_libfirm
534
	return node->node_nr;
535
#else
536
	return (long)PTR_TO_INT(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
537
#endif
538
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
539

540
const_attr *get_irn_const_attr(ir_node *node) {
541
	assert(is_Const(node));
542
	return &node->attr.con;
Christian Schäfer's avatar
Christian Schäfer committed
543
544
}

545
long get_irn_proj_attr(ir_node *node) {
546
	/* BEWARE: check for true Proj node here, no Filter */
547
548
	assert(node->op == op_Proj);
	return node->attr.proj;
Christian Schäfer's avatar
Christian Schäfer committed
549
550
}

551
alloc_attr *get_irn_alloc_attr(ir_node *node) {
552
	assert(is_Alloc(node));
553
	return &node->attr.alloc;
Christian Schäfer's avatar
Christian Schäfer committed
554
555
}

556
free_attr *get_irn_free_attr(ir_node *node) {
557
	assert(is_Free(node));
558
	return &node->attr.free;
Christian Schäfer's avatar
Christian Schäfer committed
559
560
}

561
symconst_attr *get_irn_symconst_attr(ir_node *node) {
562
	assert(is_SymConst(node));
563
	return &node->attr.symc;
Christian Schäfer's avatar
Christian Schäfer committed
564
565
}

566
ir_type *get_irn_call_attr(ir_node *node) {
567
	assert(is_Call(node));
568
	return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
569
570
}

571
sel_attr *get_irn_sel_attr(ir_node *node) {
572
	assert(is_Sel(node));
573
	return &node->attr.sel;
Christian Schäfer's avatar
Christian Schäfer committed
574
575
}

576
phi_attr *get_irn_phi_attr(ir_node *node) {
577
	return &node->attr.phi;
Christian Schäfer's avatar
Christian Schäfer committed
578
579
}

580
block_attr *get_irn_block_attr(ir_node *node) {
581
	assert(is_Block(node));
582
	return &node->attr.block;
Christian Schäfer's avatar
Christian Schäfer committed
583
584
}

585
load_attr *get_irn_load_attr(ir_node *node) {
586
	assert(is_Load(node));
587
	return &node->attr.load;
588
589
}

590
store_attr *get_irn_store_attr(ir_node *node) {
591
	assert(is_Store(node));
592
	return &node->attr.store;
593
594
}

595
except_attr *get_irn_except_attr(ir_node *node) {
596
	assert(node->op == op_Div || node->op == op_Quot ||
597
	       node->op == op_DivMod || node->op == op_Mod || node->op == op_Call || node->op == op_Alloc || node->op == op_Bound);
598
	return &node->attr.except;
599
600
}

601
602
603
604
605
606
divmod_attr *get_irn_divmod_attr(ir_node *node) {
	assert(node->op == op_Div || node->op == op_Quot ||
	       node->op == op_DivMod || node->op == op_Mod);
	return &node->attr.divmod;
}

607
608
609
void *(get_irn_generic_attr)(ir_node *node) {
	assert(is_ir_node(node));
	return _get_irn_generic_attr(node);
610
611
}

Matthias Braun's avatar
fix    
Matthias Braun committed
612
const void *(get_irn_generic_attr_const)(const ir_node *node) {
613
614
615
616
	assert(is_ir_node(node));
	return _get_irn_generic_attr_const(node);
}

617
unsigned (get_irn_idx)(const ir_node *node) {
618
619
	assert(is_ir_node(node));
	return _get_irn_idx(node);
620
621
}

622
int get_irn_pred_pos(ir_node *node, ir_node *arg) {
623
624
625
626
627
628
	int i;
	for (i = get_irn_arity(node) - 1; i >= 0; i--) {
		if (get_irn_n(node, i) == arg)
			return i;
	}
	return -1;
629
630
}

Christian Schäfer's avatar
Christian Schäfer committed
631
632
/** manipulate fields of individual nodes **/

633
/* this works for all except Block */
634
ir_node *get_nodes_block(const ir_node *node) {
635
636
	assert(node->op != op_Block);
	return get_irn_n(node, -1);
Christian Schäfer's avatar
Christian Schäfer committed
637
638
}

639
void set_nodes_block(ir_node *node, ir_node *block) {
640
641
	assert(node->op != op_Block);
	set_irn_n(node, -1, block);
Christian Schäfer's avatar
Christian Schäfer committed
642
643
}

Michael Beck's avatar
Michael Beck committed
644
/* this works for all except Block */
645
ir_node *get_nodes_MacroBlock(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
646
647
648
649
	assert(node->op != op_Block);
	return get_Block_MacroBlock(get_irn_n(node, -1));
}

650
651
/* Test whether arbitrary node is frame pointer, i.e. Proj(pn_Start_P_frame_base)
 * from Start.  If so returns frame type, else Null. */
652
ir_type *is_frame_pointer(const ir_node *n) {
653
654
	if (is_Proj(n) && (get_Proj_proj(n) == pn_Start_P_frame_base)) {
		ir_node *start = get_Proj_pred(n);
655
		if (is_Start(start)) {
656
657
658
659
			return get_irg_frame_type(get_irn_irg(start));
		}
	}
	return NULL;
660
661
}

662
663
/* Test whether arbitrary node is tls pointer, i.e. Proj(pn_Start_P_tls)
 * from Start.  If so returns tls type, else Null. */
664
ir_type *is_tls_pointer(const ir_node *n) {
665
	if (is_Proj(n) && (get_Proj_proj(n) == pn_Start_P_tls)) {
666
		ir_node *start = get_Proj_pred(n);
667
		if (is_Start(start)) {
668
669
670
671
			return get_tls_type();
		}
	}
	return NULL;
672
673
}

674
675
/* Test whether arbitrary node is value arg base, i.e. Proj(pn_Start_P_value_arg_base)
 * from Start.  If so returns 1, else 0. */
676
677
int is_value_arg_pointer(const ir_node *n) {
	if (is_Proj(n) &&
678
		(get_Proj_proj(n) == pn_Start_P_value_arg_base) &&
679
		is_Start(get_Proj_pred(n)))
680
681
		return 1;
	return 0;
682
683
}

684
/* Returns an array with the predecessors of the Block. Depending on
685
   the implementation of the graph data structure this can be a copy of
686
687
   the internal representation of predecessors as well as the internal
   array itself. Therefore writing to this array might obstruct the ir. */
688
ir_node **get_Block_cfgpred_arr(ir_node *node) {
689
	assert(is_Block(node));
690
	return (ir_node **)&(get_irn_in(node)[1]);
691
692
}

693
int (get_Block_n_cfgpreds)(const ir_node *node) {
694
	return _get_Block_n_cfgpreds(node);
Christian Schäfer's avatar
Christian Schäfer committed
695
696
}

697
ir_node *(get_Block_cfgpred)(const ir_node *node, int pos) {
698
	return _get_Block_cfgpred(node, pos);
Christian Schäfer's avatar
Christian Schäfer committed
699
700
}

701
void set_Block_cfgpred(ir_node *node, int pos, ir_node *pred) {
702
	assert(is_Block(node));
703
	set_irn_n(node, pos, pred);
Christian Schäfer's avatar
Christian Schäfer committed
704
705
}

706
ir_node *(get_Block_cfgpred_block)(const ir_node *node, int pos) {
707
	return _get_Block_cfgpred_block(node, pos);
708
709
}

710
int get_Block_matured(const ir_node *node) {
711
	assert(is_Block(node));
Michael Beck's avatar
Michael Beck committed
712
	return (int)node->attr.block.is_matured;
Christian Schäfer's avatar
Christian Schäfer committed
713
714
}

715
void set_Block_matured(ir_node *node, int matured) {
716
	assert(is_Block(node));
Michael Beck's avatar
Michael Beck committed
717
	node->attr.block.is_matured = matured;
Christian Schäfer's avatar
Christian Schäfer committed
718
}
Michael Beck's avatar
Michael Beck committed
719

720
unsigned long (get_Block_block_visited)(const ir_node *node) {
721
	return _get_Block_block_visited(node);
Christian Schäfer's avatar
Christian Schäfer committed
722
723
}

724
void (set_Block_block_visited)(ir_node *node, unsigned long visit) {
725
	_set_Block_block_visited(node, visit);
Christian Schäfer's avatar
Christian Schäfer committed
726
727
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
728
/* For this current_ir_graph must be set. */
729
void (mark_Block_block_visited)(ir_node *node) {
730
	_mark_Block_block_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
731
732
}

733
int (Block_not_block_visited)(const ir_node *node) {
734
	return _Block_not_block_visited(node);
735
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
736

737
int (Block_block_visited)(const ir_node *node) {
Matthias Braun's avatar
Matthias Braun committed
738
739
740
	return _Block_block_visited(node);
}

741
ir_node *get_Block_graph_arr(ir_node *node, int pos) {
742
	assert(is_Block(node));
743
	return node->attr.block.graph_arr[pos+1];
Christian Schäfer's avatar
Christian Schäfer committed
744
745
}

746
void set_Block_graph_arr(ir_node *node, int pos, ir_node *value) {
747
	assert(is_Block(node));
748
	node->attr.block.graph_arr[pos+1] = value;
Christian Schäfer's avatar
Christian Schäfer committed
749
}
750

751
#ifdef INTERPROCEDURAL_VIEW
Michael Beck's avatar
Michael Beck committed
752
void set_Block_cg_cfgpred_arr(ir_node *node, int arity, ir_node *in[]) {
753
	assert(is_Block(node));
754
755
756
757
758
759
760
761
762
763
764
765
766
767
	if (node->attr.block.in_cg == NULL || arity != ARR_LEN(node->attr.block.in_cg) - 1) {
		node->attr.block.in_cg = NEW_ARR_D(ir_node *, current_ir_graph->obst, arity + 1);
		node->attr.block.in_cg[0] = NULL;
		node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
		{
			/* Fix backedge array.  fix_backedges() operates depending on
			   interprocedural_view. */
			int ipv = get_interprocedural_view();
			set_interprocedural_view(1);
			fix_backedges(current_ir_graph->obst, node);
			set_interprocedural_view(ipv);
		}
	}
	memcpy(node->attr.block.in_cg + 1, in, sizeof(ir_node *) * arity);
768
769
}

Michael Beck's avatar
Michael Beck committed
770
void set_Block_cg_cfgpred(ir_node *node, int pos, ir_node *pred) {
771
	assert(is_Block(node) && node->attr.block.in_cg &&
772
773
	       0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
	node->attr.block.in_cg[pos + 1] = pred;
774
775
}

Michael Beck's avatar
Michael Beck committed
776
ir_node **get_Block_cg_cfgpred_arr(ir_node *node) {
777
	assert(is_Block(node));
778
	return node->attr.block.in_cg == NULL ? NULL : node->attr.block.in_cg  + 1;
779
780
}

781
int get_Block_cg_n_cfgpreds(const ir_node *node) {
782
	assert(is_Block(node));
783
	return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
784
785
}

786
ir_node *get_Block_cg_cfgpred(const ir_node *node, int pos) {
787
	assert(is_Block(node) && node->attr.block.in_cg);
788
	return node->attr.block.in_cg[pos + 1];
789
790
}

Michael Beck's avatar
Michael Beck committed
791
void remove_Block_cg_cfgpred_arr(ir_node *node) {
792
	assert(is_Block(node));
793
	node->attr.block.in_cg = NULL;
794
}
795
#endif /* INTERPROCEDURAL_VIEW */
796

797
ir_node *(set_Block_dead)(ir_node *block) {
798
	return _set_Block_dead(block);
799
800
801
}

int (is_Block_dead)(const ir_node *block) {
802
	return _is_Block_dead(block);
803
804
}

805
ir_extblk *get_Block_extbb(const ir_node *block) {
Michael Beck's avatar
Michael Beck committed
806
	ir_extblk *res;
807
	assert(is_Block(block));
Michael Beck's avatar
Michael Beck committed
808
809
	res = block->attr.block.extblk;
	assert(res == NULL || is_ir_extbb(res));
810
	return res;
811
812
813
}

void set_Block_extbb(ir_node *block, ir_extblk *extblk) {
814
	assert(is_Block(block));
Michael Beck's avatar
Michael Beck committed
815
	assert(extblk == NULL || is_ir_extbb(extblk));
816
	block->attr.block.extblk = extblk;
817
818
}

Michael Beck's avatar
Michael Beck committed
819
/* Returns the macro block header of a block.*/
Michael Beck's avatar
Michael Beck committed
820
ir_node *get_Block_MacroBlock(const ir_node *block) {
Michael Beck's avatar