irnode.c 27.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
/**
 * @file
 * @brief   Representation of an intermediate operation.
 * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Michael Beck
Götz Lindenmaier's avatar
Götz Lindenmaier committed
24
 */
Matthias Braun's avatar
Matthias Braun committed
25
#include "config.h"
Michael Beck's avatar
Michael Beck committed
26

27
#include <string.h>
Boris Boesler's avatar
added    
Boris Boesler committed
28

29
#include "pset_new.h"
30
#include "ident.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
31
#include "irnode_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
32
#include "irgraph_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
33
#include "irmode_t.h"
34
#include "irbackedge_t.h"
35
#include "irdump.h"
36
#include "irop_t.h"
37
#include "irprog_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
38
#include "iredgekinds.h"
Sebastian Hack's avatar
Sebastian Hack committed
39
#include "iredges_t.h"
Matthias Braun's avatar
Matthias Braun committed
40
#include "ircons.h"
41
#include "error.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
42

43
#include "irhooks.h"
44
#include "irtools.h"
45
#include "util.h"
Michael Beck's avatar
Michael Beck committed
46

47
48
#include "beinfo.h"

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
#define END_KEEPALIVE_OFFSET  0
Götz Lindenmaier's avatar
Götz Lindenmaier committed
52

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
static const char *relation_names [] = {
	"false",
	"equal",
	"less",
	"less_equal",
	"greater",
	"greater_equal",
	"less_greater",
	"less_equal_greater",
	"unordered",
	"unordered_equal",
	"unordered_less",
	"unordered_less_equal",
	"unordered_greater",
	"unordered_greater_equal",
	"not_equal",
	"true"
70
};
Christian Schäfer's avatar
Christian Schäfer committed
71

72
const char *get_relation_string(ir_relation relation)
73
{
74
75
	assert(relation < (ir_relation)ARRAY_SIZE(relation_names));
	return relation_names[relation];
Christian Schäfer's avatar
Christian Schäfer committed
76
77
}

78
ir_relation get_negated_relation(ir_relation relation)
79
{
80
	return relation ^ ir_relation_true;
Christian Schäfer's avatar
Christian Schäfer committed
81
82
}

83
ir_relation get_inversed_relation(ir_relation relation)
84
{
85
86
87
	ir_relation code    = relation & ~(ir_relation_less|ir_relation_greater);
	bool        less    = relation & ir_relation_less;
	bool        greater = relation & ir_relation_greater;
88
89
	code |= (less ? ir_relation_greater : ir_relation_false)
	      | (greater ? ir_relation_less : ir_relation_false);
90
	return code;
Michael Beck's avatar
Michael Beck committed
91
92
}

93
ir_node *new_ir_node(dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op,
94
                     ir_mode *mode, int arity, ir_node *const *in)
Christian Schäfer's avatar
Christian Schäfer committed
95
{
96
	int i;
97

Christoph Mallon's avatar
Christoph Mallon committed
98
99
100
	assert(irg);
	assert(op);
	assert(mode);
101
102

	size_t   const node_size = offsetof(ir_node, attr) + op->attr_size;
103
	ir_node *const res       = (ir_node*)OALLOCNZ(get_irg_obstack(irg), char, node_size);
104
105
106
107
108
109
110
111
112
113

	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) {
114
		res->in = NEW_ARR_F(ir_node *, 1);  /* 1: space for block */
115
	} else {
116
117
		/* not nice but necessary: End and Sync must always have a flexible array */
		if (op == op_End || op == op_Sync)
118
119
			res->in = NEW_ARR_F(ir_node *, (arity+1));
		else
120
			res->in = NEW_ARR_D(ir_node*, get_irg_obstack(irg), arity + 1);
121
		memcpy(&res->in[1], in, sizeof(ir_node *) * arity);
122
123
	}

124
	res->in[0]   = block;
125
126
	set_irn_dbg_info(res, db);
	res->node_nr = get_irp_new_node_nr();
Götz Lindenmaier's avatar
Götz Lindenmaier committed
127

Michael Beck's avatar
Michael Beck committed
128
	for (i = 0; i < EDGE_KIND_LAST; ++i) {
129
		INIT_LIST_HEAD(&res->edge_info[i].outs_head);
Michael Beck's avatar
Michael Beck committed
130
131
132
133
		/* edges will be build immediately */
		res->edge_info[i].edges_built = 1;
		res->edge_info[i].out_count = 0;
	}
134

135
	/* don't put this into the for loop, arity is -1 for some nodes! */
Matthias Braun's avatar
Matthias Braun committed
136
137
	if (block != NULL)
		edges_notify_edge(res, -1, block, NULL, irg);
138
	for (i = 1; i <= arity; ++i)
139
		edges_notify_edge(res, i - 1, res->in[i], NULL, irg);
Sebastian Hack's avatar
Sebastian Hack committed
140

141
	hook_new_node(irg, res);
142
	if (irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
143
		be_info_new_node(irg, res);
144
	}
Michael Beck's avatar
Michael Beck committed
145

146
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
147
148
}

149
150
int (is_ir_node)(const void *thing)
{
151
	return is_ir_node_(thing);
Sebastian Felis's avatar
Sebastian Felis committed
152
153
}

154
155
int (get_irn_arity)(const ir_node *node)
{
156
	return get_irn_arity_(node);
157
158
}

159
160
ir_node **get_irn_in(const ir_node *node)
{
161
162
163
	return node->in;
}

164
165
void set_irn_in(ir_node *node, int arity, ir_node **in)
{
166
	int i;
Michael Beck's avatar
Michael Beck committed
167
	ir_node *** pOld_in;
168
	ir_graph *irg = get_irn_irg(node);
169

170
	pOld_in = &node->in;
171

172
173
174
175
176
177
178
#ifndef NDEBUG
	assert(node != NULL && node->kind == k_ir_node);
	assert(arity >= 0);
	for (i = 0; i < arity; ++i) {
		assert(in[i] != NULL && in[0]->kind == k_ir_node);
	}
#endif
179
180

	for (i = 0; i < arity; i++) {
181
		if (i < (int)ARR_LEN(*pOld_in)-1)
Michael Beck's avatar
Michael Beck committed
182
			edges_notify_edge(node, i, in[i], (*pOld_in)[i+1], irg);
183
		else
Michael Beck's avatar
Michael Beck committed
184
			edges_notify_edge(node, i, in[i], NULL,            irg);
185
	}
186
	for (;i < (int)ARR_LEN(*pOld_in)-1; i++) {
Michael Beck's avatar
Michael Beck committed
187
		edges_notify_edge(node, i, NULL, (*pOld_in)[i+1], irg);
188
189
	}

190
	if (arity != (int)ARR_LEN(*pOld_in) - 1) {
Michael Beck's avatar
Michael Beck committed
191
		ir_node * block = (*pOld_in)[0];
192
		*pOld_in = NEW_ARR_D(ir_node*, get_irg_obstack(irg), arity + 1);
Michael Beck's avatar
Michael Beck committed
193
		(*pOld_in)[0] = block;
194
	}
195
	fix_backedges(get_irg_obstack(irg), node);
196

Michael Beck's avatar
Michael Beck committed
197
	memcpy((*pOld_in) + 1, in, sizeof(ir_node *) * arity);
198
199

	/* update irg flags */
200
	clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
201
202
}

203
204
ir_node *(get_irn_n)(const ir_node *node, int n)
{
205
	return get_irn_n_(node, n);
Christian Schäfer's avatar
Christian Schäfer committed
206
207
}

208
209
void set_irn_n(ir_node *node, int n, ir_node *in)
{
210
	ir_graph *irg = get_irn_irg(node);
211
212
213
214
215
216
217
218
219
	assert(node && node->kind == k_ir_node);
	assert(-1 <= n);
	assert(n < get_irn_arity(node));
	assert(in && in->kind == k_ir_node);

	/* 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 */
220
	edges_notify_edge(node, n, in, node->in[n + 1], irg);
221
222

	node->in[n + 1] = in;
223
224

	/* update irg flags */
225
	clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
Christian Schäfer's avatar
Christian Schäfer committed
226
227
}

228
229
int add_irn_n(ir_node *node, ir_node *in)
{
230
231
232
233
234
235
236
237
	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);

238
239
240
	/* Call the hook */
	hook_set_irn_n(node, pos, node->in[pos + 1], NULL);

Matthias Braun's avatar
Matthias Braun committed
241
242
243
	/* update irg flags */
	clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);

244
245
246
	return pos;
}

Matthias Braun's avatar
Matthias Braun committed
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
static void del_irn_n(ir_node *node, int n)
{
	ir_graph *irg = get_irn_irg(node);

	/* remove the edge */
	ir_node *pred = node->in[n+1];
	edges_notify_edge(node, n, NULL, pred, irg);

	int arity = get_irn_arity(node);
	if (n != arity-1) {
		/* exchange with the last one */
		ir_node *old = node->in[arity];
		edges_notify_edge(node, arity-1, NULL, old, irg);
		node->in[n+1] = old;
		edges_notify_edge(node, n, old, NULL, irg);
	}
	ARR_SHRINKLEN(node->in, arity);

	/* update irg flags */
	clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
}

Christoph Mallon's avatar
Christoph Mallon committed
269
270
void del_Sync_n(ir_node *n, int i)
{
Matthias Braun's avatar
Matthias Braun committed
271
	del_irn_n(n, i);
Christoph Mallon's avatar
Christoph Mallon committed
272
273
}

274
275
int (get_irn_deps)(const ir_node *node)
{
276
	return get_irn_deps_(node);
Sebastian Hack's avatar
Sebastian Hack committed
277
278
}

279
280
ir_node *(get_irn_dep)(const ir_node *node, int pos)
{
281
	return get_irn_dep_(node, pos);
Sebastian Hack's avatar
Sebastian Hack committed
282
283
}

284
void set_irn_dep(ir_node *node, int pos, ir_node *dep)
285
{
286
287
288
289
290
291
292
293
294
295
296
	ir_node *old;
	ir_graph *irg;

	assert(node->deps && "dependency array node yet allocated. use add_irn_dep()");
	assert(pos >= 0 && pos < (int)ARR_LEN(node->deps) && "dependency index out of range");
	assert(dep != NULL);
	old = node->deps[pos];
	node->deps[pos] = dep;
	irg = get_irn_irg(node);
	if (edges_activated_kind(irg, EDGE_KIND_DEP))
		edges_notify_edge_kind(node, pos, dep, old, EDGE_KIND_DEP, irg);
Sebastian Hack's avatar
Sebastian Hack committed
297
298
}

299
void add_irn_dep(ir_node *node, ir_node *dep)
300
{
301
	ir_graph *irg;
302
	assert(dep != NULL);
Sebastian Hack's avatar
Sebastian Hack committed
303
	if (node->deps == NULL) {
304
305
306
		node->deps = NEW_ARR_F(ir_node *, 0);
	}
	ARR_APP1(ir_node*, node->deps, dep);
307
308
309
	irg = get_irn_irg(node);
	if (edges_activated_kind(irg, EDGE_KIND_DEP))
		edges_notify_edge_kind(node, ARR_LEN(node->deps)-1, dep, NULL, EDGE_KIND_DEP, irg);
310
}
Sebastian Hack's avatar
Sebastian Hack committed
311

312
313
314
315
316
317
318
319
320
321
322
323
324
325
void delete_irn_dep(ir_node *node, ir_node *dep)
{
	size_t i;
	size_t n_deps;
	if (node->deps == NULL)
		return;

	n_deps = ARR_LEN(node->deps);
	for (i = 0; i < n_deps; ++i) {
		if (node->deps[i] == dep) {
			set_irn_dep(node, i, node->deps[n_deps-1]);
			edges_notify_edge(node, i, NULL, dep, get_irn_irg(node));
			ARR_SHRINKLEN(node->deps, n_deps-1);
			break;
Sebastian Hack's avatar
Sebastian Hack committed
326
327
328
329
		}
	}
}

330
331
void add_irn_deps(ir_node *tgt, ir_node *src)
{
Sebastian Hack's avatar
Sebastian Hack committed
332
333
	int i, n;

334
	for (i = 0, n = get_irn_deps(src); i < n; ++i)
Sebastian Hack's avatar
Sebastian Hack committed
335
336
337
338
		add_irn_dep(tgt, get_irn_dep(src, i));
}


339
340
ir_mode *(get_irn_mode)(const ir_node *node)
{
341
	return get_irn_mode_(node);
Christian Schäfer's avatar
Christian Schäfer committed
342
343
}

344
345
void (set_irn_mode)(ir_node *node, ir_mode *mode)
{
346
	set_irn_mode_(node, mode);
Till Riedel's avatar
Till Riedel committed
347
348
}

349
350
ir_op *(get_irn_op)(const ir_node *node)
{
351
	return get_irn_op_(node);
Christian Schäfer's avatar
Christian Schäfer committed
352
353
}

354
355
void (set_irn_op)(ir_node *node, ir_op *op)
{
356
	set_irn_op_(node, op);
Christian Schäfer's avatar
Christian Schäfer committed
357
358
}

359
360
unsigned (get_irn_opcode)(const ir_node *node)
{
361
	return get_irn_opcode_(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
362
363
}

364
365
const char *get_irn_opname(const ir_node *node)
{
366
	return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
367
368
}

369
370
ident *get_irn_opident(const ir_node *node)
{
371
372
	assert(node);
	return node->op->name;
373
374
}

375
376
ir_visited_t (get_irn_visited)(const ir_node *node)
{
377
	return get_irn_visited_(node);
378
379
}

380
381
void (set_irn_visited)(ir_node *node, ir_visited_t visited)
{
382
	set_irn_visited_(node, visited);
Christian Schäfer's avatar
Christian Schäfer committed
383
}
384

385
386
void (mark_irn_visited)(ir_node *node)
{
387
	mark_irn_visited_(node);
388
389
}

390
391
int (irn_visited)(const ir_node *node)
{
392
	return irn_visited_(node);
393
394
}

395
396
int (irn_visited_else_mark)(ir_node *node)
{
397
	return irn_visited_else_mark_(node);
398
399
}

400
401
void (set_irn_link)(ir_node *node, void *link)
{
402
	set_irn_link_(node, link);
Christian Schäfer's avatar
Christian Schäfer committed
403
404
}

405
406
void *(get_irn_link)(const ir_node *node)
{
407
	return get_irn_link_(node);
Christian Schäfer's avatar
Christian Schäfer committed
408
409
}

410
411
op_pin_state (get_irn_pinned)(const ir_node *node)
{
412
	return get_irn_pinned_(node);
413
414
}

415
416
op_pin_state (is_irn_pinned_in_irg) (const ir_node *node)
{
417
	return is_irn_pinned_in_irg_(node);
418
419
}

420
421
void set_irn_pinned(ir_node *node, op_pin_state state)
{
422
	/* due to optimization an opt may be turned into a Tuple */
423
	if (is_Tuple(node))
424
		return;
Michael Beck's avatar
Michael Beck committed
425

426
427
	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
428

429
	node->attr.except.pin_state = state;
Michael Beck's avatar
Michael Beck committed
430
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
431

432
433
long get_irn_node_nr(const ir_node *node)
{
434
435
	assert(node);
	return node->node_nr;
436
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
437

438
439
void *(get_irn_generic_attr)(ir_node *node)
{
440
	assert(is_ir_node(node));
441
	return get_irn_generic_attr_(node);
442
443
}

444
445
const void *(get_irn_generic_attr_const)(const ir_node *node)
{
446
	assert(is_ir_node(node));
447
	return get_irn_generic_attr_const_(node);
448
449
}

450
451
unsigned (get_irn_idx)(const ir_node *node)
{
452
	assert(is_ir_node(node));
453
	return get_irn_idx_(node);
454
455
}

456
ir_node *(get_nodes_block)(const ir_node *node)
457
{
458
	return get_nodes_block_(node);
Christian Schäfer's avatar
Christian Schäfer committed
459
460
}

461
462
void set_nodes_block(ir_node *node, ir_node *block)
{
463
	assert(!is_Block(node));
464
	set_irn_n(node, -1, block);
Christian Schäfer's avatar
Christian Schäfer committed
465
466
}

467
468
ir_type *is_frame_pointer(const ir_node *n)
{
469
470
	if (is_Proj(n) && (get_Proj_proj(n) == pn_Start_P_frame_base)) {
		ir_node *start = get_Proj_pred(n);
471
		if (is_Start(start)) {
472
473
474
475
			return get_irg_frame_type(get_irn_irg(start));
		}
	}
	return NULL;
476
477
}

478
479
int get_Block_cfgpred_pos(const ir_node *block, const ir_node *pred)
{
480
481
482
483
484
485
486
487
488
	int i;

	for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
		if (get_Block_cfgpred_block(block, i) == pred)
			return i;
	}
	return -1;
}

489
490
ir_node *(get_Block_cfgpred_block)(const ir_node *node, int pos)
{
491
	return get_Block_cfgpred_block_(node, pos);
492
493
}

494
495
int get_Block_matured(const ir_node *node)
{
496
	assert(is_Block(node));
Michael Beck's avatar
Michael Beck committed
497
	return (int)node->attr.block.is_matured;
Christian Schäfer's avatar
Christian Schäfer committed
498
499
}

500
501
void set_Block_matured(ir_node *node, int matured)
{
502
	assert(is_Block(node));
Michael Beck's avatar
Michael Beck committed
503
	node->attr.block.is_matured = matured;
Christian Schäfer's avatar
Christian Schäfer committed
504
}
Michael Beck's avatar
Michael Beck committed
505

506
507
ir_visited_t (get_Block_block_visited)(const ir_node *node)
{
508
	return get_Block_block_visited_(node);
Christian Schäfer's avatar
Christian Schäfer committed
509
510
}

511
512
void (set_Block_block_visited)(ir_node *node, ir_visited_t visit)
{
513
	set_Block_block_visited_(node, visit);
Christian Schäfer's avatar
Christian Schäfer committed
514
515
}

516
517
void (mark_Block_block_visited)(ir_node *node)
{
518
	mark_Block_block_visited_(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
519
520
}

521
522
int (Block_block_visited)(const ir_node *node)
{
523
	return Block_block_visited_(node);
Matthias Braun's avatar
Matthias Braun committed
524
525
}

526
527
ir_graph *(get_Block_irg)(const ir_node *block)
{
528
	return get_Block_irg_(block);
529
530
}

531
532
ir_entity *create_Block_entity(ir_node *block)
{
533
	ir_entity *entity;
Michael Beck's avatar
Michael Beck committed
534
	assert(is_Block(block));
535
536
537

	entity = block->attr.block.entity;
	if (entity == NULL) {
Matthias Braun's avatar
Matthias Braun committed
538
539
		ir_label_t nr = get_irp_next_label_nr();
		entity = new_label_entity(nr);
540
541
		set_entity_visibility(entity, ir_visibility_local);
		set_entity_linkage(entity, IR_LINKAGE_CONSTANT);
542
543
544
545
546
		set_entity_compiler_generated(entity, 1);

		block->attr.block.entity = entity;
	}
	return entity;
Michael Beck's avatar
Michael Beck committed
547
548
}

549
550
ir_node *(get_Block_phis)(const ir_node *block)
{
551
	return get_Block_phis_(block);
552
553
}

554
555
void (set_Block_phis)(ir_node *block, ir_node *phi)
{
556
	set_Block_phis_(block, phi);
557
558
}

559
560
void (add_Block_phi)(ir_node *block, ir_node *phi)
{
561
	add_Block_phi_(block, phi);
Michael Beck's avatar
Michael Beck committed
562
563
}

564
565
unsigned (get_Block_mark)(const ir_node *block)
{
566
	return get_Block_mark_(block);
Michael Beck's avatar
Michael Beck committed
567
568
}

569
570
void (set_Block_mark)(ir_node *block, unsigned mark)
{
571
	set_Block_mark_(block, mark);
Michael Beck's avatar
Michael Beck committed
572
573
}

574
575
void add_End_keepalive(ir_node *end, ir_node *ka)
{
576
	assert(is_End(end));
577
	add_irn_n(end, ka);
578
579
}

580
581
void set_End_keepalives(ir_node *end, int n, ir_node *in[])
{
582
583
	size_t e;
	int    i;
584
	ir_graph *irg = get_irn_irg(end);
585

586
	/* notify that edges are deleted */
587
588
	for (e = END_KEEPALIVE_OFFSET; e < ARR_LEN(end->in) - 1; ++e) {
		edges_notify_edge(end, e, NULL, end->in[e + 1], irg);
589
590
	}
	ARR_RESIZE(ir_node *, end->in, n + 1 + END_KEEPALIVE_OFFSET);
591

592
593
	for (i = 0; i < n; ++i) {
		end->in[1 + END_KEEPALIVE_OFFSET + i] = in[i];
594
		edges_notify_edge(end, END_KEEPALIVE_OFFSET + i, end->in[1 + END_KEEPALIVE_OFFSET + i], NULL, irg);
595
	}
596
597

	/* update irg flags */
598
	clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
599
}
600

601
602
void remove_End_keepalive(ir_node *end, ir_node *irn)
{
Matthias Braun's avatar
Matthias Braun committed
603
	int n = get_End_n_keepalives(end);
Christoph Mallon's avatar
Christoph Mallon committed
604
605
606
607
608
	int idx = -1;
	for (int i = n;;) {
		if (i-- == 0)
			return;

609
610
611
612
		ir_node *old_ka = end->in[1 + END_KEEPALIVE_OFFSET + i];

		/* find irn */
		if (old_ka == irn) {
Matthias Braun's avatar
Matthias Braun committed
613
			idx = END_KEEPALIVE_OFFSET + i;
Christoph Mallon's avatar
Christoph Mallon committed
614
			break;
615
		}
616
	}
Matthias Braun's avatar
Matthias Braun committed
617
618
	assert(idx != -1);
	del_irn_n(end, idx);
619
}
620

621
622
void remove_End_Bads_and_doublets(ir_node *end)
{
623
624
625
	pset_new_t keeps;
	int        idx, n = get_End_n_keepalives(end);
	ir_graph   *irg;
626
	bool       changed = false;
627
628
629
630
631
632
633
634
635
636

	if (n <= 0)
		return;

	irg = get_irn_irg(end);
	pset_new_init(&keeps);

	for (idx = n - 1; idx >= 0; --idx) {
		ir_node *ka = get_End_keepalive(end, idx);

Michael Beck's avatar
Michael Beck committed
637
		if (is_Bad(ka) || is_NoMem(ka) || pset_new_contains(&keeps, ka)) {
638
			changed = true;
Matthias Braun's avatar
Matthias Braun committed
639
			del_irn_n(end, idx - END_KEEPALIVE_OFFSET);
640
641
642
643
644
645
			--n;
		} else {
			pset_new_insert(&keeps, ka);
		}
	}
	pset_new_destroy(&keeps);
646
647

	if (changed) {
648
		clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
649
	}
650
651
}

652
653
void free_End(ir_node *end)
{
654
	assert(is_End(end));
655
656
657
658
	end->kind = k_BAD;
	DEL_ARR_F(end->in);
	end->in = NULL;   /* @@@ make sure we get an error if we use the
	                     in array afterwards ... */
659
660
}

661
662
int (is_Const_null)(const ir_node *node)
{
663
	return is_Const_null_(node);
664
665
}

666
667
int (is_Const_one)(const ir_node *node)
{
668
	return is_Const_one_(node);
669
670
}

671
672
int (is_Const_all_one)(const ir_node *node)
{
673
	return is_Const_all_one_(node);
Sebastian Hack's avatar
Sebastian Hack committed
674
675
}

676
677


678
symconst_kind get_SymConst_kind(const ir_node *node)
679
{
680
	assert(is_SymConst(node));
681
	return node->attr.symc.kind;
Christian Schäfer's avatar
Christian Schäfer committed
682
683
}

684
void set_SymConst_kind(ir_node *node, symconst_kind kind)
685
{
686
	assert(is_SymConst(node));
687
	node->attr.symc.kind = kind;
Christian Schäfer's avatar
Christian Schäfer committed
688
689
}

690
ir_type *get_SymConst_type(const ir_node *node)
691
{
Michael Beck's avatar
Michael Beck committed
692
693
694
	/* the cast here is annoying, but we have to compensate for
	   the skip_tip() */
	ir_node *irn = (ir_node *)node;
695
	assert(is_SymConst(node) &&
696
	       (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
Matthias Braun's avatar
Matthias Braun committed
697
	return irn->attr.symc.sym.type_p;
Christian Schäfer's avatar
Christian Schäfer committed
698
699
}

700
void set_SymConst_type(ir_node *node, ir_type *tp)
701
{
702
	assert(is_SymConst(node) &&
703
704
	       (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
	node->attr.symc.sym.type_p = tp;
Christian Schäfer's avatar
Christian Schäfer committed
705
706
}

707
708
ir_entity *get_SymConst_entity(const ir_node *node)
{
709
	assert(is_SymConst(node) && SYMCONST_HAS_ENT(get_SymConst_kind(node)));
710
	return node->attr.symc.sym.entity_p;
Beyhan's avatar
Beyhan committed
711
712
}

713
714
void set_SymConst_entity(ir_node *node, ir_entity *ent)
{
715
	assert(is_SymConst(node) && SYMCONST_HAS_ENT(get_SymConst_kind(node)));
716
	node->attr.symc.sym.entity_p  = ent;
Beyhan's avatar
Beyhan committed
717
718
}

719
720
ir_enum_const *get_SymConst_enum(const ir_node *node)
{
721
	assert(is_SymConst(node) && SYMCONST_HAS_ENUM(get_SymConst_kind(node)));
722
	return node->attr.symc.sym.enum_p;
723
724
}

725
726
void set_SymConst_enum(ir_node *node, ir_enum_const *ec)
{
727
	assert(is_SymConst(node) && SYMCONST_HAS_ENUM(get_SymConst_kind(node)));
728
	node->attr.symc.sym.enum_p  = ec;
729
730
}

Michael Beck's avatar
Michael Beck committed
731
union symconst_symbol
732
733
get_SymConst_symbol(const ir_node *node)
{
734
	assert(is_SymConst(node));
735
	return node->attr.symc.sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
736
737
}

738
void set_SymConst_symbol(ir_node *node, union symconst_symbol sym)
739
{
740
	assert(is_SymConst(node));
741
	node->attr.symc.sym = sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
742
743
}

744
745
const char *get_builtin_kind_name(ir_builtin_kind kind)
{
746
#define X(a)    case a: return #a
747
	switch (kind) {
Michael Beck's avatar
Michael Beck committed
748
		X(ir_bk_trap);
749
		X(ir_bk_debugbreak);
750
		X(ir_bk_return_address);
751
		X(ir_bk_frame_address);
752
		X(ir_bk_prefetch);
Michael Beck's avatar
Michael Beck committed
753
754
755
756
757
758
		X(ir_bk_ffs);
		X(ir_bk_clz);
		X(ir_bk_ctz);
		X(ir_bk_popcount);
		X(ir_bk_parity);
		X(ir_bk_bswap);
759
760
		X(ir_bk_inport);
		X(ir_bk_outport);
761
		X(ir_bk_inner_trampoline);
762
763
764
765
766
767
	}
	return "<unknown>";
#undef X
}


768
769
int Call_has_callees(const ir_node *node)
{
770
	assert(is_Call(node));
771
772
	return ((get_irg_callee_info_state(get_irn_irg(node)) != irg_callee_info_none) &&
	        (node->attr.call.callee_arr != NULL));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
773
774
}

775
size_t get_Call_n_callees(const ir_node *node)
776
{
777
  assert(is_Call(node) && node->attr.call.callee_arr);
778
779
780
  return ARR_LEN(node->attr.call.callee_arr);
}

781
ir_entity *get_Call_callee(const ir_node *node, size_t pos)
782
{
783
	assert(pos < get_Call_n_callees(node));
784
	return node->attr.call.callee_arr[pos];
785
786
}

787
void set_Call_callee_arr(ir_node *node, size_t n, ir_entity ** arr)
788
{
789
	assert(is_Call(node));
790
	if (node->attr.call.callee_arr == NULL || get_Call_n_callees(node) != n) {
791
792
		ir_graph *const irg = get_irn_irg(node);
		node->attr.call.callee_arr = NEW_ARR_D(ir_entity*, get_irg_obstack(irg), n);
793
794
	}
	memcpy(node->attr.call.callee_arr, arr, n * sizeof(ir_entity *));
795
796
}

797
798
void remove_Call_callee_arr(ir_node *node)
{
799
	assert(is_Call(node));
800
	node->attr.call.callee_arr = NULL;
801
802
}

803
804
int (is_unop)(const ir_node *node)
{
805
	return is_unop_(node);
806
807
}

808
ir_node *get_unop_op(const ir_node *node)
809
{
810
811
	if (node->op->opar == oparity_unary)
		return get_irn_n(node, node->op->op_index);
812

813
814
	assert(node->op->opar == oparity_unary);
	return NULL;
815
816
}

817
void set_unop_op(ir_node *node, ir_node *op)
818
{
819
820
	if (node->op->opar == oparity_unary)
		set_irn_n(node, node->op->op_index, op);
821

822
	assert(node->op->opar == oparity_unary);
823
824
}

825
826
int (is_binop)(const ir_node *node)
{
827
	return is_binop_(node);
828
829
}

830
ir_node *get_binop_left(const ir_node *node)
831
{
832
833
	assert(node->op->opar == oparity_binary);
	return get_irn_n(node, node->op->op_index);
834
835
}

836
void set_binop_left(ir_node *node, ir_node *left)
837
{
838
839
	assert(node->op->opar == oparity_binary);
	set_irn_n(node, node->op->op_index, left);
Götz Lindenmaier's avatar