irnode.c 26.1 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

Matthias Braun's avatar
Matthias Braun committed
6
7
8
9
/**
 * @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
10
 */
11
#include <string.h>
Boris Boesler's avatar
added    
Boris Boesler committed
12

13
#include "pset_new.h"
14
#include "ident.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
15
#include "irnode_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
16
#include "irgraph_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
17
#include "irmode_t.h"
18
#include "irbackedge_t.h"
19
#include "irdump.h"
20
#include "irop_t.h"
21
#include "irprog_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
22
#include "iredgekinds.h"
Sebastian Hack's avatar
Sebastian Hack committed
23
#include "iredges_t.h"
Matthias Braun's avatar
Matthias Braun committed
24
#include "ircons.h"
25
#include "error.h"
26
#include "irverify.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
27

28
#include "irhooks.h"
29
#include "util.h"
Michael Beck's avatar
Michael Beck committed
30

31
32
#include "beinfo.h"

Götz Lindenmaier's avatar
Götz Lindenmaier committed
33
34
/* some constants fixing the positions of nodes predecessors
   in the in array */
Michael Beck's avatar
Michael Beck committed
35
#define END_KEEPALIVE_OFFSET  0
Götz Lindenmaier's avatar
Götz Lindenmaier committed
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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"
54
};
Christian Schäfer's avatar
Christian Schäfer committed
55

56
const char *get_relation_string(ir_relation relation)
57
{
58
59
	assert(relation < (ir_relation)ARRAY_SIZE(relation_names));
	return relation_names[relation];
Christian Schäfer's avatar
Christian Schäfer committed
60
61
}

62
ir_relation get_negated_relation(ir_relation relation)
63
{
64
	return relation ^ ir_relation_true;
Christian Schäfer's avatar
Christian Schäfer committed
65
66
}

67
ir_relation get_inversed_relation(ir_relation relation)
68
{
69
70
71
	ir_relation code    = relation & ~(ir_relation_less|ir_relation_greater);
	bool        less    = relation & ir_relation_less;
	bool        greater = relation & ir_relation_greater;
72
73
	code |= (less ? ir_relation_greater : ir_relation_false)
	      | (greater ? ir_relation_less : ir_relation_false);
74
	return code;
Michael Beck's avatar
Michael Beck committed
75
76
}

77
ir_node *new_ir_node(dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op,
78
                     ir_mode *mode, int arity, ir_node *const *in)
Christian Schäfer's avatar
Christian Schäfer committed
79
{
Christoph Mallon's avatar
Christoph Mallon committed
80
81
82
	assert(irg);
	assert(op);
	assert(mode);
83
84

	size_t   const node_size = offsetof(ir_node, attr) + op->attr_size;
85
	ir_node *const res       = (ir_node*)OALLOCNZ(get_irg_obstack(irg), char, node_size);
86
87
88
89
90
91
92
93
94
95

	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) {
96
		res->in = NEW_ARR_F(ir_node *, 1);  /* 1: space for block */
97
	} else {
98
99
		/* not nice but necessary: End and Sync must always have a flexible array */
		if (op == op_End || op == op_Sync)
100
101
			res->in = NEW_ARR_F(ir_node *, (arity+1));
		else
102
			res->in = NEW_ARR_D(ir_node*, get_irg_obstack(irg), arity + 1);
103
		memcpy(&res->in[1], in, sizeof(ir_node *) * arity);
104
105
	}

106
	res->in[0]   = block;
107
108
	set_irn_dbg_info(res, db);
	res->node_nr = get_irp_new_node_nr();
Götz Lindenmaier's avatar
Götz Lindenmaier committed
109

110
	for (ir_edge_kind_t i = EDGE_KIND_FIRST; i <= EDGE_KIND_LAST; ++i) {
111
		INIT_LIST_HEAD(&res->edge_info[i].outs_head);
Michael Beck's avatar
Michael Beck committed
112
113
114
115
		/* edges will be build immediately */
		res->edge_info[i].edges_built = 1;
		res->edge_info[i].out_count = 0;
	}
116

117
	/* don't put this into the for loop, arity is -1 for some nodes! */
Matthias Braun's avatar
Matthias Braun committed
118
119
	if (block != NULL)
		edges_notify_edge(res, -1, block, NULL, irg);
120
121
	for (int i = 0; i < arity; ++i)
		edges_notify_edge(res, i, res->in[i+1], NULL, irg);
Sebastian Hack's avatar
Sebastian Hack committed
122

123
	hook_new_node(irg, res);
124
	if (irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
125
		be_info_new_node(irg, res);
126
	}
Michael Beck's avatar
Michael Beck committed
127

128
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
129
130
}

131
132
int (is_ir_node)(const void *thing)
{
133
	return is_ir_node_(thing);
Sebastian Felis's avatar
Sebastian Felis committed
134
135
}

136
137
int (get_irn_arity)(const ir_node *node)
{
138
	return get_irn_arity_(node);
139
140
}

141
142
ir_node **get_irn_in(const ir_node *node)
{
143
144
145
	return node->in;
}

146
void set_irn_in(ir_node *const node, int const arity, ir_node *const *const in)
147
{
148
	int i;
Michael Beck's avatar
Michael Beck committed
149
	ir_node *** pOld_in;
150
	ir_graph *irg = get_irn_irg(node);
151

152
	pOld_in = &node->in;
153

154
155
156
157
158
159
160
#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
161
162

	for (i = 0; i < arity; i++) {
163
		if (i < (int)ARR_LEN(*pOld_in)-1)
Michael Beck's avatar
Michael Beck committed
164
			edges_notify_edge(node, i, in[i], (*pOld_in)[i+1], irg);
165
		else
Michael Beck's avatar
Michael Beck committed
166
			edges_notify_edge(node, i, in[i], NULL,            irg);
167
	}
168
	for (;i < (int)ARR_LEN(*pOld_in)-1; i++) {
Michael Beck's avatar
Michael Beck committed
169
		edges_notify_edge(node, i, NULL, (*pOld_in)[i+1], irg);
170
171
	}

172
	if (arity != (int)ARR_LEN(*pOld_in) - 1) {
Michael Beck's avatar
Michael Beck committed
173
		ir_node * block = (*pOld_in)[0];
174
		*pOld_in = NEW_ARR_D(ir_node*, get_irg_obstack(irg), arity + 1);
Michael Beck's avatar
Michael Beck committed
175
		(*pOld_in)[0] = block;
176
	}
177
	fix_backedges(get_irg_obstack(irg), node);
178

Michael Beck's avatar
Michael Beck committed
179
	memcpy((*pOld_in) + 1, in, sizeof(ir_node *) * arity);
180
181

	/* update irg flags */
182
	clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
183
184
}

185
186
ir_node *(get_irn_n)(const ir_node *node, int n)
{
187
	return get_irn_n_(node, n);
Christian Schäfer's avatar
Christian Schäfer committed
188
189
}

190
191
void set_irn_n(ir_node *node, int n, ir_node *in)
{
192
	ir_graph *irg = get_irn_irg(node);
193
194
195
196
197
198
199
200
201
	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 */
202
	edges_notify_edge(node, n, in, node->in[n + 1], irg);
203
204

	node->in[n + 1] = in;
205
206

	/* update irg flags */
207
	clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
Christian Schäfer's avatar
Christian Schäfer committed
208
209
}

210
211
int add_irn_n(ir_node *node, ir_node *in)
{
212
213
214
215
216
217
218
219
	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);

220
221
222
	/* Call the hook */
	hook_set_irn_n(node, pos, node->in[pos + 1], NULL);

Matthias Braun's avatar
Matthias Braun committed
223
224
225
	/* update irg flags */
	clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);

226
227
228
	return pos;
}

Matthias Braun's avatar
Matthias Braun committed
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
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
251
252
void del_Sync_n(ir_node *n, int i)
{
Matthias Braun's avatar
Matthias Braun committed
253
	del_irn_n(n, i);
Christoph Mallon's avatar
Christoph Mallon committed
254
255
}

256
257
int (get_irn_deps)(const ir_node *node)
{
258
	return get_irn_deps_(node);
Sebastian Hack's avatar
Sebastian Hack committed
259
260
}

261
262
ir_node *(get_irn_dep)(const ir_node *node, int pos)
{
263
	return get_irn_dep_(node, pos);
Sebastian Hack's avatar
Sebastian Hack committed
264
265
}

266
void set_irn_dep(ir_node *node, int pos, ir_node *dep)
267
{
268
269
270
271
272
273
274
275
276
277
278
	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
279
280
}

281
void add_irn_dep(ir_node *node, ir_node *dep)
282
{
283
	ir_graph *irg;
284
	assert(dep != NULL);
Sebastian Hack's avatar
Sebastian Hack committed
285
	if (node->deps == NULL) {
286
287
288
		node->deps = NEW_ARR_F(ir_node *, 0);
	}
	ARR_APP1(ir_node*, node->deps, dep);
289
290
291
	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);
292
}
Sebastian Hack's avatar
Sebastian Hack committed
293

294
295
296
297
298
299
300
301
302
303
304
305
306
307
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
308
309
310
311
		}
	}
}

312
313
void add_irn_deps(ir_node *tgt, ir_node *src)
{
Sebastian Hack's avatar
Sebastian Hack committed
314
315
	int i, n;

316
	for (i = 0, n = get_irn_deps(src); i < n; ++i)
Sebastian Hack's avatar
Sebastian Hack committed
317
318
319
320
		add_irn_dep(tgt, get_irn_dep(src, i));
}


321
322
ir_mode *(get_irn_mode)(const ir_node *node)
{
323
	return get_irn_mode_(node);
Christian Schäfer's avatar
Christian Schäfer committed
324
325
}

326
327
void (set_irn_mode)(ir_node *node, ir_mode *mode)
{
328
	set_irn_mode_(node, mode);
Till Riedel's avatar
Till Riedel committed
329
330
}

331
332
ir_op *(get_irn_op)(const ir_node *node)
{
333
	return get_irn_op_(node);
Christian Schäfer's avatar
Christian Schäfer committed
334
335
}

336
337
void (set_irn_op)(ir_node *node, ir_op *op)
{
338
	set_irn_op_(node, op);
Christian Schäfer's avatar
Christian Schäfer committed
339
340
}

341
342
unsigned (get_irn_opcode)(const ir_node *node)
{
343
	return get_irn_opcode_(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
344
345
}

346
347
const char *get_irn_opname(const ir_node *node)
{
348
	return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
349
350
}

351
352
ident *get_irn_opident(const ir_node *node)
{
353
354
	assert(node);
	return node->op->name;
355
356
}

357
358
ir_visited_t (get_irn_visited)(const ir_node *node)
{
359
	return get_irn_visited_(node);
360
361
}

362
363
void (set_irn_visited)(ir_node *node, ir_visited_t visited)
{
364
	set_irn_visited_(node, visited);
Christian Schäfer's avatar
Christian Schäfer committed
365
}
366

367
368
void (mark_irn_visited)(ir_node *node)
{
369
	mark_irn_visited_(node);
370
371
}

372
373
int (irn_visited)(const ir_node *node)
{
374
	return irn_visited_(node);
375
376
}

377
378
int (irn_visited_else_mark)(ir_node *node)
{
379
	return irn_visited_else_mark_(node);
380
381
}

382
383
void (set_irn_link)(ir_node *node, void *link)
{
384
	set_irn_link_(node, link);
Christian Schäfer's avatar
Christian Schäfer committed
385
386
}

387
388
void *(get_irn_link)(const ir_node *node)
{
389
	return get_irn_link_(node);
Christian Schäfer's avatar
Christian Schäfer committed
390
391
}

392
393
op_pin_state (get_irn_pinned)(const ir_node *node)
{
394
	return get_irn_pinned_(node);
395
396
}

397
398
void set_irn_pinned(ir_node *node, op_pin_state state)
{
399
	/* due to optimization an opt may be turned into a Tuple */
400
	if (is_Tuple(node))
401
		return;
Michael Beck's avatar
Michael Beck committed
402

403
404
	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
405

406
	node->attr.except.pin_state = state;
Michael Beck's avatar
Michael Beck committed
407
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
408

409
410
long get_irn_node_nr(const ir_node *node)
{
411
412
	assert(node);
	return node->node_nr;
413
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
414

415
416
void *(get_irn_generic_attr)(ir_node *node)
{
417
	assert(is_ir_node(node));
418
	return get_irn_generic_attr_(node);
419
420
}

421
422
const void *(get_irn_generic_attr_const)(const ir_node *node)
{
423
	assert(is_ir_node(node));
424
	return get_irn_generic_attr_const_(node);
425
426
}

427
428
unsigned (get_irn_idx)(const ir_node *node)
{
429
	assert(is_ir_node(node));
430
	return get_irn_idx_(node);
431
432
}

433
ir_node *(get_nodes_block)(const ir_node *node)
434
{
435
	return get_nodes_block_(node);
Christian Schäfer's avatar
Christian Schäfer committed
436
437
}

438
439
void set_nodes_block(ir_node *node, ir_node *block)
{
440
	assert(!is_Block(node));
441
	set_irn_n(node, -1, block);
Christian Schäfer's avatar
Christian Schäfer committed
442
443
}

444
445
ir_type *is_frame_pointer(const ir_node *n)
{
446
447
	if (is_Proj(n) && (get_Proj_proj(n) == pn_Start_P_frame_base)) {
		ir_node *start = get_Proj_pred(n);
448
		if (is_Start(start)) {
449
450
451
452
			return get_irg_frame_type(get_irn_irg(start));
		}
	}
	return NULL;
453
454
}

455
456
int get_Block_cfgpred_pos(const ir_node *block, const ir_node *pred)
{
457
458
459
460
461
462
463
464
465
	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;
}

466
467
ir_node *(get_Block_cfgpred_block)(const ir_node *node, int pos)
{
468
	return get_Block_cfgpred_block_(node, pos);
469
470
}

471
472
int get_Block_matured(const ir_node *node)
{
473
	assert(is_Block(node));
Michael Beck's avatar
Michael Beck committed
474
	return (int)node->attr.block.is_matured;
Christian Schäfer's avatar
Christian Schäfer committed
475
476
}

477
478
void set_Block_matured(ir_node *node, int matured)
{
479
	assert(is_Block(node));
Michael Beck's avatar
Michael Beck committed
480
	node->attr.block.is_matured = matured;
Christian Schäfer's avatar
Christian Schäfer committed
481
}
Michael Beck's avatar
Michael Beck committed
482

483
484
ir_visited_t (get_Block_block_visited)(const ir_node *node)
{
485
	return get_Block_block_visited_(node);
Christian Schäfer's avatar
Christian Schäfer committed
486
487
}

488
489
void (set_Block_block_visited)(ir_node *node, ir_visited_t visit)
{
490
	set_Block_block_visited_(node, visit);
Christian Schäfer's avatar
Christian Schäfer committed
491
492
}

493
494
void (mark_Block_block_visited)(ir_node *node)
{
495
	mark_Block_block_visited_(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
496
497
}

498
499
int (Block_block_visited)(const ir_node *node)
{
500
	return Block_block_visited_(node);
Matthias Braun's avatar
Matthias Braun committed
501
502
}

503
504
ir_graph *(get_Block_irg)(const ir_node *block)
{
505
	return get_Block_irg_(block);
506
507
}

508
509
ir_entity *create_Block_entity(ir_node *block)
{
510
	ir_entity *entity;
Michael Beck's avatar
Michael Beck committed
511
	assert(is_Block(block));
512
513
514

	entity = block->attr.block.entity;
	if (entity == NULL) {
Matthias Braun's avatar
Matthias Braun committed
515
516
		ir_label_t nr = get_irp_next_label_nr();
		entity = new_label_entity(nr);
517
518
		set_entity_visibility(entity, ir_visibility_local);
		set_entity_linkage(entity, IR_LINKAGE_CONSTANT);
519
520
521
522
523
		set_entity_compiler_generated(entity, 1);

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

526
527
ir_node *(get_Block_phis)(const ir_node *block)
{
528
	return get_Block_phis_(block);
529
530
}

531
532
void (set_Block_phis)(ir_node *block, ir_node *phi)
{
533
	set_Block_phis_(block, phi);
534
535
}

536
537
void (add_Block_phi)(ir_node *block, ir_node *phi)
{
538
	add_Block_phi_(block, phi);
Michael Beck's avatar
Michael Beck committed
539
540
}

541
542
unsigned (get_Block_mark)(const ir_node *block)
{
543
	return get_Block_mark_(block);
Michael Beck's avatar
Michael Beck committed
544
545
}

546
547
void (set_Block_mark)(ir_node *block, unsigned mark)
{
548
	set_Block_mark_(block, mark);
Michael Beck's avatar
Michael Beck committed
549
550
}

551
552
void add_End_keepalive(ir_node *end, ir_node *ka)
{
553
	assert(is_End(end));
554
	add_irn_n(end, ka);
555
556
}

557
558
void set_End_keepalives(ir_node *end, int n, ir_node *in[])
{
559
560
	size_t e;
	int    i;
561
	ir_graph *irg = get_irn_irg(end);
562

563
	/* notify that edges are deleted */
564
565
	for (e = END_KEEPALIVE_OFFSET; e < ARR_LEN(end->in) - 1; ++e) {
		edges_notify_edge(end, e, NULL, end->in[e + 1], irg);
566
567
	}
	ARR_RESIZE(ir_node *, end->in, n + 1 + END_KEEPALIVE_OFFSET);
568

569
570
	for (i = 0; i < n; ++i) {
		end->in[1 + END_KEEPALIVE_OFFSET + i] = in[i];
571
		edges_notify_edge(end, END_KEEPALIVE_OFFSET + i, end->in[1 + END_KEEPALIVE_OFFSET + i], NULL, irg);
572
	}
573
574

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

578
579
void remove_End_keepalive(ir_node *end, ir_node *irn)
{
Matthias Braun's avatar
Matthias Braun committed
580
	int n = get_End_n_keepalives(end);
Christoph Mallon's avatar
Christoph Mallon committed
581
582
583
584
585
	int idx = -1;
	for (int i = n;;) {
		if (i-- == 0)
			return;

586
587
588
589
		ir_node *old_ka = end->in[1 + END_KEEPALIVE_OFFSET + i];

		/* find irn */
		if (old_ka == irn) {
Matthias Braun's avatar
Matthias Braun committed
590
			idx = END_KEEPALIVE_OFFSET + i;
Christoph Mallon's avatar
Christoph Mallon committed
591
			break;
592
		}
593
	}
Matthias Braun's avatar
Matthias Braun committed
594
595
	assert(idx != -1);
	del_irn_n(end, idx);
596
}
597

598
599
void remove_End_Bads_and_doublets(ir_node *end)
{
600
601
602
	pset_new_t keeps;
	int        idx, n = get_End_n_keepalives(end);
	ir_graph   *irg;
603
	bool       changed = false;
604
605
606
607
608
609
610
611
612
613

	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
614
		if (is_Bad(ka) || is_NoMem(ka) || pset_new_contains(&keeps, ka)) {
615
			changed = true;
Matthias Braun's avatar
Matthias Braun committed
616
			del_irn_n(end, idx - END_KEEPALIVE_OFFSET);
617
618
619
620
621
622
			--n;
		} else {
			pset_new_insert(&keeps, ka);
		}
	}
	pset_new_destroy(&keeps);
623
624

	if (changed) {
625
		clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
626
	}
627
628
}

629
630
void free_End(ir_node *end)
{
631
	assert(is_End(end));
632
633
634
635
	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 ... */
636
637
}

638
639
int (is_Const_null)(const ir_node *node)
{
640
	return is_Const_null_(node);
641
642
}

643
644
int (is_Const_one)(const ir_node *node)
{
645
	return is_Const_one_(node);
646
647
}

648
649
int (is_Const_all_one)(const ir_node *node)
{
650
	return is_Const_all_one_(node);
Sebastian Hack's avatar
Sebastian Hack committed
651
652
}

653
654


655
symconst_kind get_SymConst_kind(const ir_node *node)
656
{
657
	assert(is_SymConst(node));
658
	return node->attr.symc.kind;
Christian Schäfer's avatar
Christian Schäfer committed
659
660
}

661
void set_SymConst_kind(ir_node *node, symconst_kind kind)
662
{
663
	assert(is_SymConst(node));
664
	node->attr.symc.kind = kind;
Christian Schäfer's avatar
Christian Schäfer committed
665
666
}

667
ir_type *get_SymConst_type(const ir_node *node)
668
{
Michael Beck's avatar
Michael Beck committed
669
670
671
	/* the cast here is annoying, but we have to compensate for
	   the skip_tip() */
	ir_node *irn = (ir_node *)node;
672
	assert(is_SymConst(node) &&
673
	       (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
Matthias Braun's avatar
Matthias Braun committed
674
	return irn->attr.symc.sym.type_p;
Christian Schäfer's avatar
Christian Schäfer committed
675
676
}

677
void set_SymConst_type(ir_node *node, ir_type *tp)
678
{
679
	assert(is_SymConst(node) &&
680
681
	       (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
	node->attr.symc.sym.type_p = tp;
Christian Schäfer's avatar
Christian Schäfer committed
682
683
}

684
685
ir_entity *get_SymConst_entity(const ir_node *node)
{
686
	assert(is_SymConst(node) && SYMCONST_HAS_ENT(get_SymConst_kind(node)));
687
	return node->attr.symc.sym.entity_p;
Beyhan's avatar
Beyhan committed
688
689
}

690
691
void set_SymConst_entity(ir_node *node, ir_entity *ent)
{
692
	assert(is_SymConst(node) && SYMCONST_HAS_ENT(get_SymConst_kind(node)));
693
	node->attr.symc.sym.entity_p  = ent;
Beyhan's avatar
Beyhan committed
694
695
}

696
697
ir_enum_const *get_SymConst_enum(const ir_node *node)
{
698
	assert(is_SymConst(node) && SYMCONST_HAS_ENUM(get_SymConst_kind(node)));
699
	return node->attr.symc.sym.enum_p;
700
701
}

702
703
void set_SymConst_enum(ir_node *node, ir_enum_const *ec)
{
704
	assert(is_SymConst(node) && SYMCONST_HAS_ENUM(get_SymConst_kind(node)));
705
	node->attr.symc.sym.enum_p  = ec;
706
707
}

Michael Beck's avatar
Michael Beck committed
708
union symconst_symbol
709
710
get_SymConst_symbol(const ir_node *node)
{
711
	assert(is_SymConst(node));
712
	return node->attr.symc.sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
713
714
}

715
void set_SymConst_symbol(ir_node *node, union symconst_symbol sym)
716
{
717
	assert(is_SymConst(node));
718
	node->attr.symc.sym = sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
719
720
}

721
722
const char *get_builtin_kind_name(ir_builtin_kind kind)
{
723
#define X(a)    case a: return #a
724
	switch (kind) {
Michael Beck's avatar
Michael Beck committed
725
		X(ir_bk_trap);
726
		X(ir_bk_debugbreak);
727
		X(ir_bk_return_address);
728
		X(ir_bk_frame_address);
729
		X(ir_bk_prefetch);
Michael Beck's avatar
Michael Beck committed
730
731
732
733
734
735
		X(ir_bk_ffs);
		X(ir_bk_clz);
		X(ir_bk_ctz);
		X(ir_bk_popcount);
		X(ir_bk_parity);
		X(ir_bk_bswap);
736
737
		X(ir_bk_inport);
		X(ir_bk_outport);
738
		X(ir_bk_inner_trampoline);
739
		X(ir_bk_saturating_increment);
740
		X(ir_bk_compare_swap);
741
742
743
744
745
746
	}
	return "<unknown>";
#undef X
}


747
748
int Call_has_callees(const ir_node *node)
{
749
	assert(is_Call(node));
750
751
	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
752
753
}

754
size_t get_Call_n_callees(const ir_node *node)
755
{
756
  assert(is_Call(node) && node->attr.call.callee_arr);
757
758
759
  return ARR_LEN(node->attr.call.callee_arr);
}

760
ir_entity *get_Call_callee(const ir_node *node, size_t pos)
761
{
762
	assert(pos < get_Call_n_callees(node));
763
	return node->attr.call.callee_arr[pos];
764
765
}

766
void set_Call_callee_arr(ir_node *node, size_t n, ir_entity ** arr)
767
{
768
	assert(is_Call(node));
769
	if (node->attr.call.callee_arr == NULL || get_Call_n_callees(node) != n) {
770
771
		ir_graph *const irg = get_irn_irg(node);
		node->attr.call.callee_arr = NEW_ARR_D(ir_entity*, get_irg_obstack(irg), n);
772
773
	}
	memcpy(node->attr.call.callee_arr, arr, n * sizeof(ir_entity *));
774
775
}

776
777
void remove_Call_callee_arr(ir_node *node)
{
778
	assert(is_Call(node));
779
	node->attr.call.callee_arr = NULL;
780
781
}

782
783
int (is_binop)(const ir_node *node)
{
784
	return is_binop_(node);
785
786
}

787
ir_node *get_binop_left(const ir_node *node)
788
{
789
790
	assert(node->op->opar == oparity_binary);
	return get_irn_n(node, node->op->op_index);
791
792
}

793
void set_binop_left(ir_node *node, ir_node *left)
794
{
795
796
	assert(node->op->opar == oparity_binary);
	set_irn_n(node, node->op->op_index, left);
797
798
}

799
ir_node *get_binop_right(const ir_node *node)
800
{
801
802
	assert(node->op->opar == oparity_binary);
	return get_irn_n(node, node->op->op_index + 1);
803
804
}

805
void set_binop_right(ir_node *node, ir_node *right)
806
{
807
808
	assert(node->op->opar == oparity_binary);
	set_irn_n(node, node->op->op_index + 1, right);
809
810
}

811
812
ir_node *(get_Phi_next)(const ir_node *phi)
{
813
	return get_Phi_next_(phi);
814
815
}

816
817
void (set_Phi_next)(ir_node *phi, ir_node *next)
{
818
	set_Phi_next_(phi, next);
819
}
820

821
822
int is_memop(const ir_node *node)
{
823
	return is_op_uses_memory(get_irn_op(node));
824
825
}

826
827
ir_node *get_memop_mem(const ir_node *node)
{
828
	const ir_op *op = get_irn_op(node);
829