irgraph.c 22.8 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2011 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
115
	char           *ptr = (char *)irg;
	ir_edge_kind_t  i;
116

117
	for (i = EDGE_KIND_FIRST; i < EDGE_KIND_LAST; ++i)
118
		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
/* Allocates a list of nodes:
145
    - The start block containing a start node and Proj nodes for its four
Christian Schäfer's avatar
Christian Schäfer committed
146
147
148
149
150
151
152
      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
	set_irg_end_block (res, new_r_immBlock(res));
215
	end = new_r_End(res, 0, NULL);
216
	set_irg_end(res, end);
217

218
	start_block = new_r_Block_noopt(res, 0, NULL);
219
	set_irg_start_block(res, start_block);
220
	bad = new_r_Bad(res);
221
	set_irg_bad        (res, bad);
222
	set_irg_no_mem     (res, new_r_NoMem(res));
223
	start = new_r_Start(res);
224
225
226
	set_irg_start      (res, start);

	/* Proj results of start node */
227
	projX                   = new_r_Proj(start, mode_X, pn_Start_X_initial_exec);
228
	set_irg_initial_exec    (res, projX);
229
230
231
	set_irg_frame           (res, new_r_Proj(start, mode_P_data, pn_Start_P_frame_base));
	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);
232
233
	set_irg_initial_mem(res, initial_mem);

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

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

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

247
248
	res->method_execution_frequency = -1.0;
	res->estimated_node_count       = 0;
249

250
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
251
252
}

253
254
ir_graph *new_ir_graph(ir_entity *ent, int n_loc)
{
255
256
257
	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
258
259
}

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

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

277
278
	res->n_loc         = 1; /* Only the memory. */
	res->visited       = 0; /* visited flag, for the ir walker */
279
	res->block_visited = 0; /* visited flag, for the 'block'-walker */
280
281
	res->obst          = XMALLOC(struct obstack);
	obstack_init(res->obst);
282
283
284
285
286
287
288
289
290
	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;

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

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

	/* -- The end block -- */
300
	end_block = new_r_Block_noopt(res, 0, NULL);
301
	set_irg_end_block(res, end_block);
302
	end = new_r_End(res, 0, NULL);
303
	set_irg_end(res, end);
304
305

	/* -- The start block -- */
306
	start_block = new_r_Block_noopt(res, 0, NULL);
307
	set_irg_start_block(res, start_block);
308
	bad = new_r_Bad(res);
309
	set_irg_bad(res, bad);
310
	no_mem = new_r_NoMem(res);
311
	set_irg_no_mem(res, no_mem);
312
	start = new_r_Start(res);
313
	set_irg_start(res, start);
314
315

	/* Proj results of start node */
316
317
	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);
318

319
320
321
	body_block = new_r_Block(res, 1, &projX);

	set_r_cur_block(res, body_block);
322
323

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

	return res;
332
333
}

Michael Beck's avatar
Michael Beck committed
334
335
336
337
338
339
340
/**
 * 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.
 */
341
static void copy_all_nodes(ir_node *node, void *env)
342
{
343
	ir_graph *irg      = (ir_graph*)env;
344
345
346
	ir_node  *new_node = irn_copy_into_irg(node, irg);

	set_irn_link(node, new_node);
Michael Beck's avatar
Michael Beck committed
347
348

	/* fix access to entities on the stack frame */
349
350
351
	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
352
353
354

		if (is_frame_type(tp)) {
			/* replace by the copied entity */
355
			ent = (ir_entity*)get_entity_link(ent);
Michael Beck's avatar
Michael Beck committed
356
357
358

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

/**
 * 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.
 */
369
static void rewire(ir_node *irn, void *env)
370
{
Matthias Braun's avatar
Matthias Braun committed
371
	(void) env;
372
	irn_rewire_inputs(irn);
Michael Beck's avatar
Michael Beck committed
373
374
}

375
376
377
378
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
379
380
381
382

/*
 * Create a new graph that is a copy of a given one.
 */
383
384
ir_graph *create_irg_copy(ir_graph *irg)
{
Michael Beck's avatar
Michael Beck committed
385
386
387
388
389
390
391
	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 */
392
	res->obst       = XMALLOC(struct obstack);
Michael Beck's avatar
Michael Beck committed
393
394
395
396
397
398
399
400
401
402
	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;

403
	new_identities(res);
Michael Beck's avatar
Michael Beck committed
404
405

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

	res->phase_state = irg->phase_state;

411
	ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
Michael Beck's avatar
Michael Beck committed
412
413

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

	/* copy the Anchor node */
417
	res->anchor = get_new_node(irg->anchor);
Michael Beck's avatar
Michael Beck committed
418
419

	/* -- The end block -- */
420
421
	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
422
423

	/* -- The start block -- */
424
425
426
427
	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
428
429

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

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

436
	ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
Michael Beck's avatar
Michael Beck committed
437
	irp_free_resources(irp, IR_RESOURCE_ENTITY_LINK);
Michael Beck's avatar
Michael Beck committed
438
439
440

	return res;
}
441

442
443
444
/* 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.
445
446
   Does not remove the irgraph from the list in irprog (requires
   inefficient search, call remove_irp_irg by hand).
447
448
   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
449
450
void free_ir_graph(ir_graph *irg)
{
451
452
	assert(is_ir_graph(irg));

453
454
	edges_deactivate(irg);

455
	hook_free_graph(irg);
Michael Beck's avatar
Michael Beck committed
456
457
458
459
	if (irg->outs_state != outs_none)
		free_irg_outs(irg);
	if (irg->frame_type)
		free_type(irg->frame_type);
460
	del_identities(irg);
461
462
463
464
465
466
467
468
469
470
471
	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);
472
473
}

474
475
476
477
/* 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
478

479
480
int (is_ir_graph)(const void *thing)
{
481
	return _is_ir_graph(thing);
Sebastian Felis's avatar
Sebastian Felis committed
482
483
}

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

497
498
int get_irg_idx(const ir_graph *irg)
{
Matthias Braun's avatar
Matthias Braun committed
499
	return irg->index;
500
501
}

502
503
ir_node *(get_idx_irn)(ir_graph *irg, unsigned idx)
{
504
505
506
	return _get_idx_irn(irg, idx);
}

507
508
ir_node *(get_irg_start_block)(const ir_graph *irg)
{
509
	return _get_irg_start_block(irg);
Christian Schäfer's avatar
Christian Schäfer committed
510
511
}

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

517
518
ir_node *(get_irg_start)(const ir_graph *irg)
{
519
	return _get_irg_start(irg);
Christian Schäfer's avatar
Christian Schäfer committed
520
521
}

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

527
528
ir_node *(get_irg_end_block)(const ir_graph *irg)
{
529
	return _get_irg_end_block(irg);
Christian Schäfer's avatar
Christian Schäfer committed
530
531
}

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

537
538
ir_node *(get_irg_end)(const ir_graph *irg)
{
539
	return _get_irg_end(irg);
Christian Schäfer's avatar
Christian Schäfer committed
540
541
}

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

547
548
ir_node *(get_irg_initial_exec)(const ir_graph *irg)
{
549
	return _get_irg_initial_exec(irg);
Christian Schäfer's avatar
Christian Schäfer committed
550
551
}

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

557
558
ir_node *(get_irg_frame)(const ir_graph *irg)
{
559
	return _get_irg_frame(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
560
561
}

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

567
568
ir_node *(get_irg_initial_mem)(const ir_graph *irg)
{
569
	return _get_irg_initial_mem(irg);
570
571
}

572
573
void (set_irg_initial_mem)(ir_graph *irg, ir_node *node)
{
574
	_set_irg_initial_mem(irg, node);
575
576
}

577
578
ir_node *(get_irg_args)(const ir_graph *irg)
{
579
	return _get_irg_args(irg);
Christian Schäfer's avatar
Christian Schäfer committed
580
581
}

582
583
void (set_irg_args)(ir_graph *irg, ir_node *node)
{
584
	_set_irg_args(irg, node);
585
586
}

587
588
ir_node *(get_irg_bad)(const ir_graph *irg)
{
589
	return _get_irg_bad(irg);
Christian Schäfer's avatar
Christian Schäfer committed
590
591
}

592
593
void (set_irg_bad)(ir_graph *irg, ir_node *node)
{
594
	_set_irg_bad(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
595
596
}

597
598
ir_node *(get_irg_no_mem)(const ir_graph *irg)
{
599
	return _get_irg_no_mem(irg);
600
601
}

602
603
void (set_irg_no_mem)(ir_graph *irg, ir_node *node)
{
604
	_set_irg_no_mem(irg, node);
605
606
}

607
608
ir_entity *(get_irg_entity)(const ir_graph *irg)
{
609
	return _get_irg_entity(irg);
Christian Schäfer's avatar
Christian Schäfer committed
610
611
}

612
613
void (set_irg_entity)(ir_graph *irg, ir_entity *ent)
{
614
	_set_irg_entity(irg, ent);
Christian Schäfer's avatar
Christian Schäfer committed
615
616
}

617
618
ir_type *(get_irg_frame_type)(ir_graph *irg)
{
619
	return _get_irg_frame_type(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
620
621
}

622
623
void (set_irg_frame_type)(ir_graph *irg, ir_type *ftp)
{
624
	_set_irg_frame_type(irg, ftp);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
625
626
}

627
/* Returns the value parameter type of an IR graph. */
628
629
ir_type *get_irg_value_param_type(ir_graph *irg)
{
630
631
632
633
634
	ir_entity *ent = get_irg_entity(irg);
	ir_type   *mtp = get_entity_type(ent);
	return get_method_value_param_type(mtp);
}

635
int get_irg_n_locs(ir_graph *irg)
636
{
637
	return irg->n_loc - 1;
Christian Schäfer's avatar
Christian Schäfer committed
638
639
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
640
/* Returns the obstack associated with the graph. */
641
struct obstack *
Michael Beck's avatar
Michael Beck committed
642
(get_irg_obstack)(const ir_graph *irg) {
643
	return _get_irg_obstack(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
644
645
}

646
647
648
649
650
/*
 * 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.
 */
651
652
int node_is_in_irgs_storage(ir_graph *irg, ir_node *n)
{
653
	struct _obstack_chunk *p;
654

655
656
657
658
659
660
661
662
	/*
	 * 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;
	}
663

664
	return 0;
665
666
}

667
668
irg_phase_state (get_irg_phase_state)(const ir_graph *irg)
{
669
	return _get_irg_phase_state(irg);
670
671
}

672
673
void (set_irg_phase_state)(ir_graph *irg, irg_phase_state state)
{
674
	_set_irg_phase_state(irg, state);
675
676
}

677
678
op_pin_state (get_irg_pinned)(const ir_graph *irg)
{
679
	return _get_irg_pinned(irg);
680
681
}

682
683
irg_outs_state (get_irg_outs_state)(const ir_graph *irg)
{
684
	return _get_irg_outs_state(irg);
685
686
}

687
688
void (set_irg_outs_inconsistent)(ir_graph *irg)
{
689
	_set_irg_outs_inconsistent(irg);
690
691
}

692
irg_extblk_info_state (get_irg_extblk_state)(const ir_graph *irg)
693
{
694
	return _get_irg_extblk_state(irg);
695
696
}

697
698
void (set_irg_extblk_inconsistent)(ir_graph *irg)
{
699
	_set_irg_extblk_inconsistent(irg);
700
701
}

702
703
irg_dom_state (get_irg_dom_state)(const ir_graph *irg)
{
704
	return _get_irg_dom_state(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
705
706
}

707
708
irg_dom_state (get_irg_postdom_state)(const ir_graph *irg)
{
709
	return _get_irg_postdom_state(irg);
710
711
}

712
713
void (set_irg_doms_inconsistent)(ir_graph *irg)
{
714
	_set_irg_doms_inconsistent(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
715
716
}

717
718
irg_loopinfo_state (get_irg_loopinfo_state)(const ir_graph *irg)
{
719
	return _get_irg_loopinfo_state(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
720
721
}

722
723
void (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s)
{
724
	_set_irg_loopinfo_state(irg, s);
725
726
}

727
728
void (set_irg_loopinfo_inconsistent)(ir_graph *irg)
{
729
	_set_irg_loopinfo_inconsistent(irg);
730
731
}

732
733
void set_irp_loopinfo_inconsistent(void)
{
Michael Beck's avatar
Michael Beck committed
734
735
	size_t i, n;
	for (i = 0, n = get_irp_n_irgs(); i < n; ++i) {
736
737
		set_irg_loopinfo_inconsistent(get_irp_irg(i));
	}
738
739
740
741
}



742
743
void (set_irg_pinned)(ir_graph *irg, op_pin_state p)
{
744
	_set_irg_pinned(irg, p);
745
746
}

747
748
irg_callee_info_state (get_irg_callee_info_state)(const ir_graph *irg)
{
749
	return _get_irg_callee_info_state(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
750
751
}

752
753
void (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s)
{
754
	_set_irg_callee_info_state(irg, s);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
755
756
}

757
758
irg_inline_property (get_irg_inline_property)(const ir_graph *irg)
{
759
	return _get_irg_inline_property(irg);
760
761
}

762
763
void (set_irg_inline_property)(ir_graph *irg, irg_inline_property s)
{
764
	_set_irg_inline_property(irg, s);
765
}
766

767
mtp_additional_properties (get_irg_additional_properties)(const ir_graph *irg)
768
{
769
	return _get_irg_additional_properties(irg);
770
771
}

772
void (set_irg_additional_properties)(ir_graph *irg, mtp_additional_properties property_mask)
773
{
774
	_set_irg_additional_properties(irg, property_mask);
775
776
}

777
void (add_irg_additional_properties)(ir_graph *irg, mtp_additional_properties flag)
778
{
779
	_add_irg_additional_properties(irg, flag);
780
781
}

782
783
void (set_irg_link)(ir_graph *irg, void *thing)
{
784
	_set_irg_link(irg, thing);
785
}
786

787
788
void *(get_irg_link)(const ir_graph *irg)
{
789
	return _get_irg_link(irg);
790
791
}

792
793
ir_visited_t (get_irg_visited)(const ir_graph *irg)
{
794
	return _get_irg_visited(irg);
795
796
}

797
/** maximum visited flag content of all ir_graph visited fields. */
798
static ir_visited_t max_irg_visited = 0;
799

Matthias Braun's avatar
Matthias Braun committed
800
801
void set_irg_visited(ir_graph *irg, ir_visited_t visited)
{
802
803
804
805
	irg->visited = visited;
	if (irg->visited > max_irg_visited) {
		max_irg_visited = irg->visited;
	}
806
807
}

Matthias Braun's avatar
Matthias Braun committed
808
809
810
811
void inc_irg_visited(ir_graph *irg)
{
	++irg->visited;
	if (irg->visited > max_irg_visited) {
812
813
		max_irg_visited = irg->visited;
	}
814
815
}

Matthias Braun's avatar
Matthias Braun committed
816
817
ir_visited_t get_max_irg_visited(void)
{
818
	return max_irg_visited;
819
820
}

Matthias Braun's avatar
Matthias Braun committed
821
822
void set_max_irg_visited(int val)
{
823
	max_irg_visited = val;
824
825
}

Matthias Braun's avatar
Matthias Braun committed
826
827
ir_visited_t inc_max_irg_visited(void)
{
828
#ifndef NDEBUG
Matthias Braun's avatar
Matthias Braun committed
829
	size_t i;
830
	for (i = 0; i < get_irp_n_irgs(); i++)
831
832
		assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
#endif
833
	return ++max_irg_visited;
834
835
}

836
837
ir_visited_t (get_irg_block_visited)(const ir_graph *irg)
{
838
	return _get_irg_block_visited(irg);
839
840
}

841
842
void (set_irg_block_visited)(ir_graph *irg, ir_visited_t visited)
{
843
	_set_irg_block_visited(irg, visited);
844
845
}

846
847
void (inc_irg_block_visited)(ir_graph *irg)
{
848
  _inc_irg_block_visited(irg);
849
}
850

851
/* Return the floating point model of this graph. */
852
853
unsigned (get_irg_fp_model)(const ir_graph *irg)
{
854
	return _get_irg_fp_model(irg);
855
856
857
}

/* Sets the floating point model for this graph. */
858
859
void set_irg_fp_model(ir_graph *irg, unsigned model)
{
860
	irg->fp_model = model;
861
}
862

863
/* set a description for local value n */
864
865
void set_irg_loc_description(ir_graph *irg, int n, void *description)
{
866
	assert(0 <= n && n < irg->n_loc);
867

868
	if (! irg->loc_descriptions)
869
		irg->loc_descriptions = XMALLOCNZ(void*, irg->n_loc);
870

871
	irg->loc_descriptions[n] = description;
872
873
874
}

/* get the description for local value n */
875
876
void *get_irg_loc_description(ir_graph *irg, int n)
{
877
878
	assert(0 <= n && n < irg->n_loc);
	return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
879
}
880

881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
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;
	}
}

901
#ifndef NDEBUG
902
903
void ir_reserve_resources(ir_graph *irg, ir_resources_t resources)
{
Michael Beck's avatar
Michael Beck committed
904
	assert((resources & ~IR_RESOURCE_LOCAL_MASK) == 0);
905
906