irnode.c 26.3 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
{
Christoph Mallon's avatar
Christoph Mallon committed
81
82
83
	assert(irg);
	assert(op);
	assert(mode);
84
85

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

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

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

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

118
	/* don't put this into the for loop, arity is -1 for some nodes! */
Matthias Braun's avatar
Matthias Braun committed
119
120
	if (block != NULL)
		edges_notify_edge(res, -1, block, NULL, irg);
121
122
	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
123

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

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

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

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

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

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

153
	pOld_in = &node->in;
154

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

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

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

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

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

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

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

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

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

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

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

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

227
228
229
	return pos;
}

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

409
410
	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
411

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

532
533
ir_node *(get_Block_phis)(const ir_node *block)
{
534
	return get_Block_phis_(block);
535
536
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	if (changed) {
631
		clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
632
	}
633
634
}

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

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

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

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

659
660


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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

787
788
int (is_binop)(const ir_node *node)
{
789
	return is_binop_(node);
790
791
}

792
ir_node *get_binop_left(const ir_node *node)
793
{
794
795
	assert(node->op->opar == oparity_binary);
	return get_irn_n(node, node->op->op_index);
796
797
}

798
void set_binop_left(ir_node *node, ir_node *left)
799
{
800
801
	assert(node->op->opar == oparity_binary);
	set_irn_n(node, node->op->op_index, left);
802
803
}

804
ir_node *get_binop_right(const ir_node *node)
805
{
806
807
	assert(node->op->opar == oparity_binary);
	return get_irn_n(node, node->op->op_index + 1);
808
809
}

810
void set_binop_right(ir_node *node, ir_node *right)
811
{
812
813
	assert(node->op->opar == oparity_binary);
	set_irn_n(node, node->op->op_index + 1, right);
814
815
}

816
817
ir_node *(get_Phi_next)(const ir_node *phi)
{
818
	return get_Phi_next_(phi);
819
820
}

821
822
void (set_Phi_next)(ir_node *phi, ir_node *next)
{
823
	set_Phi_next_(phi, next);
824
}
825

826
827
int is_memop(const ir_node *node)
{
828
	return is_op_uses_memory(get_irn_op(node));
829
830