irnode.c 72.8 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
574
	assert(node->op == op_Div || node->op == op_Quot ||
	       node->op == op_DivMod || node->op == op_Mod || node->op == op_Call || node->op == op_Alloc);
575
	return &node->attr.except;
576
577
}

578
579
580
void *(get_irn_generic_attr)(ir_node *node) {
	assert(is_ir_node(node));
	return _get_irn_generic_attr(node);
581
582
}

Matthias Braun's avatar
fix    
Matthias Braun committed
583
const void *(get_irn_generic_attr_const)(const ir_node *node) {
584
585
586
587
	assert(is_ir_node(node));
	return _get_irn_generic_attr_const(node);
}

588
unsigned (get_irn_idx)(const ir_node *node) {
589
590
	assert(is_ir_node(node));
	return _get_irn_idx(node);
591
592
}

593
int get_irn_pred_pos(ir_node *node, ir_node *arg) {
594
595
596
597
598
599
	int i;
	for (i = get_irn_arity(node) - 1; i >= 0; i--) {
		if (get_irn_n(node, i) == arg)
			return i;
	}
	return -1;
600
601
}

Christian Schäfer's avatar
Christian Schäfer committed
602
603
/** manipulate fields of individual nodes **/

604
/* this works for all except Block */
605
ir_node *get_nodes_block(const ir_node *node) {
606
607
	assert(node->op != op_Block);
	return get_irn_n(node, -1);
Christian Schäfer's avatar
Christian Schäfer committed
608
609
}

610
void set_nodes_block(ir_node *node, ir_node *block) {
611
612
	assert(node->op != op_Block);
	set_irn_n(node, -1, block);
Christian Schäfer's avatar
Christian Schäfer committed
613
614
}

Michael Beck's avatar
Michael Beck committed
615
/* this works for all except Block */
616
ir_node *get_nodes_MacroBlock(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
617
618
619
620
	assert(node->op != op_Block);
	return get_Block_MacroBlock(get_irn_n(node, -1));
}

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

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

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

657
658
/* 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. */
659
660
int is_value_arg_pointer(const ir_node *n) {
	if (is_Proj(n) &&
661
		(get_Proj_proj(n) == pn_Start_P_value_arg_base) &&
662
		is_Start(get_Proj_pred(n)))
663
664
		return 1;
	return 0;
665
666
}

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

676
int (get_Block_n_cfgpreds)(const ir_node *node) {
677
	return _get_Block_n_cfgpreds(node);
Christian Schäfer's avatar
Christian Schäfer committed
678
679
}

680
ir_node *(get_Block_cfgpred)(const ir_node *node, int pos) {
681
	return _get_Block_cfgpred(node, pos);
Christian Schäfer's avatar
Christian Schäfer committed
682
683
}

684
void set_Block_cfgpred(ir_node *node, int pos, ir_node *pred) {
685
686
	assert(node->op == op_Block);
	set_irn_n(node, pos, pred);
Christian Schäfer's avatar
Christian Schäfer committed
687
688
}

689
ir_node *(get_Block_cfgpred_block)(const ir_node *node, int pos) {
690
	return _get_Block_cfgpred_block(node, pos);
691
692
}

693
int get_Block_matured(const ir_node *node) {
694
	assert(node->op == op_Block);
Michael Beck's avatar
Michael Beck committed
695
	return (int)node->attr.block.is_matured;
Christian Schäfer's avatar
Christian Schäfer committed
696
697
}

698
void set_Block_matured(ir_node *node, int matured) {
699
	assert(node->op == op_Block);
Michael Beck's avatar
Michael Beck committed
700
	node->attr.block.is_matured = matured;
Christian Schäfer's avatar
Christian Schäfer committed
701
}
Michael Beck's avatar
Michael Beck committed
702

703
unsigned long (get_Block_block_visited)(const ir_node *node) {
704
	return _get_Block_block_visited(node);
Christian Schäfer's avatar
Christian Schäfer committed
705
706
}

707
void (set_Block_block_visited)(ir_node *node, unsigned long visit) {
708
	_set_Block_block_visited(node, visit);
Christian Schäfer's avatar
Christian Schäfer committed
709
710
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
711
/* For this current_ir_graph must be set. */
712
void (mark_Block_block_visited)(ir_node *node) {
713
	_mark_Block_block_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
714
715
}

716
int (Block_not_block_visited)(const ir_node *node) {
717
	return _Block_not_block_visited(node);
718
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
719

720
int (Block_block_visited)(const ir_node *node) {
Matthias Braun's avatar
Matthias Braun committed
721
722
723
	return _Block_block_visited(node);
}

724
ir_node *get_Block_graph_arr(ir_node *node, int pos) {
725
726
	assert(node->op == op_Block);
	return node->attr.block.graph_arr[pos+1];
Christian Schäfer's avatar
Christian Schäfer committed
727
728
}

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

734
#ifdef INTERPROCEDURAL_VIEW
Michael Beck's avatar
Michael Beck committed
735
void set_Block_cg_cfgpred_arr(ir_node *node, int arity, ir_node *in[]) {
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
	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);
751
752
}

Michael Beck's avatar
Michael Beck committed
753
void set_Block_cg_cfgpred(ir_node *node, int pos, ir_node *pred) {
754
755
756
757
	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;
758
759
}

Michael Beck's avatar
Michael Beck committed
760
ir_node **get_Block_cg_cfgpred_arr(ir_node *node) {
761
762
	assert(node->op == op_Block);
	return node->attr.block.in_cg == NULL ? NULL : node->attr.block.in_cg  + 1;
763
764
}

765
int get_Block_cg_n_cfgpreds(const ir_node *node) {
766
767
	assert(node->op == op_Block);
	return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
768
769
}

770
ir_node *get_Block_cg_cfgpred(const ir_node *node, int pos) {
771
772
	assert(node->op == op_Block && node->attr.block.in_cg);
	return node->attr.block.in_cg[pos + 1];
773
774
}

Michael Beck's avatar
Michael Beck committed
775
void remove_Block_cg_cfgpred_arr(ir_node *node) {
776
777
	assert(node->op == op_Block);
	node->attr.block.in_cg = NULL;
778
}
779
#endif
780

781
ir_node *(set_Block_dead)(ir_node *block) {
782
	return _set_Block_dead(block);
783
784
785
}

int (is_Block_dead)(const ir_node *block) {
786
	return _is_Block_dead(block);
787
788
}

789
ir_extblk *get_Block_extbb(const ir_node *block) {
Michael Beck's avatar
Michael Beck committed
790
	ir_extblk *res;
791
	assert(is_Block(block));
Michael Beck's avatar
Michael Beck committed
792
793
	res = block->attr.block.extblk;
	assert(res == NULL || is_ir_extbb(res));
794
	return res;
795
796
797
}

void set_Block_extbb(ir_node *block, ir_extblk *extblk) {
798
	assert(is_Block(block));
Michael Beck's avatar
Michael Beck committed
799
	assert(extblk == NULL || is_ir_extbb(extblk));
800
	block->attr.block.extblk = extblk;
801
802
}

803
/* returns the macro block header of a block. */
Michael Beck's avatar
Michael Beck committed
804
ir_node *get_Block_MacroBlock(const ir_node *block) {
805
	ir_node *mbh;
Michael Beck's avatar
Michael Beck committed
806
	assert(is_Block(block));
807
808
809
810
811
	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
812
813
}

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

825
826
827
828
829
830
/* 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
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
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;
}

847
848
849
850
851
852
853
854
855
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) {
856
857
	assert(end->op == op_End);
	return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
858
859
}

860
ir_node *get_End_keepalive(const ir_node *end, int pos) {
861
862
	assert(end->op == op_End);
	return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
863
864
}