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
 */
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"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
26

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

30
31
#include "beinfo.h"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

151
	pOld_in = &node->in;
152

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

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

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

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

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

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

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

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

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

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

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

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

225
226
227
	return pos;
}

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

407
408
	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
409

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

530
531
ir_node *(get_Block_phis)(const ir_node *block)
{
532
	return get_Block_phis_(block);
533
534
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	if (changed) {
629
		clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
630
	}
631
632
}

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

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

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

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

657
658


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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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