irprog.c 8.59 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
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
/**
 * @file
 * @brief    Entry point to the representation of a whole program.
Michael Beck's avatar
Michael Beck committed
23
 * @author   Goetz Lindenmaier, Michael Beck
Matthias Braun's avatar
Matthias Braun committed
24
 * @date     2000
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

Michael Beck's avatar
Michael Beck committed
30
31
#include "irprog_t.h"
#include "irgraph_t.h"
Michael Beck's avatar
Michael Beck committed
32
#include "irpass_t.h"
Michael Beck's avatar
Michael Beck committed
33
#include "array.h"
yb9976's avatar
yb9976 committed
34
#include "error.h"
Michael Beck's avatar
Michael Beck committed
35
36
#include "obst.h"
#include "irop_t.h"
37
#include "irmemory.h"
38
#include "ircons.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
39

40
/** The initial name of the irp program. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
41
#define INITAL_PROG_NAME "no_name_set"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
42

Götz Lindenmaier's avatar
Götz Lindenmaier committed
43
ir_prog *irp;
44
ir_prog *get_irp(void) { return irp; }
45
46
47
48
void set_irp(ir_prog *new_irp)
{
	irp = new_irp;
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
49

50
51
52
/**
 *  Create a new incomplete ir_prog.
 */
53
54
55
static ir_prog *new_incomplete_ir_prog(void)
{
	ir_prog *res = XMALLOCZ(ir_prog);
Michael Beck's avatar
Michael Beck committed
56

57
58
59
	res->kind           = k_ir_prog;
	res->graphs         = NEW_ARR_F(ir_graph *, 0);
	res->types          = NEW_ARR_F(ir_type *, 0);
60
	res->global_asms    = NEW_ARR_F(ident *, 0);
61
	res->last_label_nr  = 1;  /* 0 is reserved as non-label */
Matthias Braun's avatar
Matthias Braun committed
62
	res->max_irg_idx    = 0;
63
64
	res->max_node_nr    = 0;
#ifndef NDEBUG
65
	res->reserved_resources = IRP_RESOURCE_NONE;
Till Riedel's avatar
Till Riedel committed
66
67
#endif

68
	return res;
69
70
}

71
72
73
74
75
76
/**
 * Completes an incomplete irprog.
 *
 * @param irp          the (yet incomplete) irp
 * @param module_name  the (module) name for this irp
 */
77
static void complete_ir_prog(ir_prog *irp, const char *module_name)
78
{
Michael Beck's avatar
Michael Beck committed
79
80
#define IDENT(x)  new_id_from_chars(x, sizeof(x) - 1)

81
	irp->name = new_id_from_str(module_name);
82
83
	irp->segment_types[IR_SEGMENT_GLOBAL]
		= new_type_class(IDENT("GlobalType"));
84
	irp->segment_types[IR_SEGMENT_THREAD_LOCAL]
85
		= new_type_struct(IDENT("ThreadLocal"));
86
	irp->segment_types[IR_SEGMENT_CONSTRUCTORS]
87
		= new_type_class(IDENT("Constructors"));
88
	irp->segment_types[IR_SEGMENT_DESTRUCTORS]
89
		= new_type_class(IDENT("Destructors"));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
90

91
	/* Set these flags for debugging. */
Matthias Braun's avatar
Matthias Braun committed
92
93
94
95
	irp->segment_types[IR_SEGMENT_GLOBAL]->flags       |= tf_segment|tf_global_type;
	irp->segment_types[IR_SEGMENT_THREAD_LOCAL]->flags |= tf_segment|tf_tls_type;
	irp->segment_types[IR_SEGMENT_CONSTRUCTORS]->flags |= tf_segment|tf_constructors;
	irp->segment_types[IR_SEGMENT_DESTRUCTORS]->flags  |= tf_segment|tf_destructors;
96

97
98
	/* The global type is a class, but we cannot derive from it, so set
	   the final property to assist optimizations that checks for it. */
99
	set_class_final(irp->segment_types[IR_SEGMENT_GLOBAL], 1);
100

101
	irp->const_code_irg             = new_const_code_irg();
102
103
104
	irp->phase_state                = phase_building;
	irp->class_cast_state           = ir_class_casts_transitive;
	irp->globals_entity_usage_state = ir_entity_usage_not_computed;
Michael Beck's avatar
Michael Beck committed
105
#undef IDENT
106
107
}

108
109
void init_irprog_1(void)
{
110
	irp = new_incomplete_ir_prog();
111
112
}

113
114
void init_irprog_2(void)
{
115
116
117
	complete_ir_prog(irp, INITAL_PROG_NAME);
	ir_init_type(irp);
	ir_init_entity(irp);
118
119
}

120
121
ir_prog *new_ir_prog(const char *name)
{
122
123
124
	ir_prog *irp = new_incomplete_ir_prog();
	complete_ir_prog(irp, name);
	return irp;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
125
126
}

127
128
void free_ir_prog(void)
{
129
130
131
132
133
	size_t i;
	/* must iterate backwards here */
	for (i = get_irp_n_irgs(); i > 0;)
		free_ir_graph(get_irp_irg(--i));

134
135
	/* free entities first to avoid entity types being destroyed before
	 * the entities using them */
136
137
138
	for (i = get_irp_n_types(); i > 0;)
		free_type_entities(get_irp_type(--i));

Matthias Braun's avatar
Matthias Braun committed
139
140
	ir_finish_entity(irp);

141
142
	for (i = get_irp_n_types(); i > 0;)
		free_type(get_irp_type(--i));
143

yb9976's avatar
yb9976 committed
144
	free_ir_graph(irp->const_code_irg);
Matthias Braun's avatar
Matthias Braun committed
145
146
147

	ir_finish_type(irp);

148
149
	DEL_ARR_F(irp->graphs);
	DEL_ARR_F(irp->types);
yb9976's avatar
yb9976 committed
150

151
	DEL_ARR_F(irp->global_asms);
152

153
154
155
	irp->name           = NULL;
	irp->const_code_irg = NULL;
	irp->kind           = k_BAD;
Matthias Braun's avatar
Matthias Braun committed
156
157
	free(irp);
	irp = NULL;
158
159
}

160
161
ir_graph *get_irp_main_irg(void)
{
162
163
	assert(irp);
	return irp->main_irg;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
164
165
}

166
167
void set_irp_main_irg(ir_graph *main_irg)
{
168
	assert(irp);
169
	irp->main_irg = main_irg;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
170
171
}

172
173
ir_type *(get_segment_type)(ir_segment_t segment)
{
174
	return get_segment_type_(segment);
175
176
}

177
178
179
180
181
182
void set_segment_type(ir_segment_t segment, ir_type *new_type)
{
	assert(segment <= IR_SEGMENT_LAST);
	irp->segment_types[segment] = new_type;
}

183
184
ir_type *(get_glob_type)(void)
{
185
	return get_glob_type_();
Götz Lindenmaier's avatar
Götz Lindenmaier committed
186
187
}

188
189
ir_type *(get_tls_type)(void)
{
190
	return get_tls_type_();
191
192
}

193
194
void add_irp_irg(ir_graph *irg)
{
195
196
197
	assert(irg != NULL);
	assert(irp && irp->graphs);
	ARR_APP1(ir_graph *, irp->graphs, irg);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
198
199
}

200
201
void remove_irp_irg_from_list(ir_graph *irg)
{
202
	size_t i, l;
203
204

	assert(irg);
205
	l = ARR_LEN(irp->graphs);
206
	for (i = 0; i < l; ++i) {
207
		if (irp->graphs[i] == irg) {
208
			for (; i < l - 1; ++i) {
209
210
				irp->graphs[i] = irp->graphs[i+1];
			}
211
			ARR_SETLEN(ir_graph*, irp->graphs, l - 1);
212
213
214
			break;
		}
	}
215
216
}

217
218
void remove_irp_irg(ir_graph *irg)
{
219
220
	free_ir_graph(irg);
	remove_irp_irg_from_list(irg);
Boris Boesler's avatar
Boris Boesler committed
221
222
}

Matthias Braun's avatar
Matthias Braun committed
223
size_t (get_irp_n_irgs)(void)
224
{
225
	return get_irp_n_irgs_();
Götz Lindenmaier's avatar
Götz Lindenmaier committed
226
227
}

Matthias Braun's avatar
Matthias Braun committed
228
ir_graph *(get_irp_irg)(size_t pos)
229
{
230
	return get_irp_irg_(pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
231
232
}

233
size_t get_irp_last_idx(void)
234
{
Matthias Braun's avatar
Matthias Braun committed
235
236
237
	return irp->max_irg_idx;
}

Matthias Braun's avatar
Matthias Braun committed
238
void set_irp_irg(size_t pos, ir_graph *irg)
239
{
240
	assert(irp && irg);
Matthias Braun's avatar
Matthias Braun committed
241
	assert(pos < ARR_LEN(irp->graphs));
242
	irp->graphs[pos] = irg;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
243
244
}

245
246
void add_irp_type(ir_type *typ)
{
247
248
	assert(typ != NULL);
	assert(irp);
Michael Beck's avatar
Michael Beck committed
249
	ARR_APP1(ir_type *, irp->types, typ);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
250
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
251

252
253
void remove_irp_type(ir_type *typ)
{
254
	size_t i, l;
255
	assert(typ);
256

257
258
	l = ARR_LEN(irp->types);
	for (i = 0; i < l; ++i) {
259
		if (irp->types[i] == typ) {
260
			for (; i < l - 1; ++i) {
261
262
				irp->types[i] = irp->types[i+1];
			}
263
			ARR_SETLEN(ir_type *, irp->types, l - 1);
264
265
266
			break;
		}
	}
267
268
}

Matthias Braun's avatar
Matthias Braun committed
269
size_t (get_irp_n_types) (void)
270
{
271
	return get_irp_n_types_();
Götz Lindenmaier's avatar
Götz Lindenmaier committed
272
273
}

Matthias Braun's avatar
Matthias Braun committed
274
ir_type *(get_irp_type) (size_t pos)
275
{
276
	return get_irp_type_(pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
277
278
}

Matthias Braun's avatar
Matthias Braun committed
279
void set_irp_type(size_t pos, ir_type *typ)
280
{
281
	assert(irp && typ);
Matthias Braun's avatar
Matthias Braun committed
282
	assert(pos < ARR_LEN((irp)->types));
283
	irp->types[pos] = typ;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
284
285
}

Matthias Braun's avatar
Matthias Braun committed
286
void set_irp_prog_name(ident *name)
287
{
288
	irp->name = name;
289
}
290
291
int irp_prog_name_is_set(void)
{
292
	return irp->name != new_id_from_str(INITAL_PROG_NAME);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
293
}
294
295
ident *get_irp_ident(void)
{
296
	return irp->name;
297
}
298
299
const char  *get_irp_name(void)
{
300
	return get_id_str(irp->name);
301
302
303
}


304
305
ir_graph *(get_const_code_irg)(void)
{
306
	return get_const_code_irg_();
307
}
308

309
310
irg_phase_state get_irp_phase_state(void)
{
311
	return irp->phase_state;
312
}
313

314
315
void set_irp_phase_state(irg_phase_state s)
{
316
	irp->phase_state = s;
317
318
}

319
typedef struct pass_t {
Michael Beck's avatar
Michael Beck committed
320
321
	ir_prog_pass_t  pass;
	irg_phase_state state;
322
} pass_t;
Michael Beck's avatar
Michael Beck committed
323
324
325
326

/**
 * Wrapper for setting the state of a whole ir_prog.
 */
327
328
static int set_irp_phase_state_wrapper(ir_prog *irp, void *context)
{
329
	pass_t         *pass  = (pass_t *)context;
Michael Beck's avatar
Michael Beck committed
330
	irg_phase_state state = pass->state;
Michael Beck's avatar
Michael Beck committed
331
	size_t          i, n;
Michael Beck's avatar
Michael Beck committed
332
333
334
335

	(void)irp;

	/* set the phase of all graphs */
Michael Beck's avatar
Michael Beck committed
336
	for (i = 0, n = get_irp_n_irgs(); i < n; ++i)
Michael Beck's avatar
Michael Beck committed
337
338
339
340
341
342
343
344
		set_irg_phase_state(get_irp_irg(i), state);

	/* set the irp phase */
	set_irp_phase_state(state);

	return 0;
}

345
346
ir_prog_pass_t *set_irp_phase_state_pass(const char *name, irg_phase_state state)
{
Michael Beck's avatar
Michael Beck committed
347
348
349
350
351
352
353
354
355
356
357
358
359
	struct pass_t *pass = XMALLOCZ(struct pass_t);

	def_prog_pass_constructor(
		&pass->pass, name ? name : "set_irp_phase", set_irp_phase_state_wrapper);
	pass->state = state;

	/* no dump/verify */
	pass->pass.verify_irprog = ir_prog_no_verify;
	pass->pass.dump_irprog   = ir_prog_no_dump;

	return &pass->pass;
}

360
361
void set_irp_ip_outedges(ir_node ** ip_outedges)
{
362
	irp->ip_outedges = ip_outedges;
363
364
}

365
366
ir_node** get_irp_ip_outedges(void)
{
367
	return irp->ip_outedges;
368
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
369

370
371
irg_callee_info_state get_irp_callee_info_state(void)
{
372
	return irp->callee_info_state;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
373
374
}

375
376
void set_irp_callee_info_state(irg_callee_info_state s)
{
377
378
379
	irp->callee_info_state = s;
}

380
381
ir_label_t (get_irp_next_label_nr)(void)
{
382
	return get_irp_next_label_nr_();
Michael Beck's avatar
Michael Beck committed
383
}
384

385
386
void add_irp_asm(ident *asm_string)
{
387
388
389
	ARR_APP1(ident *, irp->global_asms, asm_string);
}

Matthias Braun's avatar
Matthias Braun committed
390
size_t get_irp_n_asms(void)
391
{
392
393
394
	return ARR_LEN(irp->global_asms);
}

Matthias Braun's avatar
Matthias Braun committed
395
ident *get_irp_asm(size_t pos)
396
{
Matthias Braun's avatar
Matthias Braun committed
397
	assert(pos < get_irp_n_asms());
398
399
	return irp->global_asms[pos];
}
400
401

#ifndef NDEBUG
402
void irp_reserve_resources(ir_prog *irp, irp_resources_t resources)
403
{
404
405
406
407
	assert((irp->reserved_resources & resources) == 0);
	irp->reserved_resources |= resources;
}

408
void irp_free_resources(ir_prog *irp, irp_resources_t resources)
409
{
410
411
412
413
	assert((irp->reserved_resources & resources) == resources);
	irp->reserved_resources &= ~resources;
}

414
irp_resources_t irp_resources_reserved(const ir_prog *irp)
415
{
416
417
418
	return irp->reserved_resources;
}
#endif