irnode.c 25.2 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
	assert(node && node->kind == k_ir_node);
	assert(-1 <= n);
	assert(n < get_irn_arity(node));
	assert(in && in->kind == k_ir_node);
197
	assert(!is_Deleted(in));
198
199
200
201
202

	/* 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;
}

230
static void remove_irn_n(ir_node *node, int n)
Matthias Braun's avatar
Matthias Braun committed
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
{
	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);
}

252
void remove_Sync_n(ir_node *n, int i)
Christoph Mallon's avatar
Christoph Mallon committed
253
{
254
	remove_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
void set_irn_pinned(ir_node *node, op_pin_state state)
{
400
	/* due to optimization an opt may be turned into a Tuple */
401
	if (is_Tuple(node))
402
		return;
Michael Beck's avatar
Michael Beck committed
403

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

579
580
581
582
583
void remove_End_n(ir_node *n, int idx)
{
	remove_irn_n(n, idx);
}

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
	assert(idx != -1);
601
	remove_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;
622
			remove_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
union symconst_symbol get_SymConst_symbol(const ir_node *node)
703
{
704
	assert(is_SymConst(node));
705
	return node->attr.symc.sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
706
707
}

708
void set_SymConst_symbol(ir_node *node, union symconst_symbol sym)
709
{
710
	assert(is_SymConst(node));
711
	node->attr.symc.sym = sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
712
713
}

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

739
740
741
742
743
744
745
746
747
748
749
750
751
752
ir_entity *get_Call_callee(const ir_node *node)
{
	ir_node *ptr = get_Call_ptr(node);
	if (!is_SymConst_addr_ent(ptr))
		return NULL;
	ir_entity *entity = get_SymConst_entity(ptr);
	/* some (corner case/pointless) graphs can have non-method entities as
	 * call pointers */
	ir_type *type = get_entity_type(entity);
	if (!is_Method_type(type))
		return NULL;
	return entity;
}

753
754
int (is_binop)(const ir_node *node)
{
755
	return is_binop_(node);
756
757
}

758
ir_node *get_binop_left(const ir_node *node)
759
{
760
761
	assert(node->op->opar == oparity_binary);
	return get_irn_n(node, node->op->op_index);
762
763
}

764
void set_binop_left(ir_node *node, ir_node *left)
765
{
766
767
	assert(node->op->opar == oparity_binary);
	set_irn_n(node, node->op->op_index, left);
768
769
}

770
ir_node *get_binop_right(const ir_node *node)
771
{
772
773
	assert(node->op->opar == oparity_binary);
	return get_irn_n(node, node->op->op_index + 1);
774
775
}

776
void set_binop_right(ir_node *node, ir_node *right)
777
{
778
779
	assert(node->op->opar == oparity_binary);
	set_irn_n(node, node->op->op_index + 1, right);
780
781
}

782
783
ir_node *(get_Phi_next)(const ir_node *phi)
{
784
	return get_Phi_next_(phi);
785
786
}

787
788
void (set_Phi_next)(ir_node *phi, ir_node *next)
{
789
	set_Phi_next_(phi, next);
790
}
791

792
793
int is_memop(const ir_node *node)
{
794
	return is_op_uses_memory(get_irn_op(node));
795
796
}

797
798
ir_node *get_memop_mem(const ir_node *node)
{
799
	const ir_op *op = get_irn_op(node);
800
	assert(is_memop(node));
801
	return get_irn_n(node, op->memory_index);
802
803
}

804
805
void set_memop_mem(ir_node *node, ir_node *mem)
{
806
	const ir_op *op = get_irn_op(node);
807
	assert(is_memop(node));
808
	set_irn_n(node, op->memory_index, mem);
809
810
}

811
812
void add_Sync_pred(ir_node *node, ir_node *pred)
{
813
	assert(is_Sync(node));
814
	add_irn_n(node, pred);
Michael Beck's avatar
Michael Beck committed
815
816
}

817
818
int (is_arg_Proj)(const ir_node *node)
{
819
	return is_arg_Proj_(node);
Michael Beck's avatar
Michael Beck committed
820
821
}

Matthias Braun's avatar
Matthias Braun committed
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
int is_x_except_Proj(const ir_node *node)
{
	ir_node *pred;
	if (!is_Proj(node))
		return false;
	pred = get_Proj_pred(node);
	if (!is_fragile_op(pred))
		return false;
	return get_Proj_proj(node) == pred->op->pn_x_except;
}

int is_x_regular_Proj(const ir_node *node)
{
	ir_node *pred;
	if (!is_Proj(node))
		return false;
	pred = get_Proj_pred(node);
	if (!is_fragile_op(pred))
		return false;
uqxyd's avatar
Typo.    
uqxyd committed
841
	return get_Proj_proj(node) == pred->op->pn_x_regular;
Matthias Braun's avatar
Matthias Braun committed
842
843
}

844
845
846
847
848
849
850
851
852
853
854
855
856
857
void ir_set_throws_exception(ir_node *node, int throws_exception)
{
	except_attr *attr = &node->attr.except;
	assert(is_fragile_op(node));
	attr->throws_exception = throws_exception;
}

int ir_throws_exception(const ir_node *node)
{
	const except_attr *attr = &node->attr.except;
	assert(is_fragile_op(node));
	return attr->throws_exception;
}

858
size_t get_ASM_n_output_constraints(const ir_node *node)