irgraph.c 23.3 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
 *
 * 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
41
42
43
44
45
46
47
#include "irgraph_t.h"
#include "irprog_t.h"
#include "irnode_t.h"
#include "iropt_t.h"
#include "irflag_t.h"
#include "array.h"
#include "irgmod.h"
#include "irouts.h"
#include "irhooks.h"
48
#include "irtools.h"
Michael Beck's avatar
Michael Beck committed
49
50
51
#include "irgwalk.h"
#include "iredges_t.h"
#include "type_t.h"
52
#include "irmemory.h"
Christian Schäfer's avatar
Christian Schäfer committed
53

54
55
#define INITIAL_IDX_IRN_MAP_SIZE 1024

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

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

77
#ifdef INTERPROCEDURAL_VIEW
78
int firm_interprocedural_view = 0;
79
80

int (get_interprocedural_view)(void) {
81
	return _get_interprocedural_view();
82
}
83
84

void (set_interprocedural_view)(int state) {
85
	firm_interprocedural_view = state;
86

87
88
89
90
91
92
93
94
95
	/* 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;
	}
96
}
97
#endif
98

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

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

/**
109
 * Allocate a new IR graph.
110
111
112
113
114
 * 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.
 */
115
static ir_graph *alloc_graph(void) {
116
117
118
	size_t size = sizeof(ir_graph) + additional_graph_data_size;
	char *ptr = xmalloc(size);
	memset(ptr, 0, size);
119

120
	return (ir_graph *) (ptr + additional_graph_data_size);
121
}
122

123
124
125
126
/**
 * Frees an allocated IR graph
 */
static void free_graph(ir_graph *irg) {
127
128
	char *ptr = (char *)irg;
	free(ptr - additional_graph_data_size);
129
130
}

131
#if USE_EXPLICIT_PHI_IN_STACK
Götz Lindenmaier's avatar
Götz Lindenmaier committed
132
133
134
/* really defined in ircons.c */
typedef struct Phi_in_stack Phi_in_stack;
Phi_in_stack *new_Phi_in_stack();
135
void free_Phi_in_stack(Phi_in_stack *s);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
136
137
#endif

Christian Schäfer's avatar
Christian Schäfer committed
138
139
140
141
142
143
144
145
146
/* 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.
*/
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
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();
	res->kind = k_ir_graph;

	//edges_init_graph_kind(res, EDGE_KIND_NORMAL);
	//edges_init_graph_kind(res, EDGE_KIND_BLOCK);

	/* 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]));

	/* 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. --*/
	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!  */
	}

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

187
#if USE_EXPLICIT_PHI_IN_STACK
188
189
	res->Phi_in_stack = new_Phi_in_stack();  /* A stack needed for automatic Phi
	                                            generation */
Christian Schäfer's avatar
Christian Schäfer committed
190
#endif
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
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
	res->kind = k_ir_graph;
	res->obst = xmalloc (sizeof(*res->obst));
	obstack_init(res->obst);
	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->phase_state         = phase_building;
	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);
257

Matthias Braun's avatar
Matthias Braun committed
258
	res->index       = get_irp_new_irg_idx();
259
#ifdef DEBUG_libfirm
260
	res->graph_nr    = get_irp_new_node_nr();
261
262
#endif

263
264
265
266
267
268
	/*
	 * 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
269

270
271
272
	/*-- 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
273

274
275
	res->method_execution_frequency = -1.0;
	res->estimated_node_count       = 0;
276

277
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
278
279
}

280

Götz Lindenmaier's avatar
Götz Lindenmaier committed
281
ir_graph *
282
283
284
285
new_ir_graph(ir_entity *ent, int n_loc) {
	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
286
287
}

288
/* Make a rudimentary IR graph for the constant code.
289
   Must look like a correct irg, spare everything else. */
290
ir_graph *new_const_code_irg(void) {
291
292
	ir_graph *res;
	ir_node  *end, *start_block, *start, *projX;
293

294
	res = alloc_graph();
295

296
297
298
	/* 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]));
299

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

303
304
305
306
	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 */
307
#if USE_EXPLICIT_PHI_IN_STACK
308
	res->Phi_in_stack = NULL;
309
#endif
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
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
	res->kind = k_ir_graph;
	res->obst      = xmalloc (sizeof(*res->obst));
	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;

	res->value_table = new_identities (); /* value table for global value
					   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;
367
368
}

369
370
371
/* Defined in iropt.c */
void  del_identities (pset *value_table);

372
373
374
/* 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.
375
376
   Does not remove the irgraph from the list in irprog (requires
   inefficient search, call remove_irp_irg by hand).
377
378
379
   Does not free types, entities or modes that are used only by this
   graph, nor the entity standing for this graph. */
void free_ir_graph (ir_graph *irg) {
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
	assert(is_ir_graph(irg));

	hook_free_graph(irg);
	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);
	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);
396
#if USE_EXPLICIT_PHI_IN_STACK
397
	free_Phi_in_stack(irg->Phi_in_stack);
398
#endif
399
400
401
402
	if (irg->loc_descriptions)
		free(irg->loc_descriptions);
	irg->kind = k_BAD;
	free_graph(irg);
403
404
}

405
406
407
408
/* 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
409

Sebastian Felis's avatar
Sebastian Felis committed
410
int
Michael Beck's avatar
Michael Beck committed
411
(is_ir_graph)(const void *thing) {
412
	return _is_ir_graph(thing);
Sebastian Felis's avatar
Sebastian Felis committed
413
414
}

415
#ifdef DEBUG_libfirm
Matthias Braun's avatar
Matthias Braun committed
416
417
/* Outputs a unique number for this node */
long get_irg_graph_nr(const ir_graph *irg) {
418
	return irg->graph_nr;
Matthias Braun's avatar
Matthias Braun committed
419
}
420
#endif
Matthias Braun's avatar
Matthias Braun committed
421
422
423

int get_irg_idx(const ir_graph *irg) {
	return irg->index;
424
425
}

Christian Schäfer's avatar
Christian Schäfer committed
426
ir_node *
Michael Beck's avatar
Michael Beck committed
427
(get_irg_start_block)(const ir_graph *irg) {
428
	return _get_irg_start_block(irg);
Christian Schäfer's avatar
Christian Schäfer committed
429
430
431
}

void
432
(set_irg_start_block)(ir_graph *irg, ir_node *node) {
433
	_set_irg_start_block(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
434
435
436
}

ir_node *
Michael Beck's avatar
Michael Beck committed
437
(get_irg_start)(const ir_graph *irg) {
438
	return _get_irg_start(irg);
Christian Schäfer's avatar
Christian Schäfer committed
439
440
441
}

void
442
(set_irg_start)(ir_graph *irg, ir_node *node) {
443
	_set_irg_start(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
444
445
446
}

ir_node *
Michael Beck's avatar
Michael Beck committed
447
(get_irg_end_block)(const ir_graph *irg) {
448
	return _get_irg_end_block(irg);
Christian Schäfer's avatar
Christian Schäfer committed
449
450
451
}

void
452
(set_irg_end_block)(ir_graph *irg, ir_node *node) {
453
  _set_irg_end_block(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
454
455
456
}

ir_node *
Michael Beck's avatar
Michael Beck committed
457
(get_irg_end)(const ir_graph *irg) {
458
	return _get_irg_end(irg);
Christian Schäfer's avatar
Christian Schäfer committed
459
460
461
}

void
462
(set_irg_end)(ir_graph *irg, ir_node *node) {
463
	_set_irg_end(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
464
465
}

466
ir_node *
Michael Beck's avatar
Michael Beck committed
467
(get_irg_end_reg)(const ir_graph *irg) {
468
	return _get_irg_end_reg(irg);
469
}
470

471
472
473
void
(set_irg_end_reg)(ir_graph *irg, ir_node *node) {
	_set_irg_end_reg(irg, node);
474
475
}

476
ir_node *
Michael Beck's avatar
Michael Beck committed
477
(get_irg_end_except)(const ir_graph *irg) {
478
	return _get_irg_end_except(irg);
479
480
}

481
482
483
484
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);
485
486
}

Christian Schäfer's avatar
Christian Schäfer committed
487
ir_node *
Michael Beck's avatar
Michael Beck committed
488
(get_irg_frame)(const ir_graph *irg) {
489
	return _get_irg_frame(irg);
Christian Schäfer's avatar
Christian Schäfer committed
490
491
492
}

void
493
(set_irg_frame)(ir_graph *irg, ir_node *node) {
494
	_set_irg_frame(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
495
496
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
497
ir_node *
Michael Beck's avatar
Michael Beck committed
498
(get_irg_globals)(const ir_graph *irg) {
499
  return _get_irg_globals(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
500
501
502
}

void
503
(set_irg_globals)(ir_graph *irg, ir_node *node) {
504
	_set_irg_globals(irg, node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
505
506
}

507
508
ir_node *
(get_irg_tls)(const ir_graph *irg) {
509
	return _get_irg_tls(irg);
510
511
512
513
}

void
(set_irg_tls)(ir_graph *irg, ir_node *node) {
514
	_set_irg_tls(irg, node);
515
516
}

Christian Schäfer's avatar
Christian Schäfer committed
517
ir_node *
Michael Beck's avatar
Michael Beck committed
518
(get_irg_initial_mem)(const ir_graph *irg) {
519
	return _get_irg_initial_mem(irg);
520
521
522
523
}

void
(set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
524
	_set_irg_initial_mem(irg, node);
525
526
527
}

ir_node *
Michael Beck's avatar
Michael Beck committed
528
(get_irg_args)(const ir_graph *irg) {
529
	return _get_irg_args(irg);
Christian Schäfer's avatar
Christian Schäfer committed
530
531
532
}

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

537
538
ir_node *
(get_irg_value_param_base)(const ir_graph *irg) {
539
	return _get_irg_value_param_base(irg);
540
541
542
543
}

void
(set_irg_value_param_base)(ir_graph *irg, ir_node *node) {
544
	_set_irg_value_param_base(irg, node);
545
546
}

Christian Schäfer's avatar
Christian Schäfer committed
547
ir_node *
Michael Beck's avatar
Michael Beck committed
548
(get_irg_bad)(const ir_graph *irg) {
549
	return _get_irg_bad(irg);
Christian Schäfer's avatar
Christian Schäfer committed
550
551
552
}

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

557
ir_node *
558
(get_irg_no_mem)(const ir_graph *irg) {
559
	return _get_irg_no_mem(irg);
560
561
562
}

void
563
(set_irg_no_mem)(ir_graph *irg, ir_node *node) {
564
	_set_irg_no_mem(irg, node);
565
566
}

Christian Schäfer's avatar
Christian Schäfer committed
567
ir_node *
Michael Beck's avatar
Michael Beck committed
568
(get_irg_current_block)(const ir_graph *irg) {
569
	return _get_irg_current_block(irg);
Christian Schäfer's avatar
Christian Schäfer committed
570
571
572
}

void
573
(set_irg_current_block)(ir_graph *irg, ir_node *node) {
574
	_set_irg_current_block(irg, node);
Christian Schäfer's avatar
Christian Schäfer committed
575
576
}

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

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

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

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

Christian Schäfer's avatar
Christian Schäfer committed
597
int
598
599
600
601
602
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
603
604
605
}

void
606
607
608
609
610
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
611
}
612

Götz Lindenmaier's avatar
Götz Lindenmaier committed
613
614
615


/* Returns the obstack associated with the graph. */
616
struct obstack *
Michael Beck's avatar
Michael Beck committed
617
(get_irg_obstack)(const ir_graph *irg) {
618
	return _get_irg_obstack(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
619
620
}

621
622
623
624
625
/*
 * 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.
 */
626
627
int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) {
	struct _obstack_chunk *p;
628

629
630
631
632
633
634
635
636
	/*
	 * 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;
	}
637

638
	return 0;
639
640
}

641
irg_phase_state
Michael Beck's avatar
Michael Beck committed
642
(get_irg_phase_state)(const ir_graph *irg) {
643
	return _get_irg_phase_state(irg);
644
645
}

646
void
647
(set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
648
	_set_irg_phase_state(irg, state);
649
650
}

651
op_pin_state
Michael Beck's avatar
Michael Beck committed
652
(get_irg_pinned)(const ir_graph *irg) {
653
	return _get_irg_pinned(irg);
654
655
}

656
irg_outs_state
Michael Beck's avatar
Michael Beck committed
657
(get_irg_outs_state)(const ir_graph *irg) {
658
	return _get_irg_outs_state(irg);
659
660
}

661
void
662
(set_irg_outs_inconsistent)(ir_graph *irg) {
663
	_set_irg_outs_inconsistent(irg);
664
665
}

666
667
irg_extblk_state
(get_irg_extblk_state)(const ir_graph *irg) {
668
	return _get_irg_extblk_state(irg);
669
670
671
672
}

void
(set_irg_extblk_inconsistent)(ir_graph *irg) {
673
	_set_irg_extblk_inconsistent(irg);
674
675
}

676
irg_dom_state
Michael Beck's avatar
Michael Beck committed
677
(get_irg_dom_state)(const ir_graph *irg) {
678
	return _get_irg_dom_state(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
679
680
}

681
682
irg_dom_state
(get_irg_postdom_state)(const ir_graph *irg) {
683
	return _get_irg_postdom_state(irg);
684
685
}

686
void
687
(set_irg_doms_inconsistent)(ir_graph *irg) {
688
	_set_irg_doms_inconsistent(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
689
690
}

691
irg_loopinfo_state
Michael Beck's avatar
Michael Beck committed
692
(get_irg_loopinfo_state)(const ir_graph *irg) {
693
	return _get_irg_loopinfo_state(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
694
695
}

696
697
void
(set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
698
	_set_irg_loopinfo_state(irg, s);
699
700
701
}

void
702
(set_irg_loopinfo_inconsistent)(ir_graph *irg) {
703
	_set_irg_loopinfo_inconsistent(irg);
704
705
}

706
void set_irp_loopinfo_inconsistent(void) {
707
708
709
710
	int i;
	for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
		set_irg_loopinfo_inconsistent(get_irp_irg(i));
	}
711
712
713
714
}



715
void
716
(set_irg_pinned)(ir_graph *irg, op_pin_state p) {
717
	_set_irg_pinned(irg, p);
718
719
}

720
irg_callee_info_state
Michael Beck's avatar
Michael Beck committed
721
(get_irg_callee_info_state)(const ir_graph *irg) {
722
	return _get_irg_callee_info_state(irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
723
724
}

725
726
void
(set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
727
	_set_irg_callee_info_state(irg, s);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
728
729
}

730
irg_inline_property
Michael Beck's avatar
Michael Beck committed
731
(get_irg_inline_property)(const ir_graph *irg) {
732
	return _get_irg_inline_property(irg);
733
734
}

735
736
void
(set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
737
	_set_irg_inline_property(irg, s);
738
}
739

740
741
unsigned
(get_irg_additional_properties)(const ir_graph *irg) {
742
	return _get_irg_additional_properties(irg);
743
744
745
746
}

void
(set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
747
	_set_irg_additional_properties(irg, property_mask);
748
749
750
}

void
751
(set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
752
	_set_irg_additional_property(irg, flag);
753
754
}

755
756
void
(set_irg_link)(ir_graph *irg, void *thing) {
757
	_set_irg_link(irg, thing);
758
}
759

760
void *
Michael Beck's avatar
Michael Beck committed
761
(get_irg_link)(const ir_graph *irg) {
762
	return _get_irg_link(irg);
763
764
}

765
766
/** maximum visited flag content of all ir_graph visited fields. */
static unsigned long max_irg_visited = 0;
767

768
unsigned long
Michael Beck's avatar
Michael Beck committed
769
(get_irg_visited)(const ir_graph *irg) {
770
	return _get_irg_visited(irg);
771
772
773
}

void
774
775
776
777
778
set_irg_visited(ir_graph *irg, unsigned long visited) {
	irg->visited = visited;
	if (irg->visited > max_irg_visited) {
		max_irg_visited = irg->visited;
	}
779
780
781
}

void
782
783
784
785
inc_irg_visited(ir_graph *irg) {
	if (++irg->visited > max_irg_visited) {
		max_irg_visited = irg->visited;
	}
786
787
788
}

unsigned long
789
790
791
792
793
794
795
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;
796
797
}

798
void set_max_irg_visited(int val) {
799
	max_irg_visited = val;
800
801
}

802
unsigned long
803
804
805
806
807
808
809
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;
810
811
812
}

unsigned long
Michael Beck's avatar
Michael Beck committed
813
(get_irg_block_visited)(const ir_graph *irg) {
814
	return _get_irg_block_visited(irg);
815
816
817
}

void
818
(set_irg_block_visited)(ir_graph *irg, unsigned long visited) {
819
	_set_irg_block_visited(irg, visited);
820
821
822
}

void
823
(inc_irg_block_visited)(ir_graph *irg) {
824
  _inc_irg_block_visited(irg);
825
}
826

827
828
/* Return the floating point model of this graph. */
unsigned (get_irg_fp_model)(const ir_graph *irg) {
829
	return _get_irg_fp_model(irg);
830
831
832
833
}

/* Sets the floating point model for this graph. */
void set_irg_fp_model(ir_graph *irg, unsigned model) {
834
	irg->fp_model = model;
835
}
836

837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
/**
 * walker Start->End: places Proj nodes into the same block
 * as it's predecessors
 *
 * @param n    the node
 * @param env  ignored
 */
static void normalize_proj_walker(ir_node *n, void *env) {
	(void) env;
	if (is_Proj(n)) {
		ir_node *pred  = get_Proj_pred(n);
		ir_node *block = get_nodes_block(pred);

		set_nodes_block(n, block);
	}
}

/* move Proj nodes into the same block as its predecessors */
void normalize_proj_nodes(ir_graph *irg) {
	irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
	set_irg_outs_inconsistent(irg);
}

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

864
865
	if (! irg->loc_descriptions)
		irg->loc_descriptions = xcalloc(sizeof(*irg->loc_descriptions), irg->n_loc);
866

867
	irg->loc_descriptions[n] = description;
868
869
870
}

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

876
877
878
879
#ifndef NDEBUG
void set_using_block_visited(ir_graph *irg) {
	assert(irg->using_block_visited == 0);
	irg->using_block_visited = 1;
880
881
}

882
883
884
void clear_using_block_visited(ir_graph *irg) {
	assert(irg->using_block_visited == 1);
	irg->using_block_visited = 0;
885
886
}

887
int using_block_visited(const ir_graph *irg) {
888
	return irg->using_block_visited;
889
890
}

891
892
893
894

void set_using_visited(ir_graph *irg) {
	assert(irg->using_visited == 0);
	irg->using_visited = 1;
895
896
}

897
898
899
void clear_using_visited(ir_graph *irg) {
	assert(irg->using_visited == 1);
	irg->using_visited = 0;
900
901
}

902
int using_visited(const ir_graph *irg) {
903
	return irg->using_visited;
904
905
}

906
907
908
909
910
911
912
913
914
915
916
917

void set_using_irn_link(ir_graph *irg) {
	assert(irg->using_irn_link == 0);
	irg->using_irn_link = 1;
}

void clear_using_irn_link(ir_graph *irg) {
	assert(irg->using_irn_link == 1);
	irg->using_irn_link = 0;
}

int using_irn_link(const ir_graph *irg) {
918
	return irg->using_irn_link;
919
920
921
}
#endif

Michael Beck's avatar
Michael Beck committed
922
923
/* Returns a estimated node count of the irg. */
unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg) {
924
	return _get_irg_estimated_node_cnt(irg);
Michael Beck's avatar
Michael Beck committed
925
926
}

927
928
/* Returns the last irn index for this graph. */
unsigned get_irg_last_idx(const ir_graph *irg) {
929
	return irg->last_node_idx;
930
931
}

932
/* register additional space in an IR graph */
933
934
size_t register_additional_graph_data(size_t size) {
	assert(!forbid_new_data && "Too late to register additional node data");
935

936
937
	if (forbid_new_data)
		return 0;
938

939
	return additional_graph_data_size += size;
940
}