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
 */
Michael Beck's avatar
Michael Beck committed
12
#include "config.h"
13

Sebastian Hack's avatar
Sebastian Hack committed
14
#include <stdarg.h>
15
#include <stdio.h>
16

Matthias Braun's avatar
Matthias Braun committed
17
18
#include "lc_opts.h"
#include "lc_opts_enum.h"
19

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

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

62
63
#define NEW_ID(s) new_id_from_chars(s, sizeof(s) - 1)

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

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

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

Christian Würdig's avatar
Christian Würdig committed
95
/* verify options. */
96
97
98
99
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
100
	{ NULL,     0 }
Christian Würdig's avatar
Christian Würdig committed
101
};
102

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

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

Sebastian Hack's avatar
Sebastian Hack committed
111
static const lc_opt_table_entry_t be_main_options[] = {
112
113
114
	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),
115
	LC_OPT_ENT_ENUM_INT ("verify",     "verify the backend irg",                              &verify_var),
116
	LC_OPT_ENT_BOOL     ("time",       "get backend timing statistics",                       &be_options.timing),
117
118
	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),
119
	LC_OPT_ENT_BOOL     ("verboseasm", "enable verbose assembler output",                     &be_options.verbose_asm),
120

121
122
	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),
123
	LC_OPT_LAST
Sebastian Hack's avatar
Sebastian Hack committed
124
125
};

126
127
static be_module_list_entry_t *isa_ifs         = NULL;
static bool                    isa_initialized = false;
128

129
asm_constraint_flags_t asm_constraint_flags[256];
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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;
	}
}

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

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

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

170
171
	initialize_isa();

172
173
	for (c = constraint; *c != '\0'; ++c) {
		switch (*c) {
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
		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;
192
		case '#':
193
			/* text until comma is a comment */
194
			while (*c != 0 && *c != ',')
195
196
197
				++c;
			break;
		case '*':
198
			/* next character is a comment */
199
200
201
202
203
204
205
			++c;
			break;
		default:
			tflags = asm_constraint_flags[(int) *c];
			if (tflags != 0) {
				flags |= tflags;
			} else {
206
				flags |= ASM_CONSTRAINT_FLAG_INVALID;
207
208
209
210
211
			}
			break;
		}
	}

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

	return flags;
}

232
int be_is_valid_clobber(const char *clobber)
233
{
234
235
	initialize_isa();

236
237
238
	/* 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)
239
		return 1;
240
241
	/* cc (condition code) is always valid */
	if (strcmp(clobber, "cc") == 0)
242
		return 1;
243

244
	return isa_if->is_valid_clobber(clobber);
245
246
}

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

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

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

260
	if (run_once)
261
		return;
262
	run_once = 1;
263

264
265
	be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
	lc_opt_add_table(be_grp, be_main_options);
266
267
268

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

	be_init_modules();
271
}
Sebastian Hack's avatar
Sebastian Hack committed
272

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

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

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

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

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

Manuel Mohr's avatar
Manuel Mohr committed
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
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;
}

345
346
347
348
349
350
/**
 * 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
 */
351
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
352
{
Sebastian Hack's avatar
Sebastian Hack committed
353
	memset(env, 0, sizeof(*env));
354
	env->ent_trampoline_map   = pmap_create();
355
	env->pic_trampolines_type = new_type_segment(NEW_ID("$PIC_TRAMPOLINE_TYPE"), tf_none);
356
	env->ent_pic_symbol_map   = pmap_create();
357
	env->pic_symbols_type     = new_type_segment(NEW_ID("$PIC_SYMBOLS_TYPE"), tf_none);
358
	env->cup_name             = compilation_unit_name;
359
	env->arch_env             = isa_if->begin_codegeneration();
360
361

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

363
	memset(asm_constraint_flags, 0, sizeof(asm_constraint_flags));
Sebastian Hack's avatar
Sebastian Hack committed
364
365

	return env;
366
367
}

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

379
380
381
382
383
384
385
386
387
/**
 * 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
 */
388
static void dump(int mask, ir_graph *irg, const char *suffix)
Sebastian Hack's avatar
Sebastian Hack committed
389
{
390
	if (be_options.dump_flags & mask)
391
		dump_ir_graph(irg, suffix);
Sebastian Hack's avatar
Sebastian Hack committed
392
}
393

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

402
403
	dump(DUMP_INITIAL, irg, "begin");

yb9976's avatar
yb9976 committed
404
405
	irg->be_data = birg;

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

411
412
	edges_deactivate(irg);
	edges_activate(irg);
413
414
415
416

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

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

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

424
425
426
427
	/* 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
428
	/* Ensure, that the ir_edges are computed. */
429
	assure_edges(irg);
Sebastian Hack's avatar
Sebastian Hack committed
430

431
	be_info_init_irg(irg);
432

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

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

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];
467

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

472
473
	initialize_isa();

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

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

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

Matthias Braun's avatar
Matthias Braun committed
503
504
	be_timing = (be_options.timing == BE_TIME_ON);

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

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

515
516
517
518
	be_init_env(&env, cup_name);

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

520
521
	arch_env = env.arch_env;

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

526
527
	be_info_init();

Christian Würdig's avatar
Christian Würdig committed
528
	/* First: initialize all birgs */
529
530
531
532
533
534
535
	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);
536
	}
537
	arch_env_handle_intrinsics(arch_env);
Michael Beck's avatar
Michael Beck committed
538

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

546
	bool have_profile = false;
547
548
549
550
551
	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);
552
553
554
555
		} else {
			ir_create_execfreqs_from_profile();
			ir_profile_free();
			have_profile = true;
556
557
		}
	}
558

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

Matthias Braun's avatar
Matthias Braun committed
568
569
570
	for (be_timer_id_t t = T_FIRST; t < T_LAST+1; ++t) {
		ir_timer_init_parent(be_timers[t]);
	}
571
572
573
574
575
576
577
	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);
578
	}
Adam Szalkowski's avatar
Adam Szalkowski committed
579

580
	/* For all graphs */
581
582
583
584
585
	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
586

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

590
		if (stat_ev_enabled) {
Matthias Braun's avatar
Matthias Braun committed
591
592
593
			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
594
		}
595

596
		/* stop and reset timers */
597
		be_timer_push(T_OTHER);
598

599
		/* Verify the initial graph */
600
		be_timer_push(T_VERIFY);
601
602
603
604
		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");
605
		}
606
		be_timer_pop(T_VERIFY);
607

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

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

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

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

630
631
632
		/* 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) */
633
634
635
		edges_deactivate(irg);
		edges_activate(irg);

636
		dump(DUMP_PREPARED, irg, "before-code-selection");
637

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

644
645
		dump(DUMP_PREPARED, irg, "code-selection");

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

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

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

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

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

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

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

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

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

687
		dump(DUMP_SCHED, irg, "fix_stack");
Sebastian Hack's avatar
Sebastian Hack committed
688

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

694
		if (stat_ev_enabled) {
695
			stat_ev_dbl("bemain_costs_before_ra", be_estimate_irg_costs(irg));
Matthias Braun's avatar
Matthias Braun committed
696
697
			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
698
		}
699

700
		/* Do register allocation */
701
		be_allocate_registers(irg);
702

703
		stat_ev_dbl("bemain_costs_before_ra", be_estimate_irg_costs(irg));
704

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

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

712
		dump(DUMP_FINAL, irg, "finish");
713

714
		if (stat_ev_enabled) {
Matthias Braun's avatar
Matthias Braun committed
715
716
			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
717
718
		}

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

731
		}
732
		be_timer_pop(T_VERIFY);
733

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

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

742
		restore_optimization_state(&state);
743

744
745
746
		be_timer_pop(T_OTHER);

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

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

772
773
774
	be_gas_end_compilation_unit(&env);
	be_emit_exit();

775
	arch_env_end_codegeneration(arch_env);
776

Sebastian Hack's avatar
Sebastian Hack committed
777
	be_done_env(&env);
778
779

	be_info_free();
780
781
}

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

787
	if (be_options.timing == BE_TIME_ON) {
788
		t = ir_timer_new();
789

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

Matthias Braun's avatar
Matthias Braun committed
794
		ir_timer_reset_and_start(t);
795
	}
796

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

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

807
	be_main_loop(file_handle, cup_name);
808
809

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