irgraph.c 23.1 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

Matthias Braun's avatar
Matthias Braun committed
20
21
22
23
24
/**
 * @file
 * @brief    Entry point to the representation of procedure code.
 * @author   Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Michael Beck
 * @version  $Id$
Götz Lindenmaier's avatar
Götz Lindenmaier committed
25
 */
Matthias Braun's avatar
Matthias Braun committed
26
#include "config.h"
Boris Boesler's avatar
added    
Boris Boesler committed
27

28
#include <string.h>
29
#include <stddef.h>
30

Michael Beck's avatar
Michael Beck committed
31
#include "xmalloc.h"
32
#include "ircons_t.h"
Michael Beck's avatar
Michael Beck committed
33
34
#include "irgraph_t.h"
#include "irprog_t.h"
35
#include "irgraph_t.h"
Michael Beck's avatar
Michael Beck committed
36
37
38
39
40
41
42
#include "irnode_t.h"
#include "iropt_t.h"
#include "irflag_t.h"
#include "array.h"
#include "irgmod.h"
#include "irouts.h"
#include "irhooks.h"
43
#include "irtools.h"
Michael Beck's avatar
Michael Beck committed
44
#include "irgwalk.h"
Michael Beck's avatar
Michael Beck committed
45
#include "irbackedge_t.h"
Michael Beck's avatar
Michael Beck committed
46
47
#include "iredges_t.h"
#include "type_t.h"
48
#include "irmemory.h"
49
#include "irphase.h"
Christian Schäfer's avatar
Christian Schäfer committed
50

51
52
#define INITIAL_IDX_IRN_MAP_SIZE 1024

53
54
55
56
57
58
59
60
61
62
63
64
/**
 * Indicates, whether additional data can be registered to graphs.
 * If set to 1, this is not possible anymore.
 */
static int forbid_new_data = 0;

/**
 * The amount of additional space for custom data to be allocated upon
 * creating a new graph.
 */
static size_t additional_graph_data_size = 0;

Christian Schäfer's avatar
Christian Schäfer committed
65
ir_graph *current_ir_graph;
66
67
ir_graph *get_current_ir_graph(void)
{
68
	return current_ir_graph;
69
}
70

71
72
void set_current_ir_graph(ir_graph *graph)
{
73
	current_ir_graph = graph;
74
75
}

76
77
78
79
/** contains the suffix for frame type names */
static ident *frame_type_suffix = NULL;

/* initialize the IR graph module */
80
81
void firm_init_irgraph(void)
{
82
83
	frame_type_suffix = new_id_from_str(FRAME_TP_SUFFIX);
	forbid_new_data   = 1;
84
85
86
}

/**
87
 * Allocate a new IR graph.
88
89
90
91
92
 * This function respects the registered graph data. The only reason for
 * this function is, that there are two locations, where graphs are
 * allocated (new_r_ir_graph, new_const_code_irg).
 * @return Memory for a new graph.
 */
93
94
static ir_graph *alloc_graph(void)
{
Michael Beck's avatar
Michael Beck committed
95
96
	ir_graph *res;
	size_t   size = sizeof(ir_graph) + additional_graph_data_size;
97
	char     *ptr = XMALLOCNZ(char, size);
98

Michael Beck's avatar
Michael Beck committed
99
100
101
102
103
104
105
106
	res = (ir_graph *)(ptr + additional_graph_data_size);
	res->kind = k_ir_graph;

	/* initialize the idx->node map. */
	res->idx_irn_map = NEW_ARR_F(ir_node *, INITIAL_IDX_IRN_MAP_SIZE);
	memset(res->idx_irn_map, 0, INITIAL_IDX_IRN_MAP_SIZE * sizeof(res->idx_irn_map[0]));

	return res;
107
}
108

109
110
111
/**
 * Frees an allocated IR graph
 */
112
113
static void free_graph(ir_graph *irg)
{
114
	char *ptr = (char *)irg;
115
	int  i;
116

117
118
	for (i = 0; i < EDGE_KIND_LAST; ++i)
		edges_deactivate_kind(irg, i);
119
	DEL_ARR_F(irg->idx_irn_map);
120
	free(ptr - additional_graph_data_size);
121
122
}

123
124
125
126
127
128
/**
 * Set the number of locals for a given graph.
 *
 * @param irg    the graph
 * @param n_loc  number of locals
 */
129
130
void irg_set_nloc(ir_graph *res, int n_loc)
{
131
132
	assert(res->phase_state == phase_building);

133
134
135
136
137
	res->n_loc = n_loc + 1;     /* number of local variables that are never
	                               dereferenced in this graph plus one for
	                               the store. This is not the number of
	                               parameters to the procedure!  */

138
139
	if (res->loc_descriptions) {
		xfree(res->loc_descriptions);
Michael Beck's avatar
Michael Beck committed
140
		res->loc_descriptions = NULL;
141
	}
142
143
}

Christian Schäfer's avatar
Christian Schäfer committed
144
145
146
147
148
149
150
151
152
/* Allocates a list of nodes:
    - The start block containing a start node and Proj nodes for it's four
      results (X, M, P, Tuple).
    - The end block containing an end node. This block is not matured after
      new_ir_graph as predecessors need to be added to it.
    - The current block, which is empty and also not matured.
   Further it allocates several datastructures needed for graph construction
   and optimization.
*/
153
154
ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc)
{
155
156
	ir_graph *res;
	ir_node  *first_block;
157
	ir_node  *end, *start, *start_block, *initial_mem, *projX, *bad;
158
159
160
161
162
163
164

	res = alloc_graph();

	/* inform statistics here, as blocks will be already build on this graph */
	hook_new_graph(res, ent);

	/*-- initialized for each graph. --*/
165
	res->kind = k_ir_graph;
166
	res->obst = XMALLOC(struct obstack);
167
168
169
170
	obstack_init(res->obst);

	res->phase_state = phase_building;
	irg_set_nloc(res, n_loc);
171
172
173
174
175
176

	/* descriptions will be allocated on demand */
	res->loc_descriptions = NULL;

	res->visited       = 0; /* visited flag, for the ir walker */
	res->block_visited = 0; /* visited flag, for the 'block'-walker */
177

178
179
180
181
	res->extbb_obst = NULL;

	res->last_node_idx = 0;

182
	new_identities(res);
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
	res->outs = NULL;

	res->inline_property       = irg_inline_any;
	res->additional_properties = mtp_property_inherited;  /* inherited from type */

	res->irg_pinned_state    = op_pin_state_pinned;
	res->outs_state          = outs_none;
	res->dom_state           = dom_none;
	res->pdom_state          = dom_none;
	res->typeinfo_state      = ir_typeinfo_none;
	set_irp_typeinfo_inconsistent();           /* there is a new graph with typeinfo_none. */
	res->callee_info_state   = irg_callee_info_none;
	res->loopinfo_state      = loopinfo_none;
	res->class_cast_state    = ir_class_casts_transitive;
	res->extblk_state        = ir_extblk_info_none;
	res->execfreq_state      = exec_freq_none;
	res->fp_model            = fp_model_precise;
200
	res->entity_usage_state  = ir_entity_usage_not_computed;
201
202
203
204
205
206
207
	res->mem_disambig_opt    = aa_opt_inherited;

	/*-- Type information for the procedure of the graph --*/
	res->ent = ent;
	set_entity_irg(ent, res);

	/*--  a class type so that it can contain "inner" methods as in Pascal. --*/
208
	res->frame_type = new_type_frame();
209
210

	/* the Anchor node must be created first */
211
	res->anchor = new_r_Anchor(res);
212
213

	/*-- Nodes needed in every graph --*/
214
215
	set_irg_end_block (res, new_r_immBlock(res));
	end = new_r_End(res);
216
	set_irg_end(res, end);
217

218
	start_block = new_r_Block(res, 0, NULL);
219
	set_irg_start_block(res, start_block);
220
221
222
	bad = new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL);
	bad->attr.irg.irg = res;
	set_irg_bad        (res, bad);
223
	set_irg_no_mem     (res, new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
224
	start = new_r_Start(res);
225
226
227
	set_irg_start      (res, start);

	/* Proj results of start node */
228
	projX                   = new_r_Proj(start, mode_X, pn_Start_X_initial_exec);
229
	set_irg_initial_exec    (res, projX);
230
231
232
233
	set_irg_frame           (res, new_r_Proj(start, mode_P_data, pn_Start_P_frame_base));
	set_irg_tls             (res, new_r_Proj(start, mode_P_data, pn_Start_P_tls));
	set_irg_args            (res, new_r_Proj(start, mode_T,      pn_Start_T_args));
	initial_mem             = new_r_Proj(start, mode_M, pn_Start_M);
234
235
	set_irg_initial_mem(res, initial_mem);

Matthias Braun's avatar
Matthias Braun committed
236
	res->index       = get_irp_new_irg_idx();
237
#ifdef DEBUG_libfirm
238
	res->graph_nr    = get_irp_new_node_nr();
239
240
#endif

241
242
	set_r_cur_block(res, start_block);
	set_r_store(res, initial_mem);
Christian Schäfer's avatar
Christian Schäfer committed
243

244
	/*-- Make a block to start with --*/
245
246
	first_block = new_r_immBlock(res);
	set_r_cur_block(res, first_block);
247
	add_immBlock_pred(first_block, projX);
Christian Schäfer's avatar
Christian Schäfer committed
248

249
250
	res->method_execution_frequency = -1.0;
	res->estimated_node_count       = 0;
251

252
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
253
254
}

255
256
ir_graph *new_ir_graph(ir_entity *ent, int n_loc)
{
257
258
259
	ir_graph *res = new_r_ir_graph(ent, n_loc);
	add_irp_irg(res);          /* remember this graph global. */
	return res;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
260
261
}

262
/* Make a rudimentary IR graph for the constant code.
263
   Must look like a correct irg, spare everything else. */
264
265
266
267
ir_graph *new_const_code_irg(void)
{
	ir_graph *res = alloc_graph();
	ir_node  *bad;
268
	ir_node  *body_block;
269
270
271
272
273
274
	ir_node  *end;
	ir_node  *end_block;
	ir_node  *no_mem;
	ir_node  *projX;
	ir_node  *start_block;
	ir_node  *start;
275

276
277
	/* inform statistics here, as blocks will be already build on this graph */
	hook_new_graph(res, NULL);
278

279
280
	res->n_loc         = 1; /* Only the memory. */
	res->visited       = 0; /* visited flag, for the ir walker */
281
	res->block_visited = 0; /* visited flag, for the 'block'-walker */
282
283
	res->obst          = XMALLOC(struct obstack);
	obstack_init(res->obst);
284
285
286
287
288
289
290
291
292
	res->extbb_obst = NULL;

	res->last_node_idx = 0;

	res->phase_state      = phase_building;
	res->irg_pinned_state = op_pin_state_pinned;
	res->extblk_state     = ir_extblk_info_none;
	res->fp_model         = fp_model_precise;

293
	/* value table for global value numbering for optimizing use in iropt.c */
294
	new_identities(res);
295
	res->ent         = NULL;
296
297
298
	res->frame_type  = NULL;

	/* the Anchor node must be created first */
299
	res->anchor = new_r_Anchor(res);
300
301

	/* -- The end block -- */
302
	end_block = new_r_Block(res, 0, NULL);
303
	set_irg_end_block(res, end_block);
304
	end = new_r_End(res);
305
	set_irg_end(res, end);
306
307

	/* -- The start block -- */
308
	start_block = new_r_Block(res, 0, NULL);
309
	set_irg_start_block(res, start_block);
310
	bad = new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL);
311
	bad->attr.irg.irg = res;
312
313
314
	set_irg_bad(res, bad);
	no_mem = new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL);
	set_irg_no_mem(res, no_mem);
315
	start = new_r_Start(res);
316
	set_irg_start(res, start);
317
318

	/* Proj results of start node */
319
320
	set_irg_initial_mem(res, new_r_Proj(start, mode_M, pn_Start_M));
	projX = new_r_Proj(start, mode_X, pn_Start_X_initial_exec);
321

322
323
324
	body_block = new_r_Block(res, 1, &projX);

	set_r_cur_block(res, body_block);
325
326

	/* Set the visited flag high enough that the blocks will never be visited. */
327
328
	set_irn_visited(body_block, -1);
	set_Block_block_visited(body_block, -1);
329
330
	set_Block_block_visited(start_block, -1);
	set_irn_visited(start_block, -1);
331
332
	set_irn_visited(bad, -1);
	set_irn_visited(no_mem, -1);
333
334

	return res;
335
336
}

Michael Beck's avatar
Michael Beck committed
337
338
339
340
341
342
343
/**
 * Pre-Walker: Copies blocks and nodes from the original method graph
 * to the copied graph.
 *
 * @param n    A node from the original method graph.
 * @param env  The copied graph.
 */
344
static void copy_all_nodes(ir_node *node, void *env)
345
{
346
347
348
349
	ir_graph *irg      = env;
	ir_node  *new_node = irn_copy_into_irg(node, irg);

	set_irn_link(node, new_node);
Michael Beck's avatar
Michael Beck committed
350
351

	/* fix access to entities on the stack frame */
352
353
354
	if (is_Sel(new_node)) {
		ir_entity *ent = get_Sel_entity(new_node);
		ir_type   *tp  = get_entity_owner(ent);
Michael Beck's avatar
Michael Beck committed
355
356
357
358
359
360
361

		if (is_frame_type(tp)) {
			/* replace by the copied entity */
			ent = get_entity_link(ent);

			assert(is_entity(ent));
			assert(get_entity_owner(ent) == get_irg_frame_type(irg));
362
			set_Sel_entity(new_node, ent);
Michael Beck's avatar
Michael Beck committed
363
364
365
366
367
368
369
370
371
		}
	}
}

/**
 * Post-walker: Set the predecessors of the copied nodes.
 * The copied nodes are set as link of their original nodes. The links of
 * "irn" predecessors are the predecessors of copied node.
 */
372
static void rewire(ir_node *irn, void *env)
373
{
Matthias Braun's avatar
Matthias Braun committed
374
	(void) env;
375
	irn_rewire_inputs(irn);
Michael Beck's avatar
Michael Beck committed
376
377
}

378
379
380
381
static ir_node *get_new_node(const ir_node *old_node)
{
	return (ir_node*) get_irn_link(old_node);
}
Michael Beck's avatar
Michael Beck committed
382
383
384
385

/*
 * Create a new graph that is a copy of a given one.
 */
386
387
ir_graph *create_irg_copy(ir_graph *irg)
{
Michael Beck's avatar
Michael Beck committed
388
389
390
391
392
393
394
	ir_graph *res;

	res = alloc_graph();

	res->n_loc = 0;
	res->visited = 0;       /* visited flag, for the ir walker */
	res->block_visited = 0; /* visited flag, for the 'block'-walker */
395
	res->obst       = XMALLOC(struct obstack);
Michael Beck's avatar
Michael Beck committed
396
397
398
399
400
401
402
403
404
405
	obstack_init(res->obst);
	res->extbb_obst = NULL;

	res->last_node_idx = 0;

	res->phase_state      = irg->phase_state;
	res->irg_pinned_state = irg->irg_pinned_state;
	res->extblk_state     = ir_extblk_info_none;
	res->fp_model         = irg->fp_model;

406
	new_identities(res);
Michael Beck's avatar
Michael Beck committed
407
408

	/* clone the frame type here for safety */
Michael Beck's avatar
Michael Beck committed
409
	irp_reserve_resources(irp, IR_RESOURCE_ENTITY_LINK);
Michael Beck's avatar
Michael Beck committed
410
411
412
413
	res->frame_type  = clone_frame_type(irg->frame_type);

	res->phase_state = irg->phase_state;

414
	ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
Michael Beck's avatar
Michael Beck committed
415
416

	/* copy all nodes from the graph irg to the new graph res */
417
	irg_walk_anchors(irg, copy_all_nodes, rewire, res);
Michael Beck's avatar
Michael Beck committed
418
419

	/* copy the Anchor node */
420
	res->anchor = get_new_node(irg->anchor);
Michael Beck's avatar
Michael Beck committed
421
422

	/* -- The end block -- */
423
424
	set_irg_end_block (res, get_new_node(get_irg_end_block(irg)));
	set_irg_end       (res, get_new_node(get_irg_end(irg)));
Michael Beck's avatar
Michael Beck committed
425
426

	/* -- The start block -- */
427
428
429
430
	set_irg_start_block(res, get_new_node(get_irg_start_block(irg)));
	set_irg_bad        (res, get_new_node(get_irg_bad(irg)));
	set_irg_no_mem     (res, get_new_node(get_irg_no_mem(irg)));
	set_irg_start      (res, get_new_node(get_irg_start(irg)));
Michael Beck's avatar
Michael Beck committed
431
432

	/* Proj results of start node */
433
	set_irg_initial_mem(res, get_new_node(get_irg_initial_mem(irg)));
Michael Beck's avatar
Michael Beck committed
434
435
436
437
438

	/* Copy the node count estimation. Would be strange if this
	   is different from the original one. */
	res->estimated_node_count = irg->estimated_node_count;

439
	ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
Michael Beck's avatar
Michael Beck committed
440
	irp_free_resources(irp, IR_RESOURCE_ENTITY_LINK);
Michael Beck's avatar
Michael Beck committed
441
442
443

	return res;
}
444

445
446
447
/* Frees the passed irgraph.
   Deallocates all nodes in this graph and the ir_graph structure.
   Sets the field irgraph in the corresponding entity to NULL.
448
449
   Does not remove the irgraph from the list in irprog (requires
   inefficient search, call remove_irp_irg by hand).
450
451
   Does not free types, entities or modes that are used only by this
   graph, nor the entity standing for this graph. */
Matthias Braun's avatar
Matthias Braun committed
452
453
void free_ir_graph(ir_graph *irg)
{
454
455
	assert(is_ir_graph(irg));

456
457
	edges_deactivate(irg);

458
	hook_free_graph(irg);
Michael Beck's avatar
Michael Beck committed
459
460
461
462
	if (irg->outs_state != outs_none)
		free_irg_outs(irg);
	if (irg->frame_type)
		free_type(irg->frame_type);
463
	del_identities(irg);
464
465
466
467
468
469
470
471
472
473
474
	if (irg->ent) {
		set_entity_irg(irg->ent, NULL);  /* not set in const code irg */
	}

	free_End(get_irg_end(irg));
	obstack_free(irg->obst,NULL);
	free(irg->obst);
	if (irg->loc_descriptions)
		free(irg->loc_descriptions);
	irg->kind = k_BAD;
	free_graph(irg);
475
476
}

477
478
479
480
/* access routines for all ir_graph attributes:
   templates:
   {attr type} get_irg_{attribute name} (ir_graph *irg);
   void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
Christian Schäfer's avatar
Christian Schäfer committed
481

482
483
int (is_ir_graph)(const void *thing)
{
484
	return _is_ir_graph(thing);
Sebastian Felis's avatar
Sebastian Felis committed
485
486
}

487
#ifdef DEBUG_libfirm
Matthias Braun's avatar
Matthias Braun committed
488
/* Outputs a unique number for this node */
489
490
long get_irg_graph_nr(const ir_graph *irg)
{
491
	return irg->graph_nr;
Matthias Braun's avatar
Matthias Braun committed
492
}
493
#else
494
495
long get_irg_graph_nr(const ir_graph *irg)
{
496
497
	return PTR_TO_INT(irg);
}
498
#endif
Matthias Braun's avatar
Matthias Braun committed
499

500
501
int get_irg_idx(const ir_graph *irg)
{
Matthias Braun's avatar
Matthias Braun committed
502
	return irg->index;
503
504
}

505
506
ir_node *(get_idx_irn)(ir_graph *irg, unsigned idx)
{
507
508
509
	return _get_idx_irn(irg, idx);
}

510
511
ir_node *(get_irg_start_block)(const ir_graph *irg)
{
512
	return _get_irg_start_block(irg);
Christian Schäfer's avatar
Christian Schäfer committed
513
514
}

515
516
void (set_irg_start_block)(ir_graph *irg, ir_node *node)
{
517
	_set_irg_start_block(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
518
519
}

520
521
ir_node *(get_irg_start)(const ir_graph *irg)
{
522
	return _get_irg_start(irg);
Christian Schäfer's avatar
Christian Schäfer committed
523
524
}

525
526
void (set_irg_start)(ir_graph *irg, ir_node *node)
{
527
	_set_irg_start(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
528
529
}

530
531
ir_node *(get_irg_end_block)(const ir_graph *irg)
{
532
	return _get_irg_end_block(irg);
Christian Schäfer's avatar
Christian Schäfer committed
533
534
}

535
536
void (set_irg_end_block)(ir_graph *irg, ir_node *node)
{
537
  _set_irg_end_block(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
538
539
}

540
541
ir_node *(get_irg_end)(const ir_graph *irg)
{
542
	return _get_irg_end(irg);
Christian Schäfer's avatar
Christian Schäfer committed
543
544
}

545
546
void (set_irg_end)(ir_graph *irg, ir_node *node)
{
547
	_set_irg_end(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
548
549
}

550
551
ir_node *(get_irg_initial_exec)(const ir_graph *irg)
{
552
	return _get_irg_initial_exec(irg);
Christian Schäfer's avatar
Christian Schäfer committed
553
554
}

555
556
void (set_irg_initial_exec)(ir_graph *irg, ir_node *node)
{
557
	_set_irg_initial_exec(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
558
559
}

560
561
ir_node *(get_irg_frame)(const ir_graph *irg)
{
562
	return _get_irg_frame(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
563
564
}

565
566
void (set_irg_frame)(ir_graph *irg, ir_node *node)
{
567
	_set_irg_frame(irg, node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
568
569
}

570
571
ir_node *(get_irg_tls)(const ir_graph *irg)
{
572
	return _get_irg_tls(irg);
573
574
}

575
576
void (set_irg_tls)(ir_graph *irg, ir_node *node)
{
577
	_set_irg_tls(irg, node);
578
579
}

580
581
ir_node *(get_irg_initial_mem)(const ir_graph *irg)
{
582
	return _get_irg_initial_mem(irg);
583
584
}

585
586
void (set_irg_initial_mem)(ir_graph *irg, ir_node *node)
{
587
	_set_irg_initial_mem(irg, node);
588
589
}

590
591
ir_node *(get_irg_args)(const ir_graph *irg)
{
592
	return _get_irg_args(irg);
Christian Schäfer's avatar
Christian Schäfer committed
593
594
}

595
596
void (set_irg_args)(ir_graph *irg, ir_node *node)
{
597
	_set_irg_args(irg, node);
598
599
}

600
601
ir_node *(get_irg_bad)(const ir_graph *irg)
{
602
	return _get_irg_bad(irg);
Christian Schäfer's avatar
Christian Schäfer committed
603
604
}

605
606
void (set_irg_bad)(ir_graph *irg, ir_node *node)
{
607
	_set_irg_bad(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
608
609
}

610
611
ir_node *(get_irg_no_mem)(const ir_graph *irg)
{
612
	return _get_irg_no_mem(irg);
613
614
}

615
616
void (set_irg_no_mem)(ir_graph *irg, ir_node *node)
{
617
	_set_irg_no_mem(irg, node);
618
619
}

620
621
ir_entity *(get_irg_entity)(const ir_graph *irg)
{
622
	return _get_irg_entity(irg);
Christian Schäfer's avatar
Christian Schäfer committed
623
624
}

625
626
void (set_irg_entity)(ir_graph *irg, ir_entity *ent)
{
627
	_set_irg_entity(irg, ent);
Christian Schäfer's avatar
Christian Schäfer committed
628
629
}

630
631
ir_type *(get_irg_frame_type)(ir_graph *irg)
{
632
	return _get_irg_frame_type(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
633
634
}

635
636
void (set_irg_frame_type)(ir_graph *irg, ir_type *ftp)
{
637
	_set_irg_frame_type(irg, ftp);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
638
639
}

640
/* Returns the value parameter type of an IR graph. */
641
642
ir_type *get_irg_value_param_type(ir_graph *irg)
{
643
644
645
646
647
	ir_entity *ent = get_irg_entity(irg);
	ir_type   *mtp = get_entity_type(ent);
	return get_method_value_param_type(mtp);
}

648
int get_irg_n_locs(ir_graph *irg)
649
{
650
	return irg->n_loc - 1;
Christian Schäfer's avatar
Christian Schäfer committed
651
652
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
653
/* Returns the obstack associated with the graph. */
654
struct obstack *
Michael Beck's avatar
Michael Beck committed
655
(get_irg_obstack)(const ir_graph *irg) {
656
	return _get_irg_obstack(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
657
658
}

659
660
661
662
663
/*
 * Returns true if the node n is allocated on the storage of graph irg.
 *
 * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
 */
664
665
int node_is_in_irgs_storage(ir_graph *irg, ir_node *n)
{
666
	struct _obstack_chunk *p;
667

668
669
670
671
672
673
674
675
	/*
	 * checks weather the ir_node pointer is on the obstack.
	 * A more sophisticated check would test the "whole" ir_node
	 */
	for (p = irg->obst->chunk; p; p = p->prev) {
		if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
			return 1;
	}
676

677
	return 0;
678
679
}

680
681
irg_phase_state (get_irg_phase_state)(const ir_graph *irg)
{
682
	return _get_irg_phase_state(irg);
683
684
}

685
686
void (set_irg_phase_state)(ir_graph *irg, irg_phase_state state)
{
687
	_set_irg_phase_state(irg, state);
688
689
}

690
691
op_pin_state (get_irg_pinned)(const ir_graph *irg)
{
692
	return _get_irg_pinned(irg);
693
694
}

695
696
irg_outs_state (get_irg_outs_state)(const ir_graph *irg)
{
697
	return _get_irg_outs_state(irg);
698
699
}

700
701
void (set_irg_outs_inconsistent)(ir_graph *irg)
{
702
	_set_irg_outs_inconsistent(irg);
703
704
}

705
706
irg_extblk_state (get_irg_extblk_state)(const ir_graph *irg)
{
707
	return _get_irg_extblk_state(irg);
708
709
}

710
711
void (set_irg_extblk_inconsistent)(ir_graph *irg)
{
712
	_set_irg_extblk_inconsistent(irg);
713
714
}

715
716
irg_dom_state (get_irg_dom_state)(const ir_graph *irg)
{
717
	return _get_irg_dom_state(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
718
719
}

720
721
irg_dom_state (get_irg_postdom_state)(const ir_graph *irg)
{
722
	return _get_irg_postdom_state(irg);
723
724
}

725
726
void (set_irg_doms_inconsistent)(ir_graph *irg)
{
727
	_set_irg_doms_inconsistent(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
728
729
}

730
731
irg_loopinfo_state (get_irg_loopinfo_state)(const ir_graph *irg)
{
732
	return _get_irg_loopinfo_state(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
733
734
}

735
736
void (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s)
{
737
	_set_irg_loopinfo_state(irg, s);
738
739
}

740
741
void (set_irg_loopinfo_inconsistent)(ir_graph *irg)
{
742
	_set_irg_loopinfo_inconsistent(irg);
743
744
}

745
746
void set_irp_loopinfo_inconsistent(void)
{
747
748
749
750
	int i;
	for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
		set_irg_loopinfo_inconsistent(get_irp_irg(i));
	}
751
752
753
754
}



755
756
void (set_irg_pinned)(ir_graph *irg, op_pin_state p)
{
757
	_set_irg_pinned(irg, p);
758
759
}

760
761
irg_callee_info_state (get_irg_callee_info_state)(const ir_graph *irg)
{
762
	return _get_irg_callee_info_state(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
763
764
}

765
766
void (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s)
{
767
	_set_irg_callee_info_state(irg, s);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
768
769
}

770
771
irg_inline_property (get_irg_inline_property)(const ir_graph *irg)
{
772
	return _get_irg_inline_property(irg);
773
774
}

775
776
void (set_irg_inline_property)(ir_graph *irg, irg_inline_property s)
{
777
	_set_irg_inline_property(irg, s);
778
}
779

780
781
unsigned (get_irg_additional_properties)(const ir_graph *irg)
{
782
	return _get_irg_additional_properties(irg);
783
784
}

785
786
void (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask)
{
787
	_set_irg_additional_properties(irg, property_mask);
788
789
}

790
791
void (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag)
{
792
	_set_irg_additional_property(irg, flag);
793
794
}

795
796
void (set_irg_link)(ir_graph *irg, void *thing)
{
797
	_set_irg_link(irg, thing);
798
}
799

800
801
void *(get_irg_link)(const ir_graph *irg)
{
802
	return _get_irg_link(irg);
803
804
}

805
806
ir_visited_t (get_irg_visited)(const ir_graph *irg)
{
807
	return _get_irg_visited(irg);
808
809
}

810
/** maximum visited flag content of all ir_graph visited fields. */
811
static ir_visited_t max_irg_visited = 0;
812

Matthias Braun's avatar
Matthias Braun committed
813
814
void set_irg_visited(ir_graph *irg, ir_visited_t visited)
{
815
816
817
818
	irg->visited = visited;
	if (irg->visited > max_irg_visited) {
		max_irg_visited = irg->visited;
	}
819
820
}

Matthias Braun's avatar
Matthias Braun committed
821
822
823
824
void inc_irg_visited(ir_graph *irg)
{
	++irg->visited;
	if (irg->visited > max_irg_visited) {
825
826
		max_irg_visited = irg->visited;
	}
827
828
}

Matthias Braun's avatar
Matthias Braun committed
829
830
ir_visited_t get_max_irg_visited(void)
{
831
	return max_irg_visited;
832
833
}

Matthias Braun's avatar
Matthias Braun committed
834
835
void set_max_irg_visited(int val)
{
836
	max_irg_visited = val;
837
838
}

Matthias Braun's avatar
Matthias Braun committed
839
840
ir_visited_t inc_max_irg_visited(void)
{
841
#ifndef NDEBUG
842
	int i;
843
	for (i = 0; i < get_irp_n_irgs(); i++)
844
845
		assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
#endif
846
	return ++max_irg_visited;
847
848
}

849
850
ir_visited_t (get_irg_block_visited)(const ir_graph *irg)
{
851
	return _get_irg_block_visited(irg);
852
853
}

854
855
void (set_irg_block_visited)(ir_graph *irg, ir_visited_t visited)
{
856
	_set_irg_block_visited(irg, visited);
857
858
}

859
860
void (inc_irg_block_visited)(ir_graph *irg)
{
861
  _inc_irg_block_visited(irg);
862
}
863

864
/* Return the floating point model of this graph. */
865
866
unsigned (get_irg_fp_model)(const ir_graph *irg)
{
867
	return _get_irg_fp_model(irg);
868
869
870
}

/* Sets the floating point model for this graph. */
871
872
void set_irg_fp_model(ir_graph *irg, unsigned model)
{
873
	irg->fp_model = model;
874
}
875

876
/* set a description for local value n */
877
878
void set_irg_loc_description(ir_graph *irg, int n, void *description)
{
879
	assert(0 <= n && n < irg->n_loc);
880

881
	if (! irg->loc_descriptions)
882
		irg->loc_descriptions = XMALLOCNZ(void*, irg->n_loc);
883

884
	irg->loc_descriptions[n] = description;
885
886
887
}

/* get the description for local value n */
888
889
void *get_irg_loc_description(ir_graph *irg, int n)
{
890
891
	assert(0 <= n && n < irg->n_loc);
	return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
892
}
893

894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
void irg_register_phase(ir_graph *irg, ir_phase_id id, ir_phase *phase)
{
	assert(id <= PHASE_LAST);
	assert(irg->phases[id] == NULL);
	irg->phases[id] = phase;
}

void irg_invalidate_phases(ir_graph *irg)
{
	int p;
	for (p = 0; p <= PHASE_LAST; ++p) {
		ir_phase *phase = irg->phases[p];
		if (phase == NULL)
			continue;

		phase_free(phase);
		irg->phases[p] = NULL;
	}
}

914
#ifndef NDEBUG
915
916
void ir_reserve_resources(ir_graph *irg, ir_resources_t resources)
{
Michael Beck's avatar
Michael Beck committed
917
	assert((resources & ~IR_RESOURCE_LOCAL_MASK) == 0);
918
919
	assert((irg->reserved_resources & resources) == 0);
	irg->reserved_resources |= resources;
920
921
}

922
923
void ir_free_resources(ir_graph *irg, ir_resources_t resources)
{
924
925
	assert((irg->reserved_resources & resources) == resources);
	irg->reserved_resources &= ~resources;
Christian Würdig's avatar