irnode.c 26.7 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
 */
Matthias Braun's avatar
Matthias Braun committed
11
#include "config.h"
Michael Beck's avatar
Michael Beck committed
12

13
#include <string.h>
Boris Boesler's avatar
added    
Boris Boesler committed
14

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

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

32
33
#include "beinfo.h"

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

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

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

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

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

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

Christoph Mallon's avatar
Christoph Mallon committed
83
84
85
	assert(irg);
	assert(op);
	assert(mode);
86
87

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

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

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

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

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

126
	hook_new_node(irg, res);
127
	if (irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
128
		be_info_new_node(irg, res);
129
	}
Michael Beck's avatar
Michael Beck committed
130

131
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
132
133
}

134
135
int (is_ir_node)(const void *thing)
{
136
	return is_ir_node_(thing);
Sebastian Felis's avatar
Sebastian Felis committed
137
138
}

139
140
int (get_irn_arity)(const ir_node *node)
{
141
	return get_irn_arity_(node);
142
143
}

144
145
ir_node **get_irn_in(const ir_node *node)
{
146
147
148
	return node->in;
}

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

155
	pOld_in = &node->in;
156

157
158
159
160
161
162
163
#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
164
165

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

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

Michael Beck's avatar
Michael Beck committed
182
	memcpy((*pOld_in) + 1, in, sizeof(ir_node *) * arity);
183
184

	/* update irg flags */
185
	clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
186
187
}

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

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

	node->in[n + 1] = in;
208
209

	/* update irg flags */
210
	clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
Christian Schäfer's avatar
Christian Schäfer committed
211
212
}

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

223
224
225
	/* Call the hook */
	hook_set_irn_n(node, pos, node->in[pos + 1], NULL);

Matthias Braun's avatar
Matthias Braun committed
226
227
228
	/* update irg flags */
	clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);

229
230
231
	return pos;
}

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

259
260
int (get_irn_deps)(const ir_node *node)
{
261
	return get_irn_deps_(node);
Sebastian Hack's avatar
Sebastian Hack committed
262
263
}

264
265
ir_node *(get_irn_dep)(const ir_node *node, int pos)
{
266
	return get_irn_dep_(node, pos);
Sebastian Hack's avatar
Sebastian Hack committed
267
268
}

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

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

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

315
316
void add_irn_deps(ir_node *tgt, ir_node *src)
{
Sebastian Hack's avatar
Sebastian Hack committed
317
318
	int i, n;

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


324
325
ir_mode *(get_irn_mode)(const ir_node *node)
{
326
	return get_irn_mode_(node);
Christian Schäfer's avatar
Christian Schäfer committed
327
328
}

329
330
void (set_irn_mode)(ir_node *node, ir_mode *mode)
{
331
	set_irn_mode_(node, mode);
Till Riedel's avatar
Till Riedel committed
332
333
}

334
335
ir_op *(get_irn_op)(const ir_node *node)
{
336
	return get_irn_op_(node);
Christian Schäfer's avatar
Christian Schäfer committed
337
338
}

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

344
345
unsigned (get_irn_opcode)(const ir_node *node)
{
346
	return get_irn_opcode_(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
347
348
}

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

354
355
ident *get_irn_opident(const ir_node *node)
{
356
357
	assert(node);
	return node->op->name;
358
359
}

360
361
ir_visited_t (get_irn_visited)(const ir_node *node)
{
362
	return get_irn_visited_(node);
363
364
}

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

370
371
void (mark_irn_visited)(ir_node *node)
{
372
	mark_irn_visited_(node);
373
374
}

375
376
int (irn_visited)(const ir_node *node)
{
377
	return irn_visited_(node);
378
379
}

380
381
int (irn_visited_else_mark)(ir_node *node)
{
382
	return irn_visited_else_mark_(node);
383
384
}

385
386
void (set_irn_link)(ir_node *node, void *link)
{
387
	set_irn_link_(node, link);
Christian Schäfer's avatar
Christian Schäfer committed
388
389
}

390
391
void *(get_irn_link)(const ir_node *node)
{
392
	return get_irn_link_(node);
Christian Schäfer's avatar
Christian Schäfer committed
393
394
}

395
396
op_pin_state (get_irn_pinned)(const ir_node *node)
{
397
	return get_irn_pinned_(node);
398
399
}

400
401
op_pin_state (is_irn_pinned_in_irg) (const ir_node *node)
{
402
	return is_irn_pinned_in_irg_(node);
403
404
}

405
406
void set_irn_pinned(ir_node *node, op_pin_state state)
{
407
	/* due to optimization an opt may be turned into a Tuple */
408
	if (is_Tuple(node))
409
		return;
Michael Beck's avatar
Michael Beck committed
410

411
412
	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
413

414
	node->attr.except.pin_state = state;
Michael Beck's avatar
Michael Beck committed
415
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
416

417
418
long get_irn_node_nr(const ir_node *node)
{
419
420
	assert(node);
	return node->node_nr;
421
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
422

423
424
void *(get_irn_generic_attr)(ir_node *node)
{
425
	assert(is_ir_node(node));
426
	return get_irn_generic_attr_(node);
427
428
}

429
430
const void *(get_irn_generic_attr_const)(const ir_node *node)
{
431
	assert(is_ir_node(node));
432
	return get_irn_generic_attr_const_(node);
433
434
}

435
436
unsigned (get_irn_idx)(const ir_node *node)
{
437
	assert(is_ir_node(node));
438
	return get_irn_idx_(node);
439
440
}

441
ir_node *(get_nodes_block)(const ir_node *node)
442
{
443
	return get_nodes_block_(node);
Christian Schäfer's avatar
Christian Schäfer committed
444
445
}

446
447
void set_nodes_block(ir_node *node, ir_node *block)
{
448
	assert(!is_Block(node));
449
	set_irn_n(node, -1, block);
Christian Schäfer's avatar
Christian Schäfer committed
450
451
}

452
453
ir_type *is_frame_pointer(const ir_node *n)
{
454
455
	if (is_Proj(n) && (get_Proj_proj(n) == pn_Start_P_frame_base)) {
		ir_node *start = get_Proj_pred(n);
456
		if (is_Start(start)) {
457
458
459
460
			return get_irg_frame_type(get_irn_irg(start));
		}
	}
	return NULL;
461
462
}

463
464
int get_Block_cfgpred_pos(const ir_node *block, const ir_node *pred)
{
465
466
467
468
469
470
471
472
473
	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;
}

474
475
ir_node *(get_Block_cfgpred_block)(const ir_node *node, int pos)
{
476
	return get_Block_cfgpred_block_(node, pos);
477
478
}

479
480
int get_Block_matured(const ir_node *node)
{
481
	assert(is_Block(node));
Michael Beck's avatar
Michael Beck committed
482
	return (int)node->attr.block.is_matured;
Christian Schäfer's avatar
Christian Schäfer committed
483
484
}

485
486
void set_Block_matured(ir_node *node, int matured)
{
487
	assert(is_Block(node));
Michael Beck's avatar
Michael Beck committed
488
	node->attr.block.is_matured = matured;
Christian Schäfer's avatar
Christian Schäfer committed
489
}
Michael Beck's avatar
Michael Beck committed
490

491
492
ir_visited_t (get_Block_block_visited)(const ir_node *node)
{
493
	return get_Block_block_visited_(node);
Christian Schäfer's avatar
Christian Schäfer committed
494
495
}

496
497
void (set_Block_block_visited)(ir_node *node, ir_visited_t visit)
{
498
	set_Block_block_visited_(node, visit);
Christian Schäfer's avatar
Christian Schäfer committed
499
500
}

501
502
void (mark_Block_block_visited)(ir_node *node)
{
503
	mark_Block_block_visited_(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
504
505
}

506
507
int (Block_block_visited)(const ir_node *node)
{
508
	return Block_block_visited_(node);
Matthias Braun's avatar
Matthias Braun committed
509
510
}

511
512
ir_graph *(get_Block_irg)(const ir_node *block)
{
513
	return get_Block_irg_(block);
514
515
}

516
517
ir_entity *create_Block_entity(ir_node *block)
{
518
	ir_entity *entity;
Michael Beck's avatar
Michael Beck committed
519
	assert(is_Block(block));
520
521
522

	entity = block->attr.block.entity;
	if (entity == NULL) {
Matthias Braun's avatar
Matthias Braun committed
523
524
		ir_label_t nr = get_irp_next_label_nr();
		entity = new_label_entity(nr);
525
526
		set_entity_visibility(entity, ir_visibility_local);
		set_entity_linkage(entity, IR_LINKAGE_CONSTANT);
527
528
529
530
531
		set_entity_compiler_generated(entity, 1);

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

534
535
ir_node *(get_Block_phis)(const ir_node *block)
{
536
	return get_Block_phis_(block);
537
538
}

539
540
void (set_Block_phis)(ir_node *block, ir_node *phi)
{
541
	set_Block_phis_(block, phi);
542
543
}

544
545
void (add_Block_phi)(ir_node *block, ir_node *phi)
{
546
	add_Block_phi_(block, phi);
Michael Beck's avatar
Michael Beck committed
547
548
}

549
550
unsigned (get_Block_mark)(const ir_node *block)
{
551
	return get_Block_mark_(block);
Michael Beck's avatar
Michael Beck committed
552
553
}

554
555
void (set_Block_mark)(ir_node *block, unsigned mark)
{
556
	set_Block_mark_(block, mark);
Michael Beck's avatar
Michael Beck committed
557
558
}

559
560
void add_End_keepalive(ir_node *end, ir_node *ka)
{
561
	assert(is_End(end));
562
	add_irn_n(end, ka);
563
564
}

565
566
void set_End_keepalives(ir_node *end, int n, ir_node *in[])
{
567
568
	size_t e;
	int    i;
569
	ir_graph *irg = get_irn_irg(end);
570

571
	/* notify that edges are deleted */
572
573
	for (e = END_KEEPALIVE_OFFSET; e < ARR_LEN(end->in) - 1; ++e) {
		edges_notify_edge(end, e, NULL, end->in[e + 1], irg);
574
575
	}
	ARR_RESIZE(ir_node *, end->in, n + 1 + END_KEEPALIVE_OFFSET);
576

577
578
	for (i = 0; i < n; ++i) {
		end->in[1 + END_KEEPALIVE_OFFSET + i] = in[i];
579
		edges_notify_edge(end, END_KEEPALIVE_OFFSET + i, end->in[1 + END_KEEPALIVE_OFFSET + i], NULL, irg);
580
	}
581
582

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

586
587
void remove_End_keepalive(ir_node *end, ir_node *irn)
{
Matthias Braun's avatar
Matthias Braun committed
588
	int n = get_End_n_keepalives(end);
Christoph Mallon's avatar
Christoph Mallon committed
589
590
591
592
593
	int idx = -1;
	for (int i = n;;) {
		if (i-- == 0)
			return;

594
595
596
597
		ir_node *old_ka = end->in[1 + END_KEEPALIVE_OFFSET + i];

		/* find irn */
		if (old_ka == irn) {
Matthias Braun's avatar
Matthias Braun committed
598
			idx = END_KEEPALIVE_OFFSET + i;
Christoph Mallon's avatar
Christoph Mallon committed
599
			break;
600
		}
601
	}
Matthias Braun's avatar
Matthias Braun committed
602
603
	assert(idx != -1);
	del_irn_n(end, idx);
604
}
605

606
607
void remove_End_Bads_and_doublets(ir_node *end)
{
608
609
610
	pset_new_t keeps;
	int        idx, n = get_End_n_keepalives(end);
	ir_graph   *irg;
611
	bool       changed = false;
612
613
614
615
616
617
618
619
620
621

	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
622
		if (is_Bad(ka) || is_NoMem(ka) || pset_new_contains(&keeps, ka)) {
623
			changed = true;
Matthias Braun's avatar
Matthias Braun committed
624
			del_irn_n(end, idx - END_KEEPALIVE_OFFSET);
625
626
627
628
629
630
			--n;
		} else {
			pset_new_insert(&keeps, ka);
		}
	}
	pset_new_destroy(&keeps);
631
632

	if (changed) {
633
		clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
634
	}
635
636
}

637
638
void free_End(ir_node *end)
{
639
	assert(is_End(end));
640
641
642
643
	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 ... */
644
645
}

646
647
int (is_Const_null)(const ir_node *node)
{
648
	return is_Const_null_(node);
649
650
}

651
652
int (is_Const_one)(const ir_node *node)
{
653
	return is_Const_one_(node);
654
655
}

656
657
int (is_Const_all_one)(const ir_node *node)
{
658
	return is_Const_all_one_(node);
Sebastian Hack's avatar
Sebastian Hack committed
659
660
}

661
662


663
symconst_kind get_SymConst_kind(const ir_node *node)
664
{
665
	assert(is_SymConst(node));
666
	return node->attr.symc.kind;
Christian Schäfer's avatar
Christian Schäfer committed
667
668
}

669
void set_SymConst_kind(ir_node *node, symconst_kind kind)
670
{
671
	assert(is_SymConst(node));
672
	node->attr.symc.kind = kind;
Christian Schäfer's avatar
Christian Schäfer committed
673
674
}

675
ir_type *get_SymConst_type(const ir_node *node)
676
{
Michael Beck's avatar
Michael Beck committed
677
678
679
	/* the cast here is annoying, but we have to compensate for
	   the skip_tip() */
	ir_node *irn = (ir_node *)node;
680
	assert(is_SymConst(node) &&
681
	       (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
Matthias Braun's avatar
Matthias Braun committed
682
	return irn->attr.symc.sym.type_p;
Christian Schäfer's avatar
Christian Schäfer committed
683
684
}

685
void set_SymConst_type(ir_node *node, ir_type *tp)
686
{
687
	assert(is_SymConst(node) &&
688
689
	       (SYMCONST_HAS_TYPE(get_SymConst_kind(node))));
	node->attr.symc.sym.type_p = tp;
Christian Schäfer's avatar
Christian Schäfer committed
690
691
}

692
693
ir_entity *get_SymConst_entity(const ir_node *node)
{
694
	assert(is_SymConst(node) && SYMCONST_HAS_ENT(get_SymConst_kind(node)));
695
	return node->attr.symc.sym.entity_p;
Beyhan's avatar
Beyhan committed
696
697
}

698
699
void set_SymConst_entity(ir_node *node, ir_entity *ent)
{
700
	assert(is_SymConst(node) && SYMCONST_HAS_ENT(get_SymConst_kind(node)));
701
	node->attr.symc.sym.entity_p  = ent;
Beyhan's avatar
Beyhan committed
702
703
}

704
705
ir_enum_const *get_SymConst_enum(const ir_node *node)
{
706
	assert(is_SymConst(node) && SYMCONST_HAS_ENUM(get_SymConst_kind(node)));
707
	return node->attr.symc.sym.enum_p;
708
709
}

710
711
void set_SymConst_enum(ir_node *node, ir_enum_const *ec)
{
712
	assert(is_SymConst(node) && SYMCONST_HAS_ENUM(get_SymConst_kind(node)));
713
	node->attr.symc.sym.enum_p  = ec;
714
715
}

Michael Beck's avatar
Michael Beck committed
716
union symconst_symbol
717
718
get_SymConst_symbol(const ir_node *node)
{
719
	assert(is_SymConst(node));
720
	return node->attr.symc.sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
721
722
}

723
void set_SymConst_symbol(ir_node *node, union symconst_symbol sym)
724
{
725
	assert(is_SymConst(node));
726
	node->attr.symc.sym = sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
727
728
}

729
730
const char *get_builtin_kind_name(ir_builtin_kind kind)
{
731
#define X(a)    case a: return #a
732
	switch (kind) {
Michael Beck's avatar
Michael Beck committed
733
		X(ir_bk_trap);
734
		X(ir_bk_debugbreak);
735
		X(ir_bk_return_address);
736
		X(ir_bk_frame_address);
737
		X(ir_bk_prefetch);
Michael Beck's avatar
Michael Beck committed
738
739
740
741
742
743
		X(ir_bk_ffs);
		X(ir_bk_clz);
		X(ir_bk_ctz);
		X(ir_bk_popcount);
		X(ir_bk_parity);
		X(ir_bk_bswap);
744
745
		X(ir_bk_inport);
		X(ir_bk_outport);
746
		X(ir_bk_inner_trampoline);
747
748
749
750
751
752
	}
	return "<unknown>";
#undef X
}


753
754
int Call_has_callees(const ir_node *node)
{
755
	assert(is_Call(node));
756
757
	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
758
759
}

760
size_t get_Call_n_callees(const ir_node *node)
761
{
762
  assert(is_Call(node) && node->attr.call.callee_arr);
763
764
765
  return ARR_LEN(node->attr.call.callee_arr);
}

766
ir_entity *get_Call_callee(const ir_node *node, size_t pos)
767
{
768
	assert(pos < get_Call_n_callees(node));
769
	return node->attr.call.callee_arr[pos];
770
771
}

772
void set_Call_callee_arr(ir_node *node, size_t n, ir_entity ** arr)
773
{
774
	assert(is_Call(node));
775
	if (node->attr.call.callee_arr == NULL || get_Call_n_callees(node) != n) {
776
777
		ir_graph *const irg = get_irn_irg(node);
		node->attr.call.callee_arr = NEW_ARR_D(ir_entity*, get_irg_obstack(irg), n);
778
779
	}
	memcpy(node->attr.call.callee_arr, arr, n * sizeof(ir_entity *));
780
781
}

782
783
void remove_Call_callee_arr(ir_node *node)
{
784
	assert(is_Call(node));
785
	node->attr.call.callee_arr = NULL;
786
787
}

788
789
int (is_unop)(const ir_node *node)
{
790
	return is_unop_(node);
791
792
}

793
ir_node *get_unop_op(const ir_node *node)
794
{
795
796
	if (node->op->opar == oparity_unary)
		return get_irn_n(node, node->op->op_index);
797

798
799
	assert(node->op->opar == oparity_unary);
	return NULL;
800
801
}

802
void set_unop_op(ir_node *node, ir_node *op)
803
{
804
805
	if (node->op->opar == oparity_unary)
		set_irn_n(node, node->op->op_index, op);
806

807
	assert(node->op->opar == oparity_unary);
808
809
}

810
811
int (is_binop)(const ir_node *node)
{
812
	return is_binop_(node);
813
814
}

815
ir_node *get_binop_left(const ir_node *node)
816
{
817
818
	assert(node->op->opar == oparity_binary);
	return get_irn_n(node, node->op->op_index);
819
820
}

821
void set_binop_left(ir_node *node, ir_node *left)
822
{
823
824
	assert(node->op->opar == oparity_binary);
	set_irn_n(node, node->op->op_index, left);
825
826
}

827
ir_node *get_binop_right(const ir_node *node)