#include "beverify.h"
#include "be_dbgout.h"
#include "beirg.h"
+#include "bestack.h"
#define NEW_ID(s) new_id_from_chars(s, sizeof(s) - 1)
-#ifdef WITH_ILP
-#include "beilpsched.h"
-#endif /* WITH_ILP */
-
/* options visible for anyone */
static be_options_t be_options = {
DUMP_NONE, /* dump flags */
BE_TIME_OFF, /* no timing */
0, /* no opt profile */
0, /* try to omit frame pointer */
- 0, /* try to omit leaf frame pointer */
0, /* create PIC code */
0, /* create gprof compatible profiling code */
BE_VERIFY_WARN, /* verification level: warn */
- BE_SCHED_LIST, /* scheduler: list scheduler */
"linux", /* target OS name */
"i44pc52.info.uni-karlsruhe.de", /* ilp server */
"cplex", /* ilp solver */
{ NULL, 0 }
};
-/* scheduling options. */
-static const lc_opt_enum_int_items_t sched_items[] = {
- { "list", BE_SCHED_LIST },
-#ifdef WITH_ILP
- { "ilp", BE_SCHED_ILP },
-#endif /* WITH_ILP */
- { NULL, 0 }
-};
-
static lc_opt_enum_mask_var_t dump_var = {
&be_options.dump_flags, dump_items
};
&be_options.verify_option, verify_items
};
-static lc_opt_enum_int_var_t sched_var = {
- &be_options.scheduler, sched_items
-};
-
static const lc_opt_table_entry_t be_main_options[] = {
LC_OPT_ENT_STR ("config", "read another config file containing backend options", config_file, sizeof(config_file)),
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 ("omitleaffp", "omit frame pointer in leaf routines", &be_options.omit_leaf_fp),
LC_OPT_ENT_BOOL ("pic", "create PIC code", &be_options.pic),
LC_OPT_ENT_BOOL ("gprof", "create gprof profiling code", &be_options.gprof),
LC_OPT_ENT_ENUM_PTR ("verify", "verify the backend irg", &verify_var),
LC_OPT_ENT_BOOL ("time", "get backend timing statistics", &be_options.timing),
LC_OPT_ENT_BOOL ("profile", "instrument the code for execution count profiling", &be_options.opt_profile),
- LC_OPT_ENT_ENUM_PTR ("sched", "select a scheduler", &sched_var),
LC_OPT_ENT_STR ("os", "specify target operating system", &be_options.target_os, sizeof(be_options.target_os)),
#ifdef FIRM_STATISTICS
LC_OPT_ENT_BOOL ("statev", "dump statistic events", &be_options.statev),
return lc_opt_from_single_arg(be_grp, NULL, arg, NULL);
}
-/** The be parameters returned by default, all off. */
-static const backend_params be_params = {
- 0, /* don't support inline assembler yet */
- NULL, /* no lowering required */
- NULL, /* will be set later */
- NULL, /* no if conversion settings */
- NULL, /* no float arithmetic mode */
- 0, /* no trampoline support: size 0 */
- 0, /* no trampoline support: align 0 */
- NULL, /* no trampoline support: no trampoline builder */
- 4 /* alignment of stack parameter */
-};
-
/* Perform schedule verification if requested. */
static void be_sched_verify(ir_graph *irg, int verify_opt)
{
/* Returns the backend parameter */
const backend_params *be_get_backend_param(void)
{
- if (isa_if->get_params)
- return isa_if->get_params();
- return &be_params;
+ return isa_if->get_params();
}
/**
/* set the current graph (this is important for several firm functions) */
current_ir_graph = irg;
- /* Normalize proj nodes. */
- normalize_proj_nodes(irg);
-
/* we do this before critical edge split. As this produces less returns,
because sometimes (= 164.gzip) multiple returns are slower */
normalize_n_returns(irg);
dump(DUMP_INITIAL, irg, "prepared");
}
-#define BE_TIMER_ONLY(code) do { if (be_timing) { code; } } while (0)
-
int be_timing;
static const char *get_timer_name(be_timer_id_t id)
be_irg_t *birg = &birgs[i];
ir_graph *irg = birg->irg;
optimization_state_t state;
- const arch_code_generator_if_t *cg_if;
/* set the current graph (this is important for several firm functions) */
current_ir_graph = irg;
}
be_timer_pop(T_VERIFY);
- /* Get the code generator interface. */
- cg_if = arch_env_get_code_generator_if(arch_env);
-
/* get a code generator for this graph. */
- birg->cg = cg_if->init(irg);
+ arch_env->impl->init_graph(irg);
/* some transformations need to be done before abi introduce */
- assert(birg->cg->impl->before_abi == NULL || !arch_env->custom_abi);
- arch_code_generator_before_abi(birg->cg);
+ if (arch_env->impl->before_abi != NULL)
+ arch_env->impl->before_abi(irg);
/* implement the ABI conventions. */
be_timer_push(T_ABI);
/* perform codeselection */
be_timer_push(T_CODEGEN);
- arch_code_generator_prepare_graph(birg->cg);
+ if (arch_env->impl->prepare_graph != NULL)
+ arch_env->impl->prepare_graph(irg);
be_timer_pop(T_CODEGEN);
if (be_options.verify_option == BE_VERIFY_WARN) {
/* schedule the irg */
be_timer_push(T_SCHED);
- switch (be_options.scheduler) {
- default:
- fprintf(stderr, "Warning: invalid scheduler (%d) selected, falling back to list scheduler.\n", be_options.scheduler);
- case BE_SCHED_LIST:
- list_sched(irg);
- break;
-#ifdef WITH_ILP
- case BE_SCHED_ILP:
- be_ilp_sched(irg);
- break;
-#endif /* WITH_ILP */
- };
+ list_sched(irg);
be_timer_pop(T_SCHED);
dump(DUMP_SCHED, irg, "sched");
/* stuff needs to be done after scheduling but before register allocation */
be_timer_push(T_RA_PREPARATION);
- arch_code_generator_before_ra(birg->cg);
+ if (arch_env->impl->before_ra != NULL)
+ arch_env->impl->before_ra(irg);
be_timer_pop(T_RA_PREPARATION);
/* connect all stack modifying nodes together (see beabi.c) */
/* let the code generator prepare the graph for emitter */
be_timer_push(T_FINISH);
- arch_code_generator_after_ra(birg->cg);
+ if (arch_env->impl->after_ra != NULL)
+ arch_env->impl->after_ra(irg);
be_timer_pop(T_FINISH);
/* fix stack offsets */
dump(DUMP_SCHED, irg, "fix_stack_after_ra");
be_timer_push(T_FINISH);
- arch_code_generator_finish(birg->cg);
+ if (arch_env->impl->finish != NULL)
+ arch_env->impl->finish(irg);
be_timer_pop(T_FINISH);
dump(DUMP_FINAL, irg, "finish");
/* emit assembler code */
be_timer_push(T_EMIT);
- arch_code_generator_done(birg->cg);
+ if (arch_env->impl->emit != NULL)
+ arch_env->impl->emit(irg);
be_timer_pop(T_EMIT);
dump(DUMP_FINAL, irg, "end");