irgraph.c 20.7 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  *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
201
	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->execfreq_state      = exec_freq_none;
	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. --*/
202
	res->frame_type = new_type_frame();
203
204

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	set_r_cur_block(res, body_block);
309
310

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

	return res;
318
319
}

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

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

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

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

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

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

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

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

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

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

	res->phase_state = irg->phase_state;

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

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

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

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

	/* -- The start block -- */
409
410
411
	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
412
413

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

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

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

	return res;
}
425

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

437
438
	edges_deactivate(irg);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

629
	return 0;
630
631
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
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;
	}
}

806
#ifndef NDEBUG
807
808
void ir_reserve_resources(ir_graph *irg, ir_resources_t resources)
{
809
810
	assert((irg->reserved_resources & resources) == 0);
	irg->reserved_resources |= resources;
811
812
}

813
814
void ir_free_resources(ir_graph *irg, ir_resources_t resources)
{
815
816
	assert((irg->reserved_resources & resources) == resources);
	irg->reserved_resources &= ~resources;
817
818
}

819
820
ir_resources_t ir_resources_reserved(const ir_graph *irg)
{
821
	return irg->reserved_resources;
822
823
}
#endif /* NDEBUG */
824

Michael Beck's avatar
Michael Beck committed
825
/* Returns a estimated node count of the irg. */
826
827
unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg)
{
828
	return _get_irg_estimated_node_cnt(irg);
Michael Beck's avatar
Michael Beck committed
829
830
}

831
/* Returns the last irn index for this graph. */
832
833
unsigned get_irg_last_idx(const ir_graph *irg)
{
834
	return irg->last_node_idx;
835
836
}

837
/* register additional space in an IR graph */
838
839
size_t register_additional_graph_data(size_t size)
{
840
	assert(!forbid_new_data && "Too late to register additional node data");
841

842
843
	if (forbid_new_data)
		return 0;
844

845
	return additional_graph_data_size += size;
846
}
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861

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);
}