irgraph.c 20.3 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"
44
#include "util.h"
Michael Beck's avatar
Michael Beck committed
45
#include "irgwalk.h"
Michael Beck's avatar
Michael Beck committed
46
#include "irbackedge_t.h"
Michael Beck's avatar
Michael Beck committed
47
48
#include "iredges_t.h"
#include "type_t.h"
49
#include "irmemory.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  *start, *start_block, *initial_mem, *projX;
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
200
	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->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->class_cast_state    = ir_class_casts_transitive;
	res->fp_model            = fp_model_precise;
	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. --*/
201
	res->frame_type = new_type_frame();
202
203

	/* the Anchor node must be created first */
204
	res->anchor = new_r_Anchor(res);
205
206

	/*-- Nodes needed in every graph --*/
207
	set_irg_end_block (res, new_r_immBlock(res));
208
	set_irg_end(res, new_r_End(res, 0, NULL));
209

210
	start_block = new_r_Block_noopt(res, 0, NULL);
211
	set_irg_start_block(res, start_block);
212
	set_irg_no_mem     (res, new_r_NoMem(res));
213
	start = new_r_Start(res);
214
215
216
	set_irg_start      (res, start);

	/* Proj results of start node */
217
	projX                   = new_r_Proj(start, mode_X, pn_Start_X_initial_exec);
218
	set_irg_initial_exec    (res, projX);
219
220
221
	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);
222
223
	set_irg_initial_mem(res, initial_mem);

Matthias Braun's avatar
Matthias Braun committed
224
	res->index       = get_irp_new_irg_idx();
225
#ifdef DEBUG_libfirm
226
	res->graph_nr    = get_irp_new_node_nr();
227
228
#endif

229
230
	set_r_cur_block(res, start_block);
	set_r_store(res, initial_mem);
Christian Schäfer's avatar
Christian Schäfer committed
231

232
	/*-- Make a block to start with --*/
233
234
	first_block = new_r_immBlock(res);
	set_r_cur_block(res, first_block);
235
	add_immBlock_pred(first_block, projX);
Christian Schäfer's avatar
Christian Schäfer committed
236

237
238
	res->method_execution_frequency = -1.0;
	res->estimated_node_count       = 0;
239

240
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
241
242
}

243
244
ir_graph *new_ir_graph(ir_entity *ent, int n_loc)
{
245
246
247
	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
248
249
}

250
/* Make a rudimentary IR graph for the constant code.
251
   Must look like a correct irg, spare everything else. */
252
253
254
ir_graph *new_const_code_irg(void)
{
	ir_graph *res = alloc_graph();
255
	ir_node  *body_block;
256
257
258
259
260
261
	ir_node  *end;
	ir_node  *end_block;
	ir_node  *no_mem;
	ir_node  *projX;
	ir_node  *start_block;
	ir_node  *start;
262

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

266
267
	res->n_loc         = 1; /* Only the memory. */
	res->visited       = 0; /* visited flag, for the ir walker */
268
	res->block_visited = 0; /* visited flag, for the 'block'-walker */
269
270
	res->obst          = XMALLOC(struct obstack);
	obstack_init(res->obst);
271
272
273
274
275
276
277
278
	res->extbb_obst = NULL;

	res->last_node_idx = 0;

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

279
	/* value table for global value numbering for optimizing use in iropt.c */
280
	new_identities(res);
281
	res->ent         = NULL;
282
283
284
	res->frame_type  = NULL;

	/* the Anchor node must be created first */
285
	res->anchor = new_r_Anchor(res);
286
287

	/* -- The end block -- */
288
	end_block = new_r_Block_noopt(res, 0, NULL);
289
	set_irg_end_block(res, end_block);
290
	end = new_r_End(res, 0, NULL);
291
	set_irg_end(res, end);
292
293

	/* -- The start block -- */
294
	start_block = new_r_Block_noopt(res, 0, NULL);
295
	set_irg_start_block(res, start_block);
296
	no_mem = new_r_NoMem(res);
297
	set_irg_no_mem(res, no_mem);
298
	start = new_r_Start(res);
299
	set_irg_start(res, start);
300
301

	/* Proj results of start node */
302
303
	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);
304

305
306
307
	body_block = new_r_Block(res, 1, &projX);

	set_r_cur_block(res, body_block);
308
309

	/* Set the visited flag high enough that the blocks will never be visited. */
310
311
	set_irn_visited(body_block, -1);
	set_Block_block_visited(body_block, -1);
312
313
	set_Block_block_visited(start_block, -1);
	set_irn_visited(start_block, -1);
314
	set_irn_visited(no_mem, -1);
315
316

	return res;
317
318
}

Michael Beck's avatar
Michael Beck committed
319
320
321
322
323
324
325
/**
 * 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.
 */
326
static void copy_all_nodes(ir_node *node, void *env)
327
{
328
	ir_graph *irg      = (ir_graph*)env;
329
330
331
	ir_node  *new_node = irn_copy_into_irg(node, irg);

	set_irn_link(node, new_node);
Michael Beck's avatar
Michael Beck committed
332
333

	/* fix access to entities on the stack frame */
334
335
336
	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
337
338
339

		if (is_frame_type(tp)) {
			/* replace by the copied entity */
340
			ent = (ir_entity*)get_entity_link(ent);
Michael Beck's avatar
Michael Beck committed
341
342
343

			assert(is_entity(ent));
			assert(get_entity_owner(ent) == get_irg_frame_type(irg));
344
			set_Sel_entity(new_node, ent);
Michael Beck's avatar
Michael Beck committed
345
346
347
348
349
350
351
352
353
		}
	}
}

/**
 * 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.
 */
354
static void rewire(ir_node *irn, void *env)
355
{
Matthias Braun's avatar
Matthias Braun committed
356
	(void) env;
357
	irn_rewire_inputs(irn);
Michael Beck's avatar
Michael Beck committed
358
359
}

360
361
362
363
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
364
365
366
367

/*
 * Create a new graph that is a copy of a given one.
 */
368
369
ir_graph *create_irg_copy(ir_graph *irg)
{
Michael Beck's avatar
Michael Beck committed
370
371
372
373
374
375
376
	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 */
377
	res->obst       = XMALLOC(struct obstack);
Michael Beck's avatar
Michael Beck committed
378
379
380
381
382
383
384
385
386
	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->fp_model         = irg->fp_model;

387
	new_identities(res);
Michael Beck's avatar
Michael Beck committed
388
389

	/* clone the frame type here for safety */
390
	irp_reserve_resources(irp, IRP_RESOURCE_ENTITY_LINK);
Michael Beck's avatar
Michael Beck committed
391
392
393
394
	res->frame_type  = clone_frame_type(irg->frame_type);

	res->phase_state = irg->phase_state;

395
	ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
Michael Beck's avatar
Michael Beck committed
396
397

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

	/* copy the Anchor node */
401
	res->anchor = get_new_node(irg->anchor);
Michael Beck's avatar
Michael Beck committed
402
403

	/* -- The end block -- */
404
405
	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
406
407

	/* -- The start block -- */
408
409
410
	set_irg_start_block(res, get_new_node(get_irg_start_block(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
411
412

	/* Proj results of start node */
413
	set_irg_initial_mem(res, get_new_node(get_irg_initial_mem(irg)));
Michael Beck's avatar
Michael Beck committed
414
415
416
417
418

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

419
	ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
420
	irp_free_resources(irp, IRP_RESOURCE_ENTITY_LINK);
Michael Beck's avatar
Michael Beck committed
421
422
423

	return res;
}
424

425
426
427
/* 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.
428
429
   Does not remove the irgraph from the list in irprog (requires
   inefficient search, call remove_irp_irg by hand).
430
431
   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
432
433
void free_ir_graph(ir_graph *irg)
{
434
435
	assert(is_ir_graph(irg));

436
437
	edges_deactivate(irg);

438
	hook_free_graph(irg);
Andreas Zwinkau's avatar
Andreas Zwinkau committed
439
	free_irg_outs(irg);
Michael Beck's avatar
Michael Beck committed
440
441
	if (irg->frame_type)
		free_type(irg->frame_type);
442
	del_identities(irg);
443
444
445
446
447
448
449
450
451
452
453
	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);
454
455
}

456
457
458
459
/* 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
460

461
462
int (is_ir_graph)(const void *thing)
{
463
	return _is_ir_graph(thing);
Sebastian Felis's avatar
Sebastian Felis committed
464
465
}

466
#ifdef DEBUG_libfirm
Matthias Braun's avatar
Matthias Braun committed
467
/* Outputs a unique number for this node */
468
469
long get_irg_graph_nr(const ir_graph *irg)
{
470
	return irg->graph_nr;
Matthias Braun's avatar
Matthias Braun committed
471
}
472
#else
473
474
long get_irg_graph_nr(const ir_graph *irg)
{
475
476
	return PTR_TO_INT(irg);
}
477
#endif
Matthias Braun's avatar
Matthias Braun committed
478

479
size_t get_irg_idx(const ir_graph *irg)
480
{
Matthias Braun's avatar
Matthias Braun committed
481
	return irg->index;
482
483
}

484
ir_node *(get_idx_irn)(const ir_graph *irg, unsigned idx)
485
{
486
487
488
	return _get_idx_irn(irg, idx);
}

489
490
ir_node *(get_irg_start_block)(const ir_graph *irg)
{
491
	return _get_irg_start_block(irg);
Christian Schäfer's avatar
Christian Schäfer committed
492
493
}

494
495
void (set_irg_start_block)(ir_graph *irg, ir_node *node)
{
496
	_set_irg_start_block(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
497
498
}

499
500
ir_node *(get_irg_start)(const ir_graph *irg)
{
501
	return _get_irg_start(irg);
Christian Schäfer's avatar
Christian Schäfer committed
502
503
}

504
505
void (set_irg_start)(ir_graph *irg, ir_node *node)
{
506
	_set_irg_start(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
507
508
}

509
510
ir_node *(get_irg_end_block)(const ir_graph *irg)
{
511
	return _get_irg_end_block(irg);
Christian Schäfer's avatar
Christian Schäfer committed
512
513
}

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

519
520
ir_node *(get_irg_end)(const ir_graph *irg)
{
521
	return _get_irg_end(irg);
Christian Schäfer's avatar
Christian Schäfer committed
522
523
}

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

529
530
ir_node *(get_irg_initial_exec)(const ir_graph *irg)
{
531
	return _get_irg_initial_exec(irg);
Christian Schäfer's avatar
Christian Schäfer committed
532
533
}

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

539
540
ir_node *(get_irg_frame)(const ir_graph *irg)
{
541
	return _get_irg_frame(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
542
543
}

544
545
void (set_irg_frame)(ir_graph *irg, ir_node *node)
{
546
	_set_irg_frame(irg, node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
547
548
}

549
550
ir_node *(get_irg_initial_mem)(const ir_graph *irg)
{
551
	return _get_irg_initial_mem(irg);
552
553
}

554
555
void (set_irg_initial_mem)(ir_graph *irg, ir_node *node)
{
556
	_set_irg_initial_mem(irg, node);
557
558
}

559
560
ir_node *(get_irg_args)(const ir_graph *irg)
{
561
	return _get_irg_args(irg);
Christian Schäfer's avatar
Christian Schäfer committed
562
563
}

564
565
void (set_irg_args)(ir_graph *irg, ir_node *node)
{
566
	_set_irg_args(irg, node);
567
568
}

569
570
ir_node *(get_irg_no_mem)(const ir_graph *irg)
{
571
	return _get_irg_no_mem(irg);
572
573
}

574
575
void (set_irg_no_mem)(ir_graph *irg, ir_node *node)
{
576
	_set_irg_no_mem(irg, node);
577
578
}

579
580
ir_entity *(get_irg_entity)(const ir_graph *irg)
{
581
	return _get_irg_entity(irg);
Christian Schäfer's avatar
Christian Schäfer committed
582
583
}

584
585
void (set_irg_entity)(ir_graph *irg, ir_entity *ent)
{
586
	_set_irg_entity(irg, ent);
Christian Schäfer's avatar
Christian Schäfer committed
587
588
}

589
590
ir_type *(get_irg_frame_type)(ir_graph *irg)
{
591
	return _get_irg_frame_type(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
592
593
}

594
595
void (set_irg_frame_type)(ir_graph *irg, ir_type *ftp)
{
596
	_set_irg_frame_type(irg, ftp);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
597
598
}

599
int get_irg_n_locs(ir_graph *irg)
600
{
601
	return irg->n_loc - 1;
Christian Schäfer's avatar
Christian Schäfer committed
602
603
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
604
/* Returns the obstack associated with the graph. */
605
struct obstack *
Michael Beck's avatar
Michael Beck committed
606
(get_irg_obstack)(const ir_graph *irg) {
607
	return _get_irg_obstack(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
608
609
}

610
611
612
613
614
/*
 * 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.
 */
615
int node_is_in_irgs_storage(const ir_graph *irg, const ir_node *n)
616
{
617
	struct _obstack_chunk *p;
618

619
620
621
622
623
624
625
626
	/*
	 * 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;
	}
627

628
	return 0;
629
630
}

631
632
irg_phase_state (get_irg_phase_state)(const ir_graph *irg)
{
633
	return _get_irg_phase_state(irg);
634
635
}

636
637
void (set_irg_phase_state)(ir_graph *irg, irg_phase_state state)
{
638
	_set_irg_phase_state(irg, state);
639
640
}

641
642
op_pin_state (get_irg_pinned)(const ir_graph *irg)
{
643
	return _get_irg_pinned(irg);
644
645
}

646
647
void (set_irg_pinned)(ir_graph *irg, op_pin_state p)
{
648
	_set_irg_pinned(irg, p);
649
650
}

651
652
irg_callee_info_state (get_irg_callee_info_state)(const ir_graph *irg)
{
653
	return _get_irg_callee_info_state(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
654
655
}

656
657
void (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s)
{
658
	_set_irg_callee_info_state(irg, s);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
659
660
}

661
662
irg_inline_property (get_irg_inline_property)(const ir_graph *irg)
{
663
	return _get_irg_inline_property(irg);
664
665
}

666
667
void (set_irg_inline_property)(ir_graph *irg, irg_inline_property s)
{
668
	_set_irg_inline_property(irg, s);
669
}
670

671
mtp_additional_properties (get_irg_additional_properties)(const ir_graph *irg)
672
{
673
	return _get_irg_additional_properties(irg);
674
675
}

676
void (set_irg_additional_properties)(ir_graph *irg, mtp_additional_properties property_mask)
677
{
678
	_set_irg_additional_properties(irg, property_mask);
679
680
}

681
void (add_irg_additional_properties)(ir_graph *irg, mtp_additional_properties flag)
682
{
683
	_add_irg_additional_properties(irg, flag);
684
685
}

686
687
void (set_irg_link)(ir_graph *irg, void *thing)
{
688
	_set_irg_link(irg, thing);
689
}
690

691
692
void *(get_irg_link)(const ir_graph *irg)
{
693
	return _get_irg_link(irg);
694
695
}

696
697
ir_visited_t (get_irg_visited)(const ir_graph *irg)
{
698
	return _get_irg_visited(irg);
699
700
}

701
/** maximum visited flag content of all ir_graph visited fields. */
702
static ir_visited_t max_irg_visited = 0;
703

Matthias Braun's avatar
Matthias Braun committed
704
705
void set_irg_visited(ir_graph *irg, ir_visited_t visited)
{
706
707
708
709
	irg->visited = visited;
	if (irg->visited > max_irg_visited) {
		max_irg_visited = irg->visited;
	}
710
711
}

Matthias Braun's avatar
Matthias Braun committed
712
713
714
715
void inc_irg_visited(ir_graph *irg)
{
	++irg->visited;
	if (irg->visited > max_irg_visited) {
716
717
		max_irg_visited = irg->visited;
	}
718
719
}

Matthias Braun's avatar
Matthias Braun committed
720
721
ir_visited_t get_max_irg_visited(void)
{
722
	return max_irg_visited;
723
724
}

Matthias Braun's avatar
Matthias Braun committed
725
726
void set_max_irg_visited(int val)
{
727
	max_irg_visited = val;
728
729
}

Matthias Braun's avatar
Matthias Braun committed
730
731
ir_visited_t inc_max_irg_visited(void)
{
732
#ifndef NDEBUG
Matthias Braun's avatar
Matthias Braun committed
733
	size_t i;
734
	for (i = 0; i < get_irp_n_irgs(); i++)
735
736
		assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
#endif
737
	return ++max_irg_visited;
738
739
}

740
741
ir_visited_t (get_irg_block_visited)(const ir_graph *irg)
{
742
	return _get_irg_block_visited(irg);
743
744
}

745
746
void (set_irg_block_visited)(ir_graph *irg, ir_visited_t visited)
{
747
	_set_irg_block_visited(irg, visited);
748
749
}

750
751
void (inc_irg_block_visited)(ir_graph *irg)
{
752
  _inc_irg_block_visited(irg);
753
}
754

755
/* Return the floating point model of this graph. */
756
757
unsigned (get_irg_fp_model)(const ir_graph *irg)
{
758
	return _get_irg_fp_model(irg);
759
760
761
}

/* Sets the floating point model for this graph. */
762
763
void set_irg_fp_model(ir_graph *irg, unsigned model)
{
764
	irg->fp_model = model;
765
}
766

767
/* set a description for local value n */
768
769
void set_irg_loc_description(ir_graph *irg, int n, void *description)
{
770
	assert(0 <= n && n < irg->n_loc);
771

772
	if (! irg->loc_descriptions)
773
		irg->loc_descriptions = XMALLOCNZ(void*, irg->n_loc);
774

775
	irg->loc_descriptions[n] = description;
776
777
778
}

/* get the description for local value n */
779
780
void *get_irg_loc_description(ir_graph *irg, int n)
{
781
782
	assert(0 <= n && n < irg->n_loc);
	return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
783
}
784

785
#ifndef NDEBUG
786
787
void ir_reserve_resources(ir_graph *irg, ir_resources_t resources)
{
788
789
	assert((irg->reserved_resources & resources) == 0);
	irg->reserved_resources |= resources;
790
791
}

792
793
void ir_free_resources(ir_graph *irg, ir_resources_t resources)
{
794
795
	assert((irg->reserved_resources & resources) == resources);
	irg->reserved_resources &= ~resources;
796
797
}

798
799
ir_resources_t ir_resources_reserved(const ir_graph *irg)
{
800
	return irg->reserved_resources;
801
802
}
#endif /* NDEBUG */
803

Michael Beck's avatar
Michael Beck committed
804
/* Returns a estimated node count of the irg. */
805
806
unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg)
{
807
	return _get_irg_estimated_node_cnt(irg);
Michael Beck's avatar
Michael Beck committed
808
809
}

810
/* Returns the last irn index for this graph. */
811
812
unsigned get_irg_last_idx(const ir_graph *irg)
{
813
	return irg->last_node_idx;
814
815
}

816
/* register additional space in an IR graph */
817
818
size_t register_additional_graph_data(size_t size)
{
819
	assert(!forbid_new_data && "Too late to register additional node data");
820

821
822
	if (forbid_new_data)
		return 0;
823

824
	return additional_graph_data_size += size;
825
}
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840

void (set_irg_state)(ir_graph *irg, ir_graph_state_t state)
{
	_set_irg_state(irg, state);
}

void (clear_irg_state)(ir_graph *irg, ir_graph_state_t state)
{
	_clear_irg_state(irg, state);
}

int (is_irg_state)(const ir_graph *irg, ir_graph_state_t state)
{
	return _is_irg_state(irg, state);
}