irnode.c 73.2 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
		res->in = NEW_ARR_D(ir_node *, irg->obst, (arity+1));
		memcpy(&res->in[1], in, sizeof(ir_node *) * arity);
159
160
161
162
163
	}

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

#ifdef DEBUG_libfirm
166
	res->node_nr = get_irp_new_node_nr();
Götz Lindenmaier's avatar
Götz Lindenmaier committed
167
168
#endif

169
	for (i = 0; i < EDGE_KIND_LAST; ++i)
170
		INIT_LIST_HEAD(&res->edge_info[i].outs_head);
171

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

177
	hook_new_node(irg, res);
Michael Beck's avatar
Michael Beck committed
178

179
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
180
181
}

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

184
int (is_ir_node)(const void *thing) {
185
	return _is_ir_node(thing);
Sebastian Felis's avatar
Sebastian Felis committed
186
187
}

188
int (get_irn_intra_arity)(const ir_node *node) {
189
	return _get_irn_intra_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
190
191
}

192
int (get_irn_inter_arity)(const ir_node *node) {
193
	return _get_irn_inter_arity(node);
194
195
}

196
int (*_get_irn_arity)(const ir_node *node) = _get_irn_intra_arity;
197

198
int (get_irn_arity)(const ir_node *node) {
199
	return _get_irn_arity(node);
200
201
}

202
203
204
205
206
207
/* 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. */
208
ir_node **get_irn_in(const ir_node *node) {
209
210
211
212
213
214
215
216
217
218
219
220
221
	assert(node);
	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 */
	}
	return node->in;
}

222
void set_irn_in(ir_node *node, int arity, ir_node **in) {
223
	int i;
Michael Beck's avatar
Michael Beck committed
224
	ir_node *** pOld_in;
225
226
227
	ir_graph *irg = current_ir_graph;
	assert(node);
	if (get_interprocedural_view()) { /* handle Filter and Block specially */
Michael Beck's avatar
Michael Beck committed
228
229
		ir_opcode code = get_irn_opcode(node);
		if (code  == iro_Filter) {
230
			assert(node->attr.filter.in_cg);
Michael Beck's avatar
Michael Beck committed
231
232
233
			pOld_in = &node->attr.filter.in_cg;
		} else if (code == iro_Block && node->attr.block.in_cg) {
			pOld_in = &node->attr.block.in_cg;
234
		} else {
Michael Beck's avatar
Michael Beck committed
235
			pOld_in = &node->in;
236
237
		}
	} else {
Michael Beck's avatar
Michael Beck committed
238
		pOld_in = &node->in;
239
240
241
	}

	for (i = 0; i < arity; i++) {
Michael Beck's avatar
Michael Beck committed
242
243
		if (i < ARR_LEN(*pOld_in)-1)
			edges_notify_edge(node, i, in[i], (*pOld_in)[i+1], irg);
244
		else
Michael Beck's avatar
Michael Beck committed
245
			edges_notify_edge(node, i, in[i], NULL,            irg);
246
	}
Michael Beck's avatar
Michael Beck committed
247
248
	for (;i < ARR_LEN(*pOld_in)-1; i++) {
		edges_notify_edge(node, i, NULL, (*pOld_in)[i+1], irg);
249
250
	}

Michael Beck's avatar
Michael Beck committed
251
252
253
254
	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;
255
256
257
	}
	fix_backedges(irg->obst, node);

Michael Beck's avatar
Michael Beck committed
258
	memcpy((*pOld_in) + 1, in, sizeof(ir_node *) * arity);
259
260
}

261
ir_node *(get_irn_intra_n)(const ir_node *node, int n) {
262
	return _get_irn_intra_n (node, n);
263
264
}

265
ir_node *(get_irn_inter_n)(const ir_node *node, int n) {
266
	return _get_irn_inter_n (node, n);
267
268
}

269
ir_node *(*_get_irn_n)(const ir_node *node, int n) = _get_irn_intra_n;
270

271
ir_node *(get_irn_n)(const ir_node *node, int n) {
272
	return _get_irn_n(node, n);
Christian Schäfer's avatar
Christian Schäfer committed
273
274
}

275
void set_irn_n(ir_node *node, int n, ir_node *in) {
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
	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;
	}
	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 */
	}

	/* 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
307
308
}

309
int add_irn_n(ir_node *node, ir_node *in) {
310
311
312
313
314
315
316
317
	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);

318
319
320
	/* Call the hook */
	hook_set_irn_n(node, pos, node->in[pos + 1], NULL);

321
322
323
	return pos;
}

324
int (get_irn_deps)(const ir_node *node) {
Sebastian Hack's avatar
Sebastian Hack committed
325
326
327
	return _get_irn_deps(node);
}

328
ir_node *(get_irn_dep)(const ir_node *node, int pos) {
Sebastian Hack's avatar
Sebastian Hack committed
329
330
331
	return _get_irn_dep(node, pos);
}

332
void (set_irn_dep)(ir_node *node, int pos, ir_node *dep) {
Sebastian Hack's avatar
Sebastian Hack committed
333
334
335
	_set_irn_dep(node, pos, dep);
}

336
int add_irn_dep(ir_node *node, ir_node *dep) {
Sebastian Hack's avatar
Sebastian Hack committed
337
338
339
340
341
	int res = 0;

	if (node->deps == NULL) {
		node->deps = NEW_ARR_F(ir_node *, 1);
		node->deps[0] = dep;
342
	} else {
Sebastian Hack's avatar
Sebastian Hack committed
343
344
345
346
347
348
349
350
351
352
353
		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;
		}

354
		if (first_zero >= 0) {
Sebastian Hack's avatar
Sebastian Hack committed
355
356
			node->deps[first_zero] = dep;
			res = first_zero;
357
		} else {
Sebastian Hack's avatar
Sebastian Hack committed
358
359
360
361
362
363
364
365
366
367
			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;
}

368
void add_irn_deps(ir_node *tgt, ir_node *src) {
Sebastian Hack's avatar
Sebastian Hack committed
369
370
	int i, n;

371
	for (i = 0, n = get_irn_deps(src); i < n; ++i)
Sebastian Hack's avatar
Sebastian Hack committed
372
373
374
375
		add_irn_dep(tgt, get_irn_dep(src, i));
}


376
ir_mode *(get_irn_mode)(const ir_node *node) {
377
	return _get_irn_mode(node);
Christian Schäfer's avatar
Christian Schäfer committed
378
379
}

380
void (set_irn_mode)(ir_node *node, ir_mode *mode) {
381
	_set_irn_mode(node, mode);
Till Riedel's avatar
Till Riedel committed
382
383
}

384
modecode get_irn_modecode(const ir_node *node) {
385
386
	assert(node);
	return node->mode->code;
Christian Schäfer's avatar
Christian Schäfer committed
387
388
}

389
/** Gets the string representation of the mode .*/
390
const char *get_irn_modename(const ir_node *node) {
391
392
	assert(node);
	return get_mode_name(node->mode);
393
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
394

395
ident *get_irn_modeident(const ir_node *node) {
396
397
	assert(node);
	return get_mode_ident(node->mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
398
399
}

400
ir_op *(get_irn_op)(const ir_node *node) {
401
	return _get_irn_op(node);
Christian Schäfer's avatar
Christian Schäfer committed
402
403
404
}

/* should be private to the library: */
405
void (set_irn_op)(ir_node *node, ir_op *op) {
406
	_set_irn_op(node, op);
Christian Schäfer's avatar
Christian Schäfer committed
407
408
}

409
unsigned (get_irn_opcode)(const ir_node *node) {
410
	return _get_irn_opcode(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
411
412
}

413
const char *get_irn_opname(const ir_node *node) {
414
	assert(node);
415
	if (is_Phi0(node)) return "Phi0";
416
	return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
417
418
}

419
ident *get_irn_opident(const ir_node *node) {
420
421
	assert(node);
	return node->op->name;
422
423
}

424
unsigned long (get_irn_visited)(const ir_node *node) {
425
	return _get_irn_visited(node);
426
427
}

428
void (set_irn_visited)(ir_node *node, unsigned long visited) {
429
	_set_irn_visited(node, visited);
Christian Schäfer's avatar
Christian Schäfer committed
430
}
431

432
void (mark_irn_visited)(ir_node *node) {
433
	_mark_irn_visited(node);
434
435
}

436
int (irn_not_visited)(const ir_node *node) {
437
	return _irn_not_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
438
439
}

440
int (irn_visited)(const ir_node *node) {
441
	return _irn_visited(node);
442
443
}

444
void (set_irn_link)(ir_node *node, void *link) {
445
	_set_irn_link(node, link);
Christian Schäfer's avatar
Christian Schäfer committed
446
447
}

448
void *(get_irn_link)(const ir_node *node) {
449
	return _get_irn_link(node);
Christian Schäfer's avatar
Christian Schäfer committed
450
451
}

452
op_pin_state (get_irn_pinned)(const ir_node *node) {
453
	return _get_irn_pinned(node);
454
455
}

456
op_pin_state (is_irn_pinned_in_irg) (const ir_node *node) {
457
	return _is_irn_pinned_in_irg(node);
458
459
}

Michael Beck's avatar
Michael Beck committed
460
void set_irn_pinned(ir_node *node, op_pin_state state) {
461
462
463
	/* 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
464

465
466
	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
467

468
	node->attr.except.pin_state = state;
Michael Beck's avatar
Michael Beck committed
469
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
470
471
472
473
474

#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) {
475
	return n->av;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
476
477
478
}
/* Set the abstract interpretation information of a node. */
void set_irn_abst_value(ir_node *n, struct abstval *os) {
479
	n->av = os;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
480
481
}
struct section *firm_get_irn_section(ir_node *n) {
482
	return n->sec;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
483
484
}
void firm_set_irn_section(ir_node *n, struct section *s) {
485
	n->sec = s;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
486
}
487
488
#else
/* Dummies needed for firmjni. */
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
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
505
506
507
#endif /* DO_HEAPANALYSIS */


Götz Lindenmaier's avatar
Götz Lindenmaier committed
508
/* Outputs a unique number for this node */
509
long get_irn_node_nr(const ir_node *node) {
510
	assert(node);
511
#ifdef DEBUG_libfirm
512
	return node->node_nr;
513
#else
514
	return (long)PTR_TO_INT(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
515
#endif
516
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
517

518
const_attr *get_irn_const_attr(ir_node *node) {
519
	assert(node->op == op_Const);
520
	return &node->attr.con;
Christian Schäfer's avatar
Christian Schäfer committed
521
522
}

523
long get_irn_proj_attr(ir_node *node) {
524
525
	assert(node->op == op_Proj);
	return node->attr.proj;
Christian Schäfer's avatar
Christian Schäfer committed
526
527
}

528
alloc_attr *get_irn_alloc_attr(ir_node *node) {
529
	assert(node->op == op_Alloc);
530
	return &node->attr.alloc;
Christian Schäfer's avatar
Christian Schäfer committed
531
532
}

533
free_attr *get_irn_free_attr(ir_node *node) {
534
	assert(node->op == op_Free);
535
	return &node->attr.free;
Christian Schäfer's avatar
Christian Schäfer committed
536
537
}

538
symconst_attr *get_irn_symconst_attr(ir_node *node) {
539
	assert(node->op == op_SymConst);
540
	return &node->attr.symc;
Christian Schäfer's avatar
Christian Schäfer committed
541
542
}

543
ir_type *get_irn_call_attr(ir_node *node) {
544
545
	assert(node->op == op_Call);
	return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
546
547
}

548
sel_attr *get_irn_sel_attr(ir_node *node) {
549
	assert(node->op == op_Sel);
550
	return &node->attr.sel;
Christian Schäfer's avatar
Christian Schäfer committed
551
552
}

553
phi_attr *get_irn_phi_attr(ir_node *node) {
554
	return &node->attr.phi;
Christian Schäfer's avatar
Christian Schäfer committed
555
556
}

557
block_attr *get_irn_block_attr(ir_node *node) {
558
	assert(node->op == op_Block);
559
	return &node->attr.block;
Christian Schäfer's avatar
Christian Schäfer committed
560
561
}

562
load_attr *get_irn_load_attr(ir_node *node) {
563
	assert(node->op == op_Load);
564
	return &node->attr.load;
565
566
}

567
store_attr *get_irn_store_attr(ir_node *node) {
568
	assert(node->op == op_Store);
569
	return &node->attr.store;
570
571
}

572
except_attr *get_irn_except_attr(ir_node *node) {
573
	assert(node->op == op_Div || node->op == op_Quot ||
574
	       node->op == op_DivMod || node->op == op_Mod || node->op == op_Call || node->op == op_Alloc || node->op == op_Bound);
575
	return &node->attr.except;
576
577
}

578
579
580
581
582
583
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;
}

584
585
586
void *(get_irn_generic_attr)(ir_node *node) {
	assert(is_ir_node(node));
	return _get_irn_generic_attr(node);
587
588
}

Matthias Braun's avatar
fix    
Matthias Braun committed
589
const void *(get_irn_generic_attr_const)(const ir_node *node) {
590
591
592
593
	assert(is_ir_node(node));
	return _get_irn_generic_attr_const(node);
}

594
unsigned (get_irn_idx)(const ir_node *node) {
595
596
	assert(is_ir_node(node));
	return _get_irn_idx(node);
597
598
}

599
int get_irn_pred_pos(ir_node *node, ir_node *arg) {
600
601
602
603
604
605
	int i;
	for (i = get_irn_arity(node) - 1; i >= 0; i--) {
		if (get_irn_n(node, i) == arg)
			return i;
	}
	return -1;
606
607
}

Christian Schäfer's avatar
Christian Schäfer committed
608
609
/** manipulate fields of individual nodes **/

610
/* this works for all except Block */
611
ir_node *get_nodes_block(const ir_node *node) {
612
613
	assert(node->op != op_Block);
	return get_irn_n(node, -1);
Christian Schäfer's avatar
Christian Schäfer committed
614
615
}

616
void set_nodes_block(ir_node *node, ir_node *block) {
617
618
	assert(node->op != op_Block);
	set_irn_n(node, -1, block);
Christian Schäfer's avatar
Christian Schäfer committed
619
620
}

Michael Beck's avatar
Michael Beck committed
621
/* this works for all except Block */
622
ir_node *get_nodes_MacroBlock(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
623
624
625
626
	assert(node->op != op_Block);
	return get_Block_MacroBlock(get_irn_n(node, -1));
}

627
628
/* Test whether arbitrary node is frame pointer, i.e. Proj(pn_Start_P_frame_base)
 * from Start.  If so returns frame type, else Null. */
629
ir_type *is_frame_pointer(const ir_node *n) {
630
631
	if (is_Proj(n) && (get_Proj_proj(n) == pn_Start_P_frame_base)) {
		ir_node *start = get_Proj_pred(n);
632
		if (is_Start(start)) {
633
634
635
636
			return get_irg_frame_type(get_irn_irg(start));
		}
	}
	return NULL;
637
638
639
640
}

/* Test whether arbitrary node is globals pointer, i.e. Proj(pn_Start_P_globals)
 * from Start.  If so returns global type, else Null. */
641
ir_type *is_globals_pointer(const ir_node *n) {
642
643
	if (is_Proj(n) && (get_Proj_proj(n) == pn_Start_P_globals)) {
		ir_node *start = get_Proj_pred(n);
644
		if (is_Start(start)) {
645
646
647
648
			return get_glob_type();
		}
	}
	return NULL;
649
650
}

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

663
664
/* 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. */
665
666
int is_value_arg_pointer(const ir_node *n) {
	if (is_Proj(n) &&
667
		(get_Proj_proj(n) == pn_Start_P_value_arg_base) &&
668
		is_Start(get_Proj_pred(n)))
669
670
		return 1;
	return 0;
671
672
}

673
/* Returns an array with the predecessors of the Block. Depending on
674
   the implementation of the graph data structure this can be a copy of
675
676
   the internal representation of predecessors as well as the internal
   array itself. Therefore writing to this array might obstruct the ir. */
677
ir_node **get_Block_cfgpred_arr(ir_node *node) {
678
679
	assert((node->op == op_Block));
	return (ir_node **)&(get_irn_in(node)[1]);
680
681
}

682
int (get_Block_n_cfgpreds)(const ir_node *node) {
683
	return _get_Block_n_cfgpreds(node);
Christian Schäfer's avatar
Christian Schäfer committed
684
685
}

686
ir_node *(get_Block_cfgpred)(const ir_node *node, int pos) {
687
	return _get_Block_cfgpred(node, pos);
Christian Schäfer's avatar
Christian Schäfer committed
688
689
}

690
void set_Block_cfgpred(ir_node *node, int pos, ir_node *pred) {
691
692
	assert(node->op == op_Block);
	set_irn_n(node, pos, pred);
Christian Schäfer's avatar
Christian Schäfer committed
693
694
}

695
ir_node *(get_Block_cfgpred_block)(const ir_node *node, int pos) {
696
	return _get_Block_cfgpred_block(node, pos);
697
698
}

699
int get_Block_matured(const ir_node *node) {
700
	assert(node->op == op_Block);
Michael Beck's avatar
Michael Beck committed
701
	return (int)node->attr.block.is_matured;
Christian Schäfer's avatar
Christian Schäfer committed
702
703
}

704
void set_Block_matured(ir_node *node, int matured) {
705
	assert(node->op == op_Block);
Michael Beck's avatar
Michael Beck committed
706
	node->attr.block.is_matured = matured;
Christian Schäfer's avatar
Christian Schäfer committed
707
}
Michael Beck's avatar
Michael Beck committed
708

709
unsigned long (get_Block_block_visited)(const ir_node *node) {
710
	return _get_Block_block_visited(node);
Christian Schäfer's avatar
Christian Schäfer committed
711
712
}

713
void (set_Block_block_visited)(ir_node *node, unsigned long visit) {
714
	_set_Block_block_visited(node, visit);
Christian Schäfer's avatar
Christian Schäfer committed
715
716
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
717
/* For this current_ir_graph must be set. */
718
void (mark_Block_block_visited)(ir_node *node) {
719
	_mark_Block_block_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
720
721
}

722
int (Block_not_block_visited)(const ir_node *node) {
723
	return _Block_not_block_visited(node);
724
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
725

726
int (Block_block_visited)(const ir_node *node) {
Matthias Braun's avatar
Matthias Braun committed
727
728
729
	return _Block_block_visited(node);
}

730
ir_node *get_Block_graph_arr(ir_node *node, int pos) {
731
732
	assert(node->op == op_Block);
	return node->attr.block.graph_arr[pos+1];
Christian Schäfer's avatar
Christian Schäfer committed
733
734
}

735
void set_Block_graph_arr(ir_node *node, int pos, ir_node *value) {
736
737
	assert(node->op == op_Block);
	node->attr.block.graph_arr[pos+1] = value;
Christian Schäfer's avatar
Christian Schäfer committed
738
}
739

740
#ifdef INTERPROCEDURAL_VIEW
Michael Beck's avatar
Michael Beck committed
741
void set_Block_cg_cfgpred_arr(ir_node *node, int arity, ir_node *in[]) {
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
	assert(node->op == op_Block);
	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);
757
758
}

Michael Beck's avatar
Michael Beck committed
759
void set_Block_cg_cfgpred(ir_node *node, int pos, ir_node *pred) {
760
761
762
763
	assert(node->op == op_Block &&
	       node->attr.block.in_cg &&
	       0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
	node->attr.block.in_cg[pos + 1] = pred;
764
765
}

Michael Beck's avatar
Michael Beck committed
766
ir_node **get_Block_cg_cfgpred_arr(ir_node *node) {
767
768
	assert(node->op == op_Block);
	return node->attr.block.in_cg == NULL ? NULL : node->attr.block.in_cg  + 1;
769
770
}

771
int get_Block_cg_n_cfgpreds(const ir_node *node) {
772
773
	assert(node->op == op_Block);
	return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
774
775
}

776
ir_node *get_Block_cg_cfgpred(const ir_node *node, int pos) {
777
778
	assert(node->op == op_Block && node->attr.block.in_cg);
	return node->attr.block.in_cg[pos + 1];
779
780
}

Michael Beck's avatar
Michael Beck committed
781
void remove_Block_cg_cfgpred_arr(ir_node *node) {
782
783
	assert(node->op == op_Block);
	node->attr.block.in_cg = NULL;
784
}
785
#endif
786

787
ir_node *(set_Block_dead)(ir_node *block) {
788
	return _set_Block_dead(block);
789
790
791
}

int (is_Block_dead)(const ir_node *block) {
792
	return _is_Block_dead(block);
793
794
}

795
ir_extblk *get_Block_extbb(const ir_node *block) {
Michael Beck's avatar
Michael Beck committed
796
	ir_extblk *res;
797
	assert(is_Block(block));
Michael Beck's avatar
Michael Beck committed
798
799
	res = block->attr.block.extblk;
	assert(res == NULL || is_ir_extbb(res));
800
	return res;
801
802
803
}

void set_Block_extbb(ir_node *block, ir_extblk *extblk) {
804
	assert(is_Block(block));
Michael Beck's avatar
Michael Beck committed
805
	assert(extblk == NULL || is_ir_extbb(extblk));
806
	block->attr.block.extblk = extblk;
807
808
}

809
/* returns the macro block header of a block. */
Michael Beck's avatar
Michael Beck committed
810
ir_node *get_Block_MacroBlock(const ir_node *block) {
811
	ir_node *mbh;
Michael Beck's avatar
Michael Beck committed
812
	assert(is_Block(block));
813
814
815
816
817
	mbh = get_irn_n(block, -1);
	/* once macro block header is respected by all optimizations,
	   this assert can be removed */
	assert(mbh != NULL);
	return mbh;
Michael Beck's avatar
Michael Beck committed
818
819
}

Michael Beck's avatar
Michael Beck committed
820
821
/* returns the macro block header of a node. */
ir_node *get_irn_MacroBlock(const ir_node *n) {
822
	if (! is_Block(n)) {
Michael Beck's avatar
Michael Beck committed
823
		n = get_nodes_block(n);
824
825
		/* if the Block is Bad, do NOT try to get it's MB, it will fail. */
		if (is_Bad(n))
826
			return (ir_node *)n;
827
	}
Michael Beck's avatar
Michael Beck committed
828
829
830
	return get_Block_MacroBlock(n);
}

831
832
833
834
835
836
/* returns the graph of a Block. */
ir_graph *get_Block_irg(const ir_node *block) {
	assert(is_Block(block));
	return block->attr.block.irg;
}

Michael Beck's avatar
Michael Beck committed
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
int has_Block_label(const ir_node *block) {
	assert(is_Block(block));
	return block->attr.block.has_label;
}

ir_label_t get_Block_label(const ir_node *block) {
	assert(is_Block(block));
	return block->attr.block.label;
}

void set_Block_label(ir_node *block, ir_label_t label) {
	assert(is_Block(block));
	block->attr.block.has_label = 1;
	block->attr.block.label = label;
}

853
854
855
856
857
858
859
860
861
ir_node *(get_Block_phis)(const ir_node *block) {
	return _get_Block_phis(block);
}

void (set_Block_phis)(ir_node *block, ir_node *phi) {
	_set_Block_phis(block, phi);
}

int get_End_n_keepalives(const ir_node *end) {