irgraph.c 27.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-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
 */
Boris Boesler's avatar
added    
Boris Boesler committed
26
#ifdef HAVE_CONFIG_H
Michael Beck's avatar
Michael Beck committed
27
# include "config.h"
Boris Boesler's avatar
added    
Boris Boesler committed
28
29
#endif

Michael Beck's avatar
Michael Beck committed
30
#ifdef HAVE_STRING_H
31
# include <string.h>
Michael Beck's avatar
Michael Beck committed
32
#endif
33
34
35
#ifdef HAVE_STDDEF_H
# include <stddef.h>
#endif
36

Michael Beck's avatar
Michael Beck committed
37
#include "xmalloc.h"
38
#include "ircons_t.h"
Michael Beck's avatar
Michael Beck committed
39
40
#include "irgraph_t.h"
#include "irprog_t.h"
41
#include "irgraph_t.h"
Michael Beck's avatar
Michael Beck committed
42
43
44
45
46
47
48
#include "irnode_t.h"
#include "iropt_t.h"
#include "irflag_t.h"
#include "array.h"
#include "irgmod.h"
#include "irouts.h"
#include "irhooks.h"
49
#include "irtools.h"
Michael Beck's avatar
Michael Beck committed
50
#include "irgwalk.h"
Michael Beck's avatar
Michael Beck committed
51
#include "irbackedge_t.h"
Michael Beck's avatar
Michael Beck committed
52
53
#include "iredges_t.h"
#include "type_t.h"
54
#include "irmemory.h"
Christian Schäfer's avatar
Christian Schäfer committed
55

56
57
#define INITIAL_IDX_IRN_MAP_SIZE 1024

58
59
60
61
62
63
64
65
66
67
68
69
/**
 * 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
70
ir_graph *current_ir_graph;
71
ir_graph *get_current_ir_graph(void) {
72
	return current_ir_graph;
73
}
74

75
void set_current_ir_graph(ir_graph *graph) {
76
	current_ir_graph = graph;
77
78
}

79
#ifdef INTERPROCEDURAL_VIEW
80
int firm_interprocedural_view = 0;
81
82

int (get_interprocedural_view)(void) {
83
	return _get_interprocedural_view();
84
}
85
86

void (set_interprocedural_view)(int state) {
87
	firm_interprocedural_view = state;
88

89
90
91
92
93
94
95
96
97
	/* set function vectors for faster access */
	if (state) {
		_get_irn_arity = _get_irn_inter_arity;
		_get_irn_n     = _get_irn_inter_n;
	}
	else {
		_get_irn_arity = _get_irn_intra_arity;
		_get_irn_n     = _get_irn_intra_n;
	}
98
}
99
#endif
100

101
102
103
104
/** contains the suffix for frame type names */
static ident *frame_type_suffix = NULL;

/* initialize the IR graph module */
105
void firm_init_irgraph(void) {
106
107
	frame_type_suffix = new_id_from_str(FRAME_TP_SUFFIX);
	forbid_new_data   = 1;
108
109
110
}

/**
111
 * Allocate a new IR graph.
112
113
114
115
116
 * 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.
 */
117
static ir_graph *alloc_graph(void) {
Michael Beck's avatar
Michael Beck committed
118
119
120
	ir_graph *res;
	size_t   size = sizeof(ir_graph) + additional_graph_data_size;
	char     *ptr = xmalloc(size);
121
	memset(ptr, 0, size);
122

Michael Beck's avatar
Michael Beck committed
123
124
125
126
127
128
129
130
	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;
131
}
132

133
134
135
136
/**
 * Frees an allocated IR graph
 */
static void free_graph(ir_graph *irg) {
137
138
	char *ptr = (char *)irg;
	free(ptr - additional_graph_data_size);
139
140
}

141
#if USE_EXPLICIT_PHI_IN_STACK
Götz Lindenmaier's avatar
Götz Lindenmaier committed
142
143
144
/* really defined in ircons.c */
typedef struct Phi_in_stack Phi_in_stack;
Phi_in_stack *new_Phi_in_stack();
145
void free_Phi_in_stack(Phi_in_stack *s);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
146
147
#endif

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/**
 * Set the number of locals for a given graph.
 *
 * @param irg    the graph
 * @param n_loc  number of locals
 */
void irg_set_nloc(ir_graph *res, int n_loc) {
	assert(res->phase_state == phase_building);

	if (get_opt_precise_exc_context()) {
		res->n_loc = n_loc + 1 + 1; /* number of local variables that are never
		                               dereferenced in this graph plus one for
		                               the store plus one for links to fragile
		                               operations.  n_loc is not the number of
		                               parameters to the procedure!  */
	} else {
		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!  */
	}
}

Christian Schäfer's avatar
Christian Schäfer committed
171
172
173
174
175
176
177
178
179
/* 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.
*/
180
181
182
183
184
185
186
187
188
189
190
191
192
ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc) {
	ir_graph *res;
	ir_node  *first_block;
	ir_node  *end, *start, *start_block, *initial_mem, *projX;

	res = alloc_graph();

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

	current_ir_graph = res;

	/*-- initialized for each graph. --*/
193
194
195
196
197
198
	res->kind = k_ir_graph;
	res->obst = xmalloc (sizeof(*res->obst));
	obstack_init(res->obst);

	res->phase_state = phase_building;
	irg_set_nloc(res, n_loc);
199
200
201
202
203
204

	/* 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 */
205

206
#if USE_EXPLICIT_PHI_IN_STACK
207
208
	res->Phi_in_stack = new_Phi_in_stack();  /* A stack needed for automatic Phi
	                                            generation */
Christian Schäfer's avatar
Christian Schäfer committed
209
#endif
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
	res->extbb_obst = NULL;

	res->last_node_idx = 0;

	res->value_table = new_identities (); /* value table for global value
	                                         numbering for optimizing use in iropt.c */
	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;
	res->adr_taken_state     = ir_address_taken_not_computed;
	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. --*/
	res->frame_type = new_type_frame(mangle(get_entity_ident(ent), frame_type_suffix));

	/* the Anchor node must be created first */
	res->anchor = new_Anchor(res);

	/*-- Nodes needed in every graph --*/
	set_irg_end_block (res, new_immBlock());
	end               = new_End();
	set_irg_end       (res, end);
	set_irg_end_reg   (res, end);
	set_irg_end_except(res, end);

	start_block = new_immBlock();
	set_irg_start_block(res, start_block);
	set_irg_bad        (res, new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL));
	set_irg_no_mem     (res, new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
	start = new_Start();
	set_irg_start      (res, start);

	/* Proj results of start node */
	projX                   = new_Proj(start, mode_X, pn_Start_X_initial_exec);
	set_irg_frame           (res, new_Proj(start, mode_P_data, pn_Start_P_frame_base));
	set_irg_globals         (res, new_Proj(start, mode_P_data, pn_Start_P_globals));
	set_irg_tls             (res, new_Proj(start, mode_P_data, pn_Start_P_tls));
	set_irg_args            (res, new_Proj(start, mode_T,      pn_Start_T_args));
	set_irg_value_param_base(res, new_Proj(start, mode_P_data, pn_Start_P_value_arg_base));
	initial_mem             = new_Proj(start, mode_M, pn_Start_M);
	set_irg_initial_mem(res, initial_mem);

	add_immBlock_pred(start_block, projX);
	set_store(initial_mem);
272

Matthias Braun's avatar
Matthias Braun committed
273
	res->index       = get_irp_new_irg_idx();
274
#ifdef DEBUG_libfirm
275
	res->graph_nr    = get_irp_new_node_nr();
276
277
#endif

278
279
280
281
282
283
	/*
	 * The code generation needs it. leave it in now.
	 * Use of this edge is matter of discussion, unresolved. Also possible:
	 * add_immBlock_pred(res->start_block, res->start_block), but invalid typed.
	 */
	mature_immBlock(res->current_block);
Christian Schäfer's avatar
Christian Schäfer committed
284

285
286
287
	/*-- Make a block to start with --*/
	first_block = new_immBlock();
	add_immBlock_pred(first_block, projX);
Christian Schäfer's avatar
Christian Schäfer committed
288

289
290
	res->method_execution_frequency = -1.0;
	res->estimated_node_count       = 0;
291

292
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
293
294
}

Michael Beck's avatar
Michael Beck committed
295
ir_graph *new_ir_graph(ir_entity *ent, int n_loc) {
296
297
298
	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
299
300
}

301
/* Make a rudimentary IR graph for the constant code.
302
   Must look like a correct irg, spare everything else. */
303
ir_graph *new_const_code_irg(void) {
304
305
	ir_graph *res;
	ir_node  *end, *start_block, *start, *projX;
306

307
	res = alloc_graph();
308

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

312
313
314
315
	current_ir_graph = res;
	res->n_loc = 1;         /* Only the memory. */
	res->visited = 0;       /* visited flag, for the ir walker */
	res->block_visited = 0; /* visited flag, for the 'block'-walker */
316
#if USE_EXPLICIT_PHI_IN_STACK
317
	res->Phi_in_stack = NULL;
318
#endif
Michael Beck's avatar
Michael Beck committed
319
	res->obst       = xmalloc(sizeof(*res->obst));
320
321
322
323
324
325
326
327
328
329
	obstack_init (res->obst);
	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;

Michael Beck's avatar
Michael Beck committed
330
	res->value_table = new_identities(); /* value table for global value
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
					   numbering for optimizing use in
					   iropt.c */
	res->ent = NULL;
	res->frame_type  = NULL;

	/* the Anchor node must be created first */
	res->anchor = new_Anchor(res);

	/* -- The end block -- */
	set_irg_end_block (res, new_immBlock());
	end = new_End();
	set_irg_end       (res, end);
	set_irg_end_reg   (res, end);
	set_irg_end_except(res, end);
	mature_immBlock(get_cur_block());  /* mature the end block */

	/* -- The start block -- */
	start_block        = new_immBlock();
	set_irg_start_block(res, start_block);
	set_irg_bad        (res, new_ir_node (NULL, res, start_block, op_Bad, mode_T, 0, NULL));
	set_irg_no_mem     (res, new_ir_node (NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
	start              = new_Start();
	set_irg_start      (res, start);

	/* Proj results of start node */
	set_irg_initial_mem(res, new_Proj(start, mode_M, pn_Start_M));
	projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
	add_immBlock_pred(start_block, projX);
	mature_immBlock  (start_block);  /* mature the start block */

	add_immBlock_pred(new_immBlock(), projX);
	mature_immBlock  (get_cur_block());   /* mature the 'body' block for expressions */

	/* Set the visited flag high enough that the blocks will never be visited. */
	set_irn_visited(get_cur_block(), -1);
	set_Block_block_visited(get_cur_block(), -1);
	set_Block_block_visited(start_block, -1);
	set_irn_visited(start_block, -1);
	set_irn_visited(get_irg_bad(res), -1);
	set_irn_visited(get_irg_no_mem(res), -1);

	res->phase_state = phase_high;

	return res;
375
376
}

Michael Beck's avatar
Michael Beck committed
377
378
379
380
381
382
383
384
/**
 * 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.
 */
static void copy_all_nodes(ir_node *n, void *env) {
Michael Beck's avatar
BugFix:    
Michael Beck committed
385
	ir_graph *irg = env;
Michael Beck's avatar
Michael Beck committed
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
	ir_op    *op  = get_irn_op(n);
	ir_node  *nn;

	nn = new_ir_node(get_irn_dbg_info(n),
	                 irg,
	                 NULL,            /* no block yet, will be set later */
	                 op,
	                 get_irn_mode(n),
	                 get_irn_arity(n),
	                 get_irn_in(n) + 1);


	/* Copy the attributes.  These might point to additional data.  If this
	   was allocated on the old obstack the pointers now are dangling.  This
	   frees e.g. the memory of the graph_arr allocated in new_immBlock. */
	copy_node_attr(n, nn);
	new_backedge_info(nn);
	set_irn_link(n, nn);

	/* fix the irg for blocks */
	if (is_Block(nn))
		nn->attr.block.irg = irg;

	/* fix access to entities on the stack frame */
	if (is_Sel(nn)) {
		ir_entity *ent = get_Sel_entity(nn);
		ir_type   *tp = get_entity_owner(ent);

		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));
			set_Sel_entity(nn, ent);
		}
	}
}

/**
 * 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.
 */
static void set_all_preds(ir_node *irn, void *env) {
	int      i;
	ir_node  *nn, *pred;
Matthias Braun's avatar
Matthias Braun committed
433
	(void) env;
Michael Beck's avatar
Michael Beck committed
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520

	nn = get_irn_link(irn);

	if (is_Block(irn)) {
		ir_node *mbh = get_Block_MacroBlock(irn);
		set_Block_MacroBlock(nn, get_irn_link(mbh));
		for (i = get_Block_n_cfgpreds(irn) - 1; i >= 0; i--) {
			pred = get_Block_cfgpred(irn, i);
			set_Block_cfgpred(nn, i, get_irn_link(pred));
		}
	} else {
		/* First we set the block our copy if it is not a block.*/
		set_nodes_block(nn, get_irn_link(get_nodes_block(irn)));
		for (i = get_irn_arity(irn) - 1; i >= 0; i--) {
			pred = get_irn_n(irn, i);
			set_irn_n(nn, i, get_irn_link(pred));
		}
	}
}

#define NN(irn)  get_irn_link(irn)

/*
 * Create a new graph that is a copy of a given one.
 */
ir_graph *create_irg_copy(ir_graph *irg) {
	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 */
#if USE_EXPLICIT_PHI_IN_STACK
	res->Phi_in_stack = NULL;
#endif
	res->obst       = xmalloc(sizeof(*res->obst));
	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;

	res->value_table = new_identities();

	/* clone the frame type here for safety */
	res->frame_type  = clone_frame_type(irg->frame_type);

	res->phase_state = irg->phase_state;

	set_using_irn_link(irg);

	/* copy all nodes from the graph irg to the new graph res */
	irg_walk_anchors(irg, copy_all_nodes, set_all_preds, res);

	/* copy the Anchor node */
	res->anchor = NN(irg->anchor);

	/* -- The end block -- */
	set_irg_end_block (res, NN(get_irg_end_block(irg)));
	set_irg_end       (res, NN(get_irg_end(irg)));
	set_irg_end_reg   (res, NN(get_irg_end_reg(irg)));
	set_irg_end_except(res, NN(get_irg_end_except(irg)));

	/* -- The start block -- */
	set_irg_start_block(res, NN(get_irg_start_block(irg)));
	set_irg_bad        (res, NN(get_irg_bad(irg)));
	set_irg_no_mem     (res, NN(get_irg_no_mem(irg)));
	set_irg_start      (res, NN(get_irg_start(irg)));

	/* Proj results of start node */
	set_irg_initial_mem(res, NN(get_irg_initial_mem(irg)));

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

	clear_using_irn_link(irg);

	return res;
}
#undef NN

521

522
523
524
/* 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.
525
526
   Does not remove the irgraph from the list in irprog (requires
   inefficient search, call remove_irp_irg by hand).
527
528
   Does not free types, entities or modes that are used only by this
   graph, nor the entity standing for this graph. */
Michael Beck's avatar
Michael Beck committed
529
void free_ir_graph(ir_graph *irg) {
530
531
532
	assert(is_ir_graph(irg));

	hook_free_graph(irg);
Michael Beck's avatar
Michael Beck committed
533
534
535
536
537
538
	if (irg->outs_state != outs_none)
		free_irg_outs(irg);
	if (irg->frame_type)
		free_type(irg->frame_type);
	if (irg->value_table)
		del_identities(irg->value_table);
539
540
541
542
543
544
545
546
547
548
	if (irg->ent) {
		ir_peculiarity pec = get_entity_peculiarity (irg->ent);
		set_entity_peculiarity (irg->ent, peculiarity_description);
		set_entity_irg(irg->ent, NULL);  /* not set in const code irg */
		set_entity_peculiarity (irg->ent, pec);
	}

	free_End(get_irg_end(irg));
	obstack_free(irg->obst,NULL);
	free(irg->obst);
549
#if USE_EXPLICIT_PHI_IN_STACK
550
	free_Phi_in_stack(irg->Phi_in_stack);
551
#endif
552
553
554
555
	if (irg->loc_descriptions)
		free(irg->loc_descriptions);
	irg->kind = k_BAD;
	free_graph(irg);
556
557
}

558
559
560
561
/* 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
562

Sebastian Felis's avatar
Sebastian Felis committed
563
int
Michael Beck's avatar
Michael Beck committed
564
(is_ir_graph)(const void *thing) {
565
	return _is_ir_graph(thing);
Sebastian Felis's avatar
Sebastian Felis committed
566
567
}

568
#ifdef DEBUG_libfirm
Matthias Braun's avatar
Matthias Braun committed
569
570
/* Outputs a unique number for this node */
long get_irg_graph_nr(const ir_graph *irg) {
571
	return irg->graph_nr;
Matthias Braun's avatar
Matthias Braun committed
572
}
573
574
575
576
#else
long get_irg_graph_nr(const ir_graph *irg) {
	return PTR_TO_INT(irg);
}
577
#endif
Matthias Braun's avatar
Matthias Braun committed
578
579
580

int get_irg_idx(const ir_graph *irg) {
	return irg->index;
581
582
}

Christian Schäfer's avatar
Christian Schäfer committed
583
ir_node *
Michael Beck's avatar
Michael Beck committed
584
(get_irg_start_block)(const ir_graph *irg) {
585
	return _get_irg_start_block(irg);
Christian Schäfer's avatar
Christian Schäfer committed
586
587
588
}

void
589
(set_irg_start_block)(ir_graph *irg, ir_node *node) {
590
	_set_irg_start_block(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
591
592
593
}

ir_node *
Michael Beck's avatar
Michael Beck committed
594
(get_irg_start)(const ir_graph *irg) {
595
	return _get_irg_start(irg);
Christian Schäfer's avatar
Christian Schäfer committed
596
597
598
}

void
599
(set_irg_start)(ir_graph *irg, ir_node *node) {
600
	_set_irg_start(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
601
602
603
}

ir_node *
Michael Beck's avatar
Michael Beck committed
604
(get_irg_end_block)(const ir_graph *irg) {
605
	return _get_irg_end_block(irg);
Christian Schäfer's avatar
Christian Schäfer committed
606
607
608
}

void
609
(set_irg_end_block)(ir_graph *irg, ir_node *node) {
610
  _set_irg_end_block(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
611
612
613
}

ir_node *
Michael Beck's avatar
Michael Beck committed
614
(get_irg_end)(const ir_graph *irg) {
615
	return _get_irg_end(irg);
Christian Schäfer's avatar
Christian Schäfer committed
616
617
618
}

void
619
(set_irg_end)(ir_graph *irg, ir_node *node) {
620
	_set_irg_end(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
621
622
}

623
ir_node *
Michael Beck's avatar
Michael Beck committed
624
(get_irg_end_reg)(const ir_graph *irg) {
625
	return _get_irg_end_reg(irg);
626
}
627

628
629
630
void
(set_irg_end_reg)(ir_graph *irg, ir_node *node) {
	_set_irg_end_reg(irg, node);
631
632
}

633
ir_node *
Michael Beck's avatar
Michael Beck committed
634
(get_irg_end_except)(const ir_graph *irg) {
635
	return _get_irg_end_except(irg);
636
637
}

638
639
640
641
void
(set_irg_end_except)(ir_graph *irg, ir_node *node) {
	assert(get_irn_op(node) == op_EndExcept || get_irn_op(node) == op_End);
	_set_irg_end_except(irg, node);
642
643
}

Christian Schäfer's avatar
Christian Schäfer committed
644
ir_node *
Michael Beck's avatar
Michael Beck committed
645
(get_irg_frame)(const ir_graph *irg) {
646
	return _get_irg_frame(irg);
Christian Schäfer's avatar
Christian Schäfer committed
647
648
649
}

void
650
(set_irg_frame)(ir_graph *irg, ir_node *node) {
651
	_set_irg_frame(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
652
653
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
654
ir_node *
Michael Beck's avatar
Michael Beck committed
655
(get_irg_globals)(const ir_graph *irg) {
656
  return _get_irg_globals(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
657
658
659
}

void
660
(set_irg_globals)(ir_graph *irg, ir_node *node) {
661
	_set_irg_globals(irg, node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
662
663
}

664
665
ir_node *
(get_irg_tls)(const ir_graph *irg) {
666
	return _get_irg_tls(irg);
667
668
669
670
}

void
(set_irg_tls)(ir_graph *irg, ir_node *node) {
671
	_set_irg_tls(irg, node);
672
673
}

Christian Schäfer's avatar
Christian Schäfer committed
674
ir_node *
Michael Beck's avatar
Michael Beck committed
675
(get_irg_initial_mem)(const ir_graph *irg) {
676
	return _get_irg_initial_mem(irg);
677
678
679
680
}

void
(set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
681
	_set_irg_initial_mem(irg, node);
682
683
684
}

ir_node *
Michael Beck's avatar
Michael Beck committed
685
(get_irg_args)(const ir_graph *irg) {
686
	return _get_irg_args(irg);
Christian Schäfer's avatar
Christian Schäfer committed
687
688
689
}

void
690
(set_irg_args)(ir_graph *irg, ir_node *node) {
691
	_set_irg_args(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
692
693
}

694
695
ir_node *
(get_irg_value_param_base)(const ir_graph *irg) {
696
	return _get_irg_value_param_base(irg);
697
698
699
700
}

void
(set_irg_value_param_base)(ir_graph *irg, ir_node *node) {
701
	_set_irg_value_param_base(irg, node);
702
703
}

Christian Schäfer's avatar
Christian Schäfer committed
704
ir_node *
Michael Beck's avatar
Michael Beck committed
705
(get_irg_bad)(const ir_graph *irg) {
706
	return _get_irg_bad(irg);
Christian Schäfer's avatar
Christian Schäfer committed
707
708
709
}

void
710
(set_irg_bad)(ir_graph *irg, ir_node *node) {
711
	_set_irg_bad(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
712
713
}

714
ir_node *
715
(get_irg_no_mem)(const ir_graph *irg) {
716
	return _get_irg_no_mem(irg);
717
718
719
}

void
720
(set_irg_no_mem)(ir_graph *irg, ir_node *node) {
721
	_set_irg_no_mem(irg, node);
722
723
}

Christian Schäfer's avatar
Christian Schäfer committed
724
ir_node *
Michael Beck's avatar
Michael Beck committed
725
(get_irg_current_block)(const ir_graph *irg) {
726
	return _get_irg_current_block(irg);
Christian Schäfer's avatar
Christian Schäfer committed
727
728
729
}

void
730
(set_irg_current_block)(ir_graph *irg, ir_node *node) {
731
	_set_irg_current_block(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
732
733
}

734
ir_entity *
Michael Beck's avatar
Michael Beck committed
735
(get_irg_entity)(const ir_graph *irg) {
736
	return _get_irg_entity(irg);
Christian Schäfer's avatar
Christian Schäfer committed
737
738
739
}

void
740
(set_irg_entity)(ir_graph *irg, ir_entity *ent) {
741
	_set_irg_entity(irg, ent);
Christian Schäfer's avatar
Christian Schäfer committed
742
743
}

Michael Beck's avatar
Michael Beck committed
744
ir_type *
745
(get_irg_frame_type)(ir_graph *irg) {
746
	return _get_irg_frame_type(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
747
748
749
}

void
Michael Beck's avatar
Michael Beck committed
750
(set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
751
	_set_irg_frame_type(irg, ftp);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
752
753
}

Christian Schäfer's avatar
Christian Schäfer committed
754
int
755
756
757
758
759
get_irg_n_locs(ir_graph *irg) {
	if (get_opt_precise_exc_context())
		return irg->n_loc - 1 - 1;
	else
		return irg->n_loc - 1;
Christian Schäfer's avatar
Christian Schäfer committed
760
761
762
}

void
763
764
765
766
767
set_irg_n_loc(ir_graph *irg, int n_loc) {
	if (get_opt_precise_exc_context())
		irg->n_loc = n_loc + 1 + 1;
	else
		irg->n_loc = n_loc + 1;
Christian Schäfer's avatar
Christian Schäfer committed
768
}
769

Götz Lindenmaier's avatar
Götz Lindenmaier committed
770
771
772


/* Returns the obstack associated with the graph. */
773
struct obstack *
Michael Beck's avatar
Michael Beck committed
774
(get_irg_obstack)(const ir_graph *irg) {
775
	return _get_irg_obstack(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
776
777
}

778
779
780
781
782
/*
 * 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.
 */
783
784
int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) {
	struct _obstack_chunk *p;
785

786
787
788
789
790
791
792
793
	/*
	 * 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;
	}
794

795
	return 0;
796
797
}

798
irg_phase_state
Michael Beck's avatar
Michael Beck committed
799
(get_irg_phase_state)(const ir_graph *irg) {
800
	return _get_irg_phase_state(irg);
801
802
}

803
void
804
(set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
805
	_set_irg_phase_state(irg, state);
806
807
}

808
op_pin_state
Michael Beck's avatar
Michael Beck committed
809
(get_irg_pinned)(const ir_graph *irg) {
810
	return _get_irg_pinned(irg);
811
812
}

813
irg_outs_state
Michael Beck's avatar
Michael Beck committed
814
(get_irg_outs_state)(const ir_graph *irg) {
815
	return _get_irg_outs_state(irg);
816
817
}

818
void
819
(set_irg_outs_inconsistent)(ir_graph *irg) {
820
	_set_irg_outs_inconsistent(irg);
821
822
}

823
824
irg_extblk_state
(get_irg_extblk_state)(const ir_graph *irg) {
825
	return _get_irg_extblk_state(irg);
826
827
828
829
}

void
(set_irg_extblk_inconsistent)(ir_graph *irg) {
830
	_set_irg_extblk_inconsistent(irg);
831
832
}

833
irg_dom_state
Michael Beck's avatar
Michael Beck committed
834
(get_irg_dom_state)(const ir_graph *irg) {
835
	return _get_irg_dom_state(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
836
837
}

838
839
irg_dom_state
(get_irg_postdom_state)(const ir_graph *irg) {
840
	return _get_irg_postdom_state(irg);
841
842
}

843
void
844
(set_irg_doms_inconsistent)(ir_graph *irg) {
845
	_set_irg_doms_inconsistent(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
846
847
}

848
irg_loopinfo_state
Michael Beck's avatar
Michael Beck committed
849
(get_irg_loopinfo_state)(const ir_graph *irg) {
850
	return _get_irg_loopinfo_state(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
851
852
}

853
854
void
(set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
855
	_set_irg_loopinfo_state(irg, s);
856
857
858
}

void
859
(set_irg_loopinfo_inconsistent)(ir_graph *irg) {
860
	_set_irg_loopinfo_inconsistent(irg);
861
862
}

863
void set_irp_loopinfo_inconsistent(void) {
864
865
866
867
	int i;
	for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
		set_irg_loopinfo_inconsistent(get_irp_irg(i));
	}
868
869
870
871
}



872
void
873
(set_irg_pinned)(ir_graph *irg, op_pin_state p) {
874
	_set_irg_pinned(irg, p);
875
876
}

877
irg_callee_info_state
Michael Beck's avatar
Michael Beck committed
878
(get_irg_callee_info_state)(const ir_graph *irg) {
879
	return _get_irg_callee_info_state(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
880
881
}

882
883
void
(set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
884
	_set_irg_callee_info_state(irg, s);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
885
886
}

887
irg_inline_property
Michael Beck's avatar
Michael Beck committed
888
(get_irg_inline_property)(const ir_graph *irg) {
889
	return _get_irg_inline_property(irg);
890
891
}

892
893
void
(set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
894
	_set_irg_inline_property(irg, s);
895
}
896

897
898
unsigned
(get_irg_additional_properties)(const ir_graph *irg) {
899
	return _get_irg_additional_properties(irg);
900
901
902
903
}

void
(set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
904
	_set_irg_additional_properties(irg, property_mask);
905
906
907
}

void
908
(set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
909
	_set_irg_additional_property(irg, flag);
910
911
}

912
913
void
(set_irg_link)(ir_graph *irg, void *thing) {
914
	_set_irg_link(irg, thing);
915
}
916

917
void *
Michael Beck's avatar
Michael Beck committed
918
(get_irg_link)(const ir_graph *irg) {
919
	return _get_irg_link(irg);
920
921
}

922
unsigned long
Michael Beck's avatar
Michael Beck committed
923
(get_irg_visited)(const ir_graph *irg) {
924
	return _get_irg_visited(irg);
925
926
}

927
928
929
930
931
#ifdef INTERPROCEDURAL_VIEW
/** maximum visited flag content of all ir_graph visited fields. */
static unsigned long max_irg_visited = 0;
#endif /* INTERPROCEDURAL_VIEW */

932
void
933
934
set_irg_visited(ir_graph *irg, unsigned long visited) {
	irg->visited = visited;
935
#ifdef INTERPROCEDURAL_VIEW
936
937
938
	if (irg->visited > max_irg_visited) {
		max_irg_visited = irg->visited;
	}
939
#endif /* INTERPROCEDURAL_VIEW */
940
941
942
}

void
943
inc_irg_visited(ir_graph *irg) {
944
#ifdef INTERPROCEDURAL_VIEW
945
946
947
	if (++irg->visited > max_irg_visited) {
		max_irg_visited = irg->visited;
	}
948
949
950
#else
	++irg->visited;
#endif /* INTERPROCEDURAL_VIEW */
951
952
}

953
#ifdef INTERPROCEDURAL_VIEW
954
unsigned long
955
956
957
958
959
960
961
get_max_irg_visited(void) {
	/*
	int i;
	for(i = 0; i < get_irp_n_irgs(); i++)
	assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
	 */
	return max_irg_visited;
962
963
}

964
void set_max_irg_visited(int val) {
965
	max_irg_visited = val;
966
967
}

968
unsigned long
969
970
971
972
973
974
975
inc_max_irg_visited(void) {
	/*
	int i;
	for(i = 0; i < get_irp_n_irgs(); i++)
	assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
	*/
	return ++max_irg_visited;
976
}
977
#endif /* INTERPROCEDURAL_VIEW */
978
979

unsigned long
Michael Beck's avatar
Michael Beck committed
980
(get_irg_block_visited)(const ir_graph *irg) {
981
	return _get_irg_block_visited(irg);
982
983
984
}

void
985
(set_irg_block_visited)(ir_graph *irg, unsigned long visited) {
986
	_set_irg_block_visited(irg, visited);
987
988
989
}

void
990
(inc_irg_block_visited)(ir_graph *irg) {
991
  _inc_irg_block_visited(irg);
992
}
993

994
995
/* Return the floating point model of this graph. */
unsigned (get_irg_fp_model)(const ir_graph *irg) {
996
	return _get_irg_fp_model(irg);
997
998
999
1000
}

/* Sets the floating point model for this graph. */
void set_irg_fp_model(ir_graph *irg, unsigned model) {