bemain.c 22.4 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

6
/**
Christian Würdig's avatar
Christian Würdig committed
7
8
9
10
 * @file
 * @brief       Main Backend driver.
 * @author      Sebastian Hack
 * @date        25.11.2004
11
 */
Sebastian Hack's avatar
Sebastian Hack committed
12
#include <stdarg.h>
13
#include <stdio.h>
14

Matthias Braun's avatar
Matthias Braun committed
15
16
#include "lc_opts.h"
#include "lc_opts_enum.h"
17

Sebastian Hack's avatar
Sebastian Hack committed
18
#include "obst.h"
19
#include "statev.h"
Sebastian Hack's avatar
Sebastian Hack committed
20
#include "irprog.h"
Sebastian Hack's avatar
Sebastian Hack committed
21
#include "irgopt.h"
Daniel Grund's avatar
Daniel Grund committed
22
#include "irdump.h"
Sebastian Hack's avatar
Sebastian Hack committed
23
24
#include "irdom_t.h"
#include "iredges_t.h"
25
#include "irloop_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
26
#include "irtools.h"
27
#include "irverify.h"
Matthias Braun's avatar
Matthias Braun committed
28
#include "iroptimize.h"
Christian Würdig's avatar
Christian Würdig committed
29
#include "firmstat.h"
30
#include "execfreq_t.h"
31
#include "irprofile.h"
32
#include "irpass_t.h"
33
#include "ircons.h"
34
#include "util.h"
Sebastian Hack's avatar
Sebastian Hack committed
35

36
#include "bearch.h"
Sebastian Hack's avatar
Sebastian Hack committed
37
#include "be_t.h"
38
#include "begnuas.h"
39
#include "bemodule.h"
40
#include "beutil.h"
41
#include "benode.h"
42
#include "beirgmod.h"
43
#include "besched.h"
44
45
#include "belistsched.h"
#include "belive_t.h"
46
47
48
#include "bera.h"
#include "bechordal_t.h"
#include "beifg.h"
Daniel Grund's avatar
Daniel Grund committed
49
#include "becopyopt.h"
50
#include "becopystat.h"
51
#include "bessadestr.h"
Sebastian Hack's avatar
Sebastian Hack committed
52
#include "beabi.h"
Christian Würdig's avatar
Christian Würdig committed
53
#include "belower.h"
54
#include "bestat.h"
55
#include "beverify.h"
56
#include "beirg.h"
57
#include "bestack.h"
58
#include "beemitter.h"
Sebastian Hack's avatar
Sebastian Hack committed
59

60
61
#define NEW_ID(s) new_id_from_chars(s, sizeof(s) - 1)

Sebastian Hack's avatar
Sebastian Hack committed
62
/* options visible for anyone */
63
be_options_t be_options = {
64
	DUMP_NONE,                         /* dump flags */
65
	BE_TIME_OFF,                       /* no timing */
66
67
	false,                             /* profile_generate */
	false,                             /* profile_use */
Michael Beck's avatar
Michael Beck committed
68
	0,                                 /* try to omit frame pointer */
69
	0,                                 /* create PIC code */
70
	BE_VERIFY_WARN,                    /* verification level: warn */
Sebastian Hack's avatar
Sebastian Hack committed
71
	"",                                /* ilp server */
72
	"",                                /* ilp solver */
73
	1,                                 /* verbose assembler output */
Sebastian Hack's avatar
Sebastian Hack committed
74
75
76
};

/* back end instruction set architecture to use */
77
static const arch_isa_if_t *isa_if = NULL;
Michael Beck's avatar
Michael Beck committed
78

Sebastian Hack's avatar
Sebastian Hack committed
79
80
/* possible dumping options */
static const lc_opt_enum_mask_items_t dump_items[] = {
81
	{ "none",       DUMP_NONE },
Sebastian Hack's avatar
Sebastian Hack committed
82
	{ "initial",    DUMP_INITIAL },
83
	{ "abi",        DUMP_ABI    },
Sebastian Hack's avatar
Sebastian Hack committed
84
85
	{ "sched",      DUMP_SCHED  },
	{ "prepared",   DUMP_PREPARED },
86
	{ "regalloc",   DUMP_RA },
Sebastian Hack's avatar
Sebastian Hack committed
87
	{ "final",      DUMP_FINAL },
88
89
	{ "be",         DUMP_BE },
	{ "all",        2 * DUMP_BE - 1 },
Sebastian Hack's avatar
Sebastian Hack committed
90
91
92
	{ NULL,         0 }
};

Christian Würdig's avatar
Christian Würdig committed
93
/* verify options. */
94
95
96
97
static const lc_opt_enum_int_items_t verify_items[] = {
	{ "off",    BE_VERIFY_OFF    },
	{ "warn",   BE_VERIFY_WARN   },
	{ "assert", BE_VERIFY_ASSERT },
Christian Würdig's avatar
Christian Würdig committed
98
	{ NULL,     0 }
Christian Würdig's avatar
Christian Würdig committed
99
};
100

Sebastian Hack's avatar
Sebastian Hack committed
101
static lc_opt_enum_mask_var_t dump_var = {
102
	&be_options.dump_flags, dump_items
103
104
};

105
106
static lc_opt_enum_int_var_t verify_var = {
	&be_options.verify_option, verify_items
Christian Würdig's avatar
Christian Würdig committed
107
108
};

Sebastian Hack's avatar
Sebastian Hack committed
109
static const lc_opt_table_entry_t be_main_options[] = {
110
111
112
	LC_OPT_ENT_ENUM_MASK("dump",       "dump irg on several occasions",                       &dump_var),
	LC_OPT_ENT_BOOL     ("omitfp",     "omit frame pointer",                                  &be_options.omit_fp),
	LC_OPT_ENT_BOOL     ("pic",        "create PIC code",                                     &be_options.pic),
113
	LC_OPT_ENT_ENUM_INT ("verify",     "verify the backend irg",                              &verify_var),
114
	LC_OPT_ENT_BOOL     ("time",       "get backend timing statistics",                       &be_options.timing),
115
116
	LC_OPT_ENT_BOOL     ("profilegenerate", "instrument the code for execution count profiling",   &be_options.opt_profile_generate),
	LC_OPT_ENT_BOOL     ("profileuse",      "use existing profile data",                           &be_options.opt_profile_use),
117
	LC_OPT_ENT_BOOL     ("verboseasm", "enable verbose assembler output",                     &be_options.verbose_asm),
118

119
120
	LC_OPT_ENT_STR("ilp.server", "the ilp server name", &be_options.ilp_server),
	LC_OPT_ENT_STR("ilp.solver", "the ilp solver name", &be_options.ilp_solver),
121
	LC_OPT_LAST
Sebastian Hack's avatar
Sebastian Hack committed
122
123
};

124
125
static be_module_list_entry_t *isa_ifs         = NULL;
static bool                    isa_initialized = false;
126

127
asm_constraint_flags_t asm_constraint_flags[256];
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
static void be_init_default_asm_constraint_flags(void)
{
	/* list of constraints supported by gcc for any machine (or at least
	 * recognized). Mark them as NO_SUPPORT so we can differentiate them
	 * from INVALID. Backends should change the flags they support. */
	static const unsigned char gcc_common_flags[] = {
		'?', '!', '&', '%', 'i', 's', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
		'M', 'N', 'O', 'P', 'm', 'o', 'r', 'V', '<', '>', 'p', 'g', 'X',
		'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	};
	for (size_t i = 0; i < ARRAY_SIZE(gcc_common_flags); ++i) {
		unsigned char const c = gcc_common_flags[i];
		asm_constraint_flags[c] = ASM_CONSTRAINT_FLAG_NO_SUPPORT;
	}
}

145
146
147
148
static void initialize_isa(void)
{
	if (isa_initialized)
		return;
149
	be_init_default_asm_constraint_flags();
150
	isa_if->init();
Matthias Braun's avatar
Matthias Braun committed
151
152
153
154
155
156
157
158
159
	isa_initialized = true;
}

static void finish_isa(void)
{
	if (isa_initialized) {
		isa_if->finish();
		isa_initialized = false;
	}
160
161
}

162
asm_constraint_flags_t be_parse_asm_constraints(const char *constraint)
163
{
164
	asm_constraint_flags_t  flags = ASM_CONSTRAINT_FLAG_NONE;
165
166
167
	const char             *c;
	asm_constraint_flags_t  tflags;

168
169
	initialize_isa();

170
171
	for (c = constraint; *c != '\0'; ++c) {
		switch (*c) {
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
		case ' ':
		case '\t':
		case '\n':
		case '\r':
			break;
		case '=':
			flags |= ASM_CONSTRAINT_FLAG_MODIFIER_WRITE;
			flags |= ASM_CONSTRAINT_FLAG_MODIFIER_NO_READ;
			break;
		case '+':
			flags |= ASM_CONSTRAINT_FLAG_MODIFIER_READ;
			flags |= ASM_CONSTRAINT_FLAG_MODIFIER_WRITE;
			break;
		case '&':
		case '%':
			/* not really supported by libFirm yet */
			flags |= ASM_CONSTRAINT_FLAG_NO_SUPPORT;
			break;
190
		case '#':
191
			/* text until comma is a comment */
192
			while (*c != 0 && *c != ',')
193
194
195
				++c;
			break;
		case '*':
196
			/* next character is a comment */
197
198
199
200
201
202
203
			++c;
			break;
		default:
			tflags = asm_constraint_flags[(int) *c];
			if (tflags != 0) {
				flags |= tflags;
			} else {
204
				flags |= ASM_CONSTRAINT_FLAG_INVALID;
205
206
207
208
209
			}
			break;
		}
	}

210
	if ((
211
212
	        flags & ASM_CONSTRAINT_FLAG_MODIFIER_WRITE &&
	        flags & ASM_CONSTRAINT_FLAG_MODIFIER_NO_WRITE
213
	    ) || (
214
215
	        flags & ASM_CONSTRAINT_FLAG_MODIFIER_READ &&
	        flags & ASM_CONSTRAINT_FLAG_MODIFIER_NO_READ
216
	    )) {
217
218
		flags |= ASM_CONSTRAINT_FLAG_INVALID;
	}
219
220
221
222
223
	if (!(flags & (ASM_CONSTRAINT_FLAG_MODIFIER_READ     |
	               ASM_CONSTRAINT_FLAG_MODIFIER_WRITE    |
	               ASM_CONSTRAINT_FLAG_MODIFIER_NO_WRITE |
	               ASM_CONSTRAINT_FLAG_MODIFIER_NO_READ)
	    )) {
224
225
		flags |= ASM_CONSTRAINT_FLAG_MODIFIER_READ;
	}
226
227
228
229

	return flags;
}

230
int be_is_valid_clobber(const char *clobber)
231
{
232
233
	initialize_isa();

234
235
236
	/* memory is a valid clobber. (the frontend has to detect this case too,
	 * because it has to add memory edges to the asm) */
	if (strcmp(clobber, "memory") == 0)
237
		return 1;
238
239
	/* cc (condition code) is always valid */
	if (strcmp(clobber, "cc") == 0)
240
		return 1;
241

242
	return isa_if->is_valid_clobber(clobber);
243
244
}

245
246
void be_register_isa_if(const char *name, const arch_isa_if_t *isa)
{
247
	if (isa_if == NULL)
248
249
250
251
252
		isa_if = isa;

	be_add_module_to_list(&isa_ifs, name, (void*) isa);
}

253
static void be_opt_register(void)
Sebastian Hack's avatar
Sebastian Hack committed
254
{
255
	lc_opt_entry_t *be_grp;
256
257
	static int run_once = 0;

258
	if (run_once)
259
		return;
260
	run_once = 1;
261

262
263
	be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
	lc_opt_add_table(be_grp, be_main_options);
264
265
266

	be_add_module_list_opt(be_grp, "isa", "the instruction set architecture",
	                       &isa_ifs, (void**) &isa_if);
267
268

	be_init_modules();
269
}
Sebastian Hack's avatar
Sebastian Hack committed
270

271
/* Parse one argument. */
272
273
int be_parse_arg(const char *arg)
{
274
	lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
Michael Beck's avatar
Michael Beck committed
275
	if (strcmp(arg, "help") == 0 || (arg[0] == '?' && arg[1] == '\0')) {
276
		lc_opt_print_help_for_entry(be_grp, '-', stdout);
Michael Beck's avatar
Michael Beck committed
277
278
		return -1;
	}
279
	return lc_opt_from_single_arg(be_grp, arg);
280
281
}

Christian Würdig's avatar
Christian Würdig committed
282
/* Perform schedule verification if requested. */
283
static void be_sched_verify(ir_graph *irg, int verify_opt)
284
{
285
	if (verify_opt == BE_VERIFY_WARN) {
286
		be_verify_schedule(irg);
287
	} else if (verify_opt == BE_VERIFY_ASSERT) {
288
		assert(be_verify_schedule(irg) && "Schedule verification failed.");
Christian Würdig's avatar
Christian Würdig committed
289
290
291
	}
}

292
293
/* Initialize the Firm backend. Must be run first in init_firm()! */
void firm_be_init(void)
294
{
Sebastian Hack's avatar
Sebastian Hack committed
295
	be_opt_register();
296
	be_init_modules();
297
}
298

yb9976's avatar
yb9976 committed
299
300
301
/* Finalize the Firm backend. */
void firm_be_finish(void)
{
Matthias Braun's avatar
Matthias Braun committed
302
	finish_isa();
yb9976's avatar
yb9976 committed
303
304
305
	be_quit_modules();
}

306
307
308
/* Returns the backend parameter */
const backend_params *be_get_backend_param(void)
{
309
	initialize_isa();
310
	return isa_if->get_params();
311
312
}

Manuel Mohr's avatar
Manuel Mohr committed
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
int be_is_big_endian(void)
{
	return be_get_backend_param()->byte_order_big_endian;
}

unsigned be_get_machine_size(void)
{
	return be_get_backend_param()->machine_size;
}

ir_mode *be_get_mode_float_arithmetic(void)
{
	return be_get_backend_param()->mode_float_arithmetic;
}

ir_type *be_get_type_long_long(void)
{
	return be_get_backend_param()->type_long_long;
}

ir_type *be_get_type_unsigned_long_long(void)
{
	return be_get_backend_param()->type_unsigned_long_long;
}

ir_type *be_get_type_long_double(void)
{
	return be_get_backend_param()->type_long_double;
}

343
344
345
346
347
348
/**
 * Initializes the main environment for the backend.
 *
 * @param env          an empty environment
 * @param file_handle  the file handle where the output will be written to
 */
349
static be_main_env_t *be_init_env(be_main_env_t *const env, char const *const compilation_unit_name)
Sebastian Hack's avatar
Sebastian Hack committed
350
{
Sebastian Hack's avatar
Sebastian Hack committed
351
	memset(env, 0, sizeof(*env));
352
	env->ent_trampoline_map   = pmap_create();
353
	env->pic_trampolines_type = new_type_segment(NEW_ID("$PIC_TRAMPOLINE_TYPE"), tf_none);
354
	env->ent_pic_symbol_map   = pmap_create();
355
	env->pic_symbols_type     = new_type_segment(NEW_ID("$PIC_SYMBOLS_TYPE"), tf_none);
356
	env->cup_name             = compilation_unit_name;
357
	env->arch_env             = isa_if->begin_codegeneration();
358
359

	set_class_final(env->pic_trampolines_type, 1);
Sebastian Hack's avatar
Sebastian Hack committed
360

361
	memset(asm_constraint_flags, 0, sizeof(asm_constraint_flags));
Sebastian Hack's avatar
Sebastian Hack committed
362
363

	return env;
364
365
}

366
367
368
/**
 * Called when the be_main_env_t can be destroyed.
 */
Sebastian Hack's avatar
Sebastian Hack committed
369
static void be_done_env(be_main_env_t *env)
370
{
371
372
	pmap_destroy(env->ent_trampoline_map);
	pmap_destroy(env->ent_pic_symbol_map);
373
374
	free_type(env->pic_trampolines_type);
	free_type(env->pic_symbols_type);
Sebastian Hack's avatar
Sebastian Hack committed
375
}
Sebastian Hack's avatar
Sebastian Hack committed
376

377
378
379
380
381
382
383
384
385
/**
 * A wrapper around a firm dumper. Dumps only, if
 * flags are enabled.
 *
 * @param mask    a bitmask containing the reason what will be dumped
 * @param irg     the IR graph to dump
 * @param suffix  the suffix for the dumper
 * @param dumper  the dumper to be called
 */
386
static void dump(int mask, ir_graph *irg, const char *suffix)
Sebastian Hack's avatar
Sebastian Hack committed
387
{
388
	if (be_options.dump_flags & mask)
389
		dump_ir_graph(irg, suffix);
Sebastian Hack's avatar
Sebastian Hack committed
390
}
391

Michael Beck's avatar
Michael Beck committed
392
/**
393
 * Prepare a backend graph for code generation and initialize its irg
Michael Beck's avatar
Michael Beck committed
394
 */
395
static void initialize_birg(be_irg_t *birg, ir_graph *irg, be_main_env_t *env)
Sebastian Hack's avatar
Sebastian Hack committed
396
{
397
398
399
	/* don't duplicate locals in backend when dumping... */
	ir_remove_dump_flags(ir_dump_flag_consts_local);

400
401
	dump(DUMP_INITIAL, irg, "begin");

yb9976's avatar
yb9976 committed
402
403
	irg->be_data = birg;

404
405
	memset(birg, 0, sizeof(*birg));
	birg->main_env = env;
406
	obstack_init(&birg->obst);
407
	birg->lv = be_liveness_new(irg);
408

409
410
	edges_deactivate(irg);
	edges_activate(irg);
411
412
413
414

	/* set the current graph (this is important for several firm functions) */
	current_ir_graph = irg;

415
416
	/* we do this before critical edge split. As this produces less returns,
	   because sometimes (= 164.gzip) multiple returns are slower */
417
	normalize_n_returns(irg);
Sebastian Hack's avatar
Sebastian Hack committed
418

Sebastian Hack's avatar
Sebastian Hack committed
419
	/* Remove critical edges */
420
	remove_critical_cf_edges_ex(irg, /*ignore_exception_edges=*/0);
Sebastian Hack's avatar
Sebastian Hack committed
421

422
423
424
425
	/* For code generation all unreachable code and Bad nodes should be gone */
	remove_unreachable_code(irg);
	remove_bads(irg);

Sebastian Hack's avatar
Sebastian Hack committed
426
	/* Ensure, that the ir_edges are computed. */
427
	assure_edges(irg);
Sebastian Hack's avatar
Sebastian Hack committed
428

429
	be_info_init_irg(irg);
430

431
	dump(DUMP_INITIAL, irg, "prepared");
Sebastian Hack's avatar
Sebastian Hack committed
432
433
}

Matthias Braun's avatar
Matthias Braun committed
434
int be_timing;
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

static const char *get_timer_name(be_timer_id_t id)
{
	switch (id) {
	case T_ABI:            return "abi";
	case T_CODEGEN:        return "codegen";
	case T_RA_PREPARATION: return "ra_preparation";
	case T_SCHED:          return "sched";
	case T_CONSTR:         return "constr";
	case T_FINISH:         return "finish";
	case T_EMIT:           return "emit";
	case T_VERIFY:         return "verify";
	case T_OTHER:          return "other";
	case T_HEIGHTS:        return "heights";
	case T_LIVE:           return "live";
	case T_EXECFREQ:       return "execfreq";
	case T_SSA_CONSTR:     return "ssa_constr";
	case T_RA_EPILOG:      return "ra_epilog";
	case T_RA_CONSTR:      return "ra_constr";
	case T_RA_SPILL:       return "ra_spill";
	case T_RA_SPILL_APPLY: return "ra_spill_apply";
	case T_RA_COLOR:       return "ra_color";
	case T_RA_IFG:         return "ra_ifg";
	case T_RA_COPYMIN:     return "ra_copymin";
	case T_RA_SSA:         return "ra_ssa";
	case T_RA_OTHER:       return "ra_other";
	}
	return "unknown";
}
ir_timer_t *be_timers[T_LAST+1];
465

466
467
void be_lower_for_target(void)
{
Michael Beck's avatar
Michael Beck committed
468
	size_t i;
469

470
471
	initialize_isa();

472
473
	isa_if->lower_for_target();
	/* set the phase to low */
Michael Beck's avatar
Michael Beck committed
474
475
	for (i = get_irp_n_irgs(); i > 0;) {
		ir_graph *irg = get_irp_irg(--i);
476
477
		assert(!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_TARGET_LOWERED));
		add_irg_constraints(irg, IR_GRAPH_CONSTRAINT_TARGET_LOWERED);
478
479
480
	}
}

Michael Beck's avatar
Michael Beck committed
481
482
483
484
/**
 * The Firm backend main loop.
 * Do architecture specific lowering for all graphs
 * and call the architecture specific code generator.
485
486
 *
 * @param file_handle   the file handle the output will be written to
487
 * @param cup_name      name of the compilation unit
Michael Beck's avatar
Michael Beck committed
488
 */
489
static void be_main_loop(FILE *file_handle, const char *cup_name)
490
{
Adam Szalkowski's avatar
Adam Szalkowski committed
491
	static const char suffix[] = ".prof";
492

493
494
495
	size_t        i;
	size_t        num_irgs;
	size_t        num_birgs;
496
497
498
499
	be_main_env_t env;
	char          prof_filename[256];
	be_irg_t      *birgs;
	arch_env_t    *arch_env;
500

Matthias Braun's avatar
Matthias Braun committed
501
502
	be_timing = (be_options.timing == BE_TIME_ON);

503
	/* perform target lowering if it didn't happen yet */
504
	if (get_irp_n_irgs() > 0 && !irg_is_constrained(get_irp_irg(0), IR_GRAPH_CONSTRAINT_TARGET_LOWERED))
505
506
		be_lower_for_target();

Matthias Braun's avatar
Matthias Braun committed
507
	if (be_timing) {
508
509
510
		for (i = 0; i < T_LAST+1; ++i) {
			be_timers[i] = ir_timer_new();
		}
511
	}
512

513
514
515
516
	be_init_env(&env, cup_name);

	be_emit_init(file_handle);
	be_gas_begin_compilation_unit(&env);
517

518
519
	arch_env = env.arch_env;

Christian Würdig's avatar
Christian Würdig committed
520
	/* we might need 1 birg more for instrumentation constructor */
521
522
	num_irgs = get_irp_n_irgs();
	birgs    = ALLOCAN(be_irg_t, num_irgs + 1);
523

524
525
	be_info_init();

Christian Würdig's avatar
Christian Würdig committed
526
	/* First: initialize all birgs */
527
528
529
530
531
532
533
	num_birgs = 0;
	for (i = 0; i < num_irgs; ++i) {
		ir_graph  *irg    = get_irp_irg(i);
		ir_entity *entity = get_irg_entity(irg);
		if (get_entity_linkage(entity) & IR_LINKAGE_NO_CODEGEN)
			continue;
		initialize_birg(&birgs[num_birgs++], irg, &env);
534
	}
535
	arch_env_handle_intrinsics(arch_env);
Michael Beck's avatar
Michael Beck committed
536

Christian Würdig's avatar
Christian Würdig committed
537
538
539
540
	/*
		Get the filename for the profiling data.
		Beware: '\0' is already included in sizeof(suffix)
	*/
541
542
543
	sprintf(prof_filename, "%.*s%s",
	        (int)(sizeof(prof_filename) - sizeof(suffix)), cup_name, suffix);

544
	bool have_profile = false;
545
546
547
548
549
	if (be_options.opt_profile_use) {
		bool res = ir_profile_read(prof_filename);
		if (!res) {
			fprintf(stderr, "Warning: Couldn't read profile data '%s'\n",
			        prof_filename);
550
551
552
553
		} else {
			ir_create_execfreqs_from_profile();
			ir_profile_free();
			have_profile = true;
554
555
		}
	}
556

557
	if (num_birgs > 0 && be_options.opt_profile_generate) {
558
		ir_graph *const prof_init_irg = ir_profile_instrument(prof_filename);
559
		assert(prof_init_irg->be_data == NULL);
560
561
		initialize_birg(&birgs[num_birgs], prof_init_irg, &env);
		num_birgs++;
562
563
564
565
		num_irgs++;
		assert(num_irgs == get_irp_n_irgs());
	}

Matthias Braun's avatar
Matthias Braun committed
566
567
568
	for (be_timer_id_t t = T_FIRST; t < T_LAST+1; ++t) {
		ir_timer_init_parent(be_timers[t]);
	}
569
570
571
572
573
574
575
	if (!have_profile) {
		be_timer_push(T_EXECFREQ);
		for (i = 0; i < num_irgs; ++i) {
			ir_graph *irg = get_irp_irg(i);
			ir_estimate_execfreq(irg);
		}
		be_timer_pop(T_EXECFREQ);
576
	}
Adam Szalkowski's avatar
Adam Szalkowski committed
577

578
	/* For all graphs */
579
580
581
582
583
	for (i = 0; i < num_irgs; ++i) {
		ir_graph  *const irg    = get_irp_irg(i);
		ir_entity *const entity = get_irg_entity(irg);
		if (get_entity_linkage(entity) & IR_LINKAGE_NO_CODEGEN)
			continue;
Sebastian Hack's avatar
Sebastian Hack committed
584

585
586
587
		/* set the current graph (this is important for several firm functions) */
		current_ir_graph = irg;

588
		if (stat_ev_enabled) {
Matthias Braun's avatar
Matthias Braun committed
589
590
591
			stat_ev_ctx_push_fmt("bemain_irg", "%+F", irg);
			stat_ev_ull("bemain_insns_start", be_count_insns(irg));
			stat_ev_ull("bemain_blocks_start", be_count_blocks(irg));
Matthias Braun's avatar
Matthias Braun committed
592
		}
593

594
		/* stop and reset timers */
595
		be_timer_push(T_OTHER);
596

597
		/* Verify the initial graph */
598
		be_timer_push(T_VERIFY);
599
600
601
602
		if (be_options.verify_option == BE_VERIFY_WARN) {
			irg_verify(irg, VERIFY_ENFORCE_SSA);
		} else if (be_options.verify_option == BE_VERIFY_ASSERT) {
			assert(irg_verify(irg, VERIFY_ENFORCE_SSA) && "irg verification failed");
603
		}
604
		be_timer_pop(T_VERIFY);
605

606
		/* get a code generator for this graph. */
607
608
		if (arch_env->impl->init_graph)
			arch_env->impl->init_graph(irg);
609
610

		/* some transformations need to be done before abi introduce */
611
612
		if (arch_env->impl->before_abi != NULL)
			arch_env->impl->before_abi(irg);
613

Sebastian Hack's avatar
Sebastian Hack committed
614
		/* implement the ABI conventions. */
615
		if (!arch_env->custom_abi) {
616
617
618
			be_timer_push(T_ABI);
			be_abi_introduce(irg);
			be_timer_pop(T_ABI);
619
620
			dump(DUMP_ABI, irg, "abi");
		}
621

Andreas Zwinkau's avatar
Andreas Zwinkau committed
622
623
624
		/* We can't have Bad-blocks or critical edges in the backend.
		 * Before removing Bads, we remove unreachable code. */
		optimize_graph_df(irg);
625
		remove_critical_cf_edges(irg);
Andreas Zwinkau's avatar
Andreas Zwinkau committed
626
		remove_bads(irg);
627

628
629
630
		/* We often have dead code reachable through out-edges here. So for
		 * now we rebuild edges (as we need correct user count for code
		 * selection) */
631
632
633
		edges_deactivate(irg);
		edges_activate(irg);

634
		dump(DUMP_PREPARED, irg, "before-code-selection");
635

636
		/* perform codeselection */
637
		be_timer_push(T_CODEGEN);
638
639
		if (arch_env->impl->prepare_graph != NULL)
			arch_env->impl->prepare_graph(irg);
640
		be_timer_pop(T_CODEGEN);
Sebastian Hack's avatar
Sebastian Hack committed
641

642
643
		dump(DUMP_PREPARED, irg, "code-selection");

644
		/* disabled for now, fails for EmptyFor.c and XXEndless.c */
645
		/* be_live_chk_compare(irg); */
646

Christian Würdig's avatar
Christian Würdig committed
647
		/* schedule the irg */
648
		be_timer_push(T_SCHED);
649
		be_schedule_graph(irg);
650
		be_timer_pop(T_SCHED);
Sebastian Hack's avatar
Sebastian Hack committed
651

652
		dump(DUMP_SCHED, irg, "sched");
Christian Würdig's avatar
Christian Würdig committed
653

Christian Würdig's avatar
Christian Würdig committed
654
		/* check schedule */
655
		be_timer_push(T_VERIFY);
656
		be_sched_verify(irg, be_options.verify_option);
657
		be_timer_pop(T_VERIFY);
658

Christian Würdig's avatar
Christian Würdig committed
659
		/* introduce patterns to assure constraints */
660
		be_timer_push(T_CONSTR);
661
		/* we switch off optimizations here, because they might cause trouble */
662
		optimization_state_t state;
663
		save_optimization_state(&state);
664
		set_optimize(0);
665
666
		set_opt_cse(0);

667
668
		/* add Keeps for should_be_different constrained nodes  */
		/* beware: needs schedule due to usage of be_ssa_constr */
669
		assure_constraints(irg);
670
		be_timer_pop(T_CONSTR);
671

672
		dump(DUMP_SCHED, irg, "assured");
Christian Würdig's avatar
Christian Würdig committed
673

674
		/* stuff needs to be done after scheduling but before register allocation */
675
		be_timer_push(T_RA_PREPARATION);
676
677
		if (arch_env->impl->before_ra != NULL)
			arch_env->impl->before_ra(irg);
678
		be_timer_pop(T_RA_PREPARATION);
679

Sebastian Hack's avatar
Sebastian Hack committed
680
		/* connect all stack modifying nodes together (see beabi.c) */
681
		be_timer_push(T_ABI);
682
		be_abi_fix_stack_nodes(irg);
683
		be_timer_pop(T_ABI);
Christian Würdig's avatar
Christian Würdig committed
684

685
		dump(DUMP_SCHED, irg, "fix_stack");
Sebastian Hack's avatar
Sebastian Hack committed
686

Christian Würdig's avatar
Christian Würdig committed
687
		/* check schedule */
688
		be_timer_push(T_VERIFY);
689
		be_sched_verify(irg, be_options.verify_option);
690
		be_timer_pop(T_VERIFY);
Sebastian Hack's avatar
Sebastian Hack committed
691

692
		if (stat_ev_enabled) {
693
			stat_ev_dbl("bemain_costs_before_ra", be_estimate_irg_costs(irg));
Matthias Braun's avatar
Matthias Braun committed
694
695
			stat_ev_ull("bemain_insns_before_ra", be_count_insns(irg));
			stat_ev_ull("bemain_blocks_before_ra", be_count_blocks(irg));
Matthias Braun's avatar
Matthias Braun committed
696
		}
697

698
		/* Do register allocation */
699
		be_allocate_registers(irg);
700

701
		stat_ev_dbl("bemain_costs_before_ra", be_estimate_irg_costs(irg));
702

703
		dump(DUMP_RA, irg, "ra");
Christian Würdig's avatar
Christian Würdig committed
704

705
		be_timer_push(T_FINISH);
Matthias Braun's avatar
Matthias Braun committed
706
707
		if (arch_env->impl->finish_graph != NULL)
			arch_env->impl->finish_graph(irg);
708
		be_timer_pop(T_FINISH);
709

710
		dump(DUMP_FINAL, irg, "finish");
711

712
		if (stat_ev_enabled) {
Matthias Braun's avatar
Matthias Braun committed
713
714
			stat_ev_ull("bemain_insns_finish", be_count_insns(irg));
			stat_ev_ull("bemain_blocks_finish", be_count_blocks(irg));
Matthias Braun's avatar
Matthias Braun committed
715
716
		}

717
		/* check schedule and register allocation */
718
		be_timer_push(T_VERIFY);
719
720
		if (be_options.verify_option == BE_VERIFY_WARN) {
			irg_verify(irg, VERIFY_ENFORCE_SSA);
721
722
			be_verify_schedule(irg);
			be_verify_register_allocation(irg);
723
724
		} else if (be_options.verify_option == BE_VERIFY_ASSERT) {
			assert(irg_verify(irg, VERIFY_ENFORCE_SSA) && "irg verification failed");
725
726
			assert(be_verify_schedule(irg) && "Schedule verification failed");
			assert(be_verify_register_allocation(irg)
727
			       && "register allocation verification failed");
728

729
		}
730
		be_timer_pop(T_VERIFY);
731

Christian Würdig's avatar
Christian Würdig committed
732
		/* emit assembler code */
733
		be_timer_push(T_EMIT);
734
735
		if (arch_env->impl->emit != NULL)
			arch_env->impl->emit(irg);
736
		be_timer_pop(T_EMIT);
Christian Würdig's avatar
Christian Würdig committed
737

738
		dump(DUMP_FINAL, irg, "end");
Christian Würdig's avatar
Christian Würdig committed
739

740
		restore_optimization_state(&state);
741

742
743
744
		be_timer_pop(T_OTHER);

		if (be_timing) {
745
			be_timer_id_t t;
746
			if (stat_ev_enabled) {
747
				for (t = T_FIRST; t < T_LAST+1; ++t) {
748
749
750
					char buf[128];
					snprintf(buf, sizeof(buf), "bemain_time_%s",
					         get_timer_name(t));
Manuel Mohr's avatar
Manuel Mohr committed
751
					stat_ev_dbl(buf, ir_timer_elapsed_usec(be_timers[t]));
752
				}
Matthias Braun's avatar
Matthias Braun committed
753
			} else {
754
755
				printf("==>> IRG %s <<==\n",
				       get_entity_name(get_irg_entity(irg)));
756
				for (t = T_FIRST; t < T_LAST+1; ++t) {
757
					double val = ir_timer_elapsed_usec(be_timers[t]) / 1000.0;
758
					printf("%-20s: %10.3f msec\n", get_timer_name(t), val);
759
				}
760
			}
761
			for (t = T_FIRST; t < T_LAST+1; ++t) {
762
763
764
				ir_timer_reset(be_timers[t]);
			}
		}
Michael Beck's avatar
BugFix:    
Michael Beck committed
765

766
		be_free_birg(irg);
Sebastian Hack's avatar
Sebastian Hack committed
767
		stat_ev_ctx_pop("bemain_irg");
768
	}
769

770
771
772
	be_gas_end_compilation_unit(&env);
	be_emit_exit();

773
	arch_env_end_codegeneration(arch_env);
774

Sebastian Hack's avatar
Sebastian Hack committed
775
	be_done_env(&env);
776
777

	be_info_free();
778
779
}

Michael Beck's avatar
Michael Beck committed
780
/* Main interface to the frontend. */
781
void be_main(FILE *file_handle, const char *cup_name)
782
{
Matthias Braun's avatar
Matthias Braun committed
783
	ir_timer_t *t = NULL;
784

785
	if (be_options.timing == BE_TIME_ON) {
786
		t = ir_timer_new();
787

Matthias Braun's avatar
Matthias Braun committed
788
		if (ir_timer_enter_high_priority()) {
789
790
791
			fprintf(stderr, "Warning: Could not enter high priority mode.\n");
		}

Matthias Braun's avatar
Matthias Braun committed
792
		ir_timer_reset_and_start(t);
793
	}
794

795
	if (stat_ev_enabled) {
796
		const char *dot = strrchr(cup_name, '.');
Sebastian Hack's avatar
Sebastian Hack committed
797
		const char *pos = dot ? dot : cup_name + strlen(cup_name);
798
		char       *buf = ALLOCAN(char, pos - cup_name + 1);
Sebastian Hack's avatar
Sebastian Hack committed
799
		strncpy(buf, cup_name, pos - cup_name);
Sebastian Hack's avatar
Sebastian Hack committed
800
		buf[pos - cup_name] = '\0';
Sebastian Hack's avatar
Sebastian Hack committed
801

802
		stat_ev_ctx_push_str("bemain_compilation_unit", cup_name);
Sebastian Hack's avatar
Sebastian Hack committed
803
	}
804

805
	be_main_loop(file_handle, cup_name);
806
807

	if (be_options.timing == BE_TIME_ON) {
Matthias Braun's avatar
Matthias Braun committed
808
809
		ir_timer_stop(t);
		ir_timer_leave_high_priority();
810
		if (stat_ev_enabled) {