return &p;
}
-void be_init_arch_TEMPLATE()
-{
-}
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_TEMPLATE);
-
const arch_isa_if_t TEMPLATE_isa_if = {
TEMPLATE_init,
TEMPLATE_done,
TEMPLATE_get_reg_class_alignment,
TEMPLATE_get_libfirm_params,
};
+
+void be_init_arch_TEMPLATE(void)
+{
+ be_register_isa_if("TEMPLATE", &TEMPLATE_isa_if);
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_TEMPLATE);
LC_OPT_ENT_BOOL("gen_reg_names", "use generic register names", &arm_isa_template.gen_reg_names),
{ NULL }
};
-
-/**
- * Register command line options for the ARM backend.
- *
- * Options so far:
- *
- * arm-fpuunit=unit select the floating point unit
- * arm-gen_reg_names use generic register names instead of SP, LR, PC
- */
-void be_init_arch_arm(void)
-{
- lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
- lc_opt_entry_t *arm_grp = lc_opt_get_grp(be_grp, "arm");
-
- lc_opt_add_table(arm_grp, arm_options);
-}
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_arm);
#endif /* WITH_LIBCORE */
const arch_isa_if_t arm_isa_if = {
arm_get_allowed_execution_units,
arm_get_machine,
};
+
+void be_init_arch_arm(void)
+{
+ lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
+ lc_opt_entry_t *arm_grp = lc_opt_get_grp(be_grp, "arm");
+
+ lc_opt_add_table(arm_grp, arm_options);
+
+ be_register_isa_if("arm", &arm_isa_if);
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_arm);
*/
extern const arch_irn_handler_t *arch_env_pop_irn_handler(arch_env_t *env);
+/**
+ * Register an instruction set architecture
+ */
+void be_register_isa_if(const char *name, const arch_isa_if_t *isa);
+
#endif /* _FIRM_BEARCH_H */
static be_ra_chordal_opts_t options = {
BE_CH_DUMP_NONE,
- BE_CH_SPILL_BELADY,
BE_CH_IFG_STD,
BE_CH_LOWER_PERM_SWAP,
BE_CH_VRFY_WARN,
NULL,
};
-static const lc_opt_enum_int_items_t spill_items[] = {
- { "belady", BE_CH_SPILL_BELADY },
- { "morgan", BE_CH_SPILL_MORGAN },
-#ifdef WITH_ILP
- { "remat", BE_CH_SPILL_REMAT },
-#endif /* WITH_ILP */
- { NULL, 0 }
-};
-
static const lc_opt_enum_int_items_t ifg_flavor_items[] = {
{ "std", BE_CH_IFG_STD },
{ "fast", BE_CH_IFG_FAST },
{ NULL, 0 }
};
-static lc_opt_enum_int_var_t spill_var = {
- &options.spill_method, spill_items
-};
-
static lc_opt_enum_int_var_t ifg_flavor_var = {
&options.ifg_flavor, ifg_flavor_items
};
};
static const lc_opt_table_entry_t be_chordal_options[] = {
- LC_OPT_ENT_ENUM_INT ("spill", "spill method", &spill_var),
LC_OPT_ENT_ENUM_PTR ("ifg", "interference graph flavour", &ifg_flavor_var),
LC_OPT_ENT_ENUM_PTR ("perm", "perm lowering options", &lower_perm_var),
LC_OPT_ENT_ENUM_MASK("dump", "select dump phases", &dump_var),
pre_spill(isa, j, &pse);
BE_TIMER_PUSH(ra_timer.t_spill);
- /* spilling */
- switch(options.spill_method) {
- case BE_CH_SPILL_MORGAN:
- be_spill_morgan(&pse.cenv);
- break;
- case BE_CH_SPILL_BELADY:
- be_spill_belady(&pse.cenv);
- break;
- #ifdef WITH_ILP
- case BE_CH_SPILL_REMAT:
- be_spill_remat(&pse.cenv);
- break;
- #endif /* WITH_ILP */
- default:
- fprintf(stderr, "no valid spiller selected. falling back to belady\n");
- be_spill_belady(&pse.cenv);
- }
+ be_do_spill(&pse.cenv);
BE_TIMER_POP(ra_timer.t_spill);
dump(BE_CH_DUMP_SPILL, irg, pse.cenv.cls, "-spill", dump_ir_block_graph_sched);
void be_ra_chordal_check(be_chordal_env_t *chordal_env);
enum {
- /* spill method */
- BE_CH_SPILL_BELADY = 1,
- BE_CH_SPILL_MORGAN = 2,
- BE_CH_SPILL_REMAT = 3,
-
/* Dump flags */
BE_CH_DUMP_NONE = (1 << 0),
BE_CH_DUMP_SPILL = (1 << 1),
struct _be_ra_chordal_opts_t {
int dump_flags;
- int spill_method;
int ifg_flavor;
int lower_perm_opt;
int vrfy_option;
static char config_file[256] = { 0 };
/* back end instruction set architecture to use */
-static const arch_isa_if_t *isa_if = &ia32_isa_if;
+static const arch_isa_if_t *isa_if = NULL;
#ifdef WITH_LIBCORE
{ NULL, 0 }
};
-/* instruction set architectures. */
-static const lc_opt_enum_const_ptr_items_t isa_items[] = {
- { "ia32", &ia32_isa_if },
-#if 0
- { "sta", &sta_isa_if },
- { "arm", &arm_isa_if },
- { "ppc32", &ppc32_isa_if },
- { "mips", &mips_isa_if },
-#endif
- { NULL, NULL }
-};
-
/* verify options. */
static const lc_opt_enum_int_items_t vrfy_items[] = {
{ "off", BE_VRFY_OFF },
&be_options.dump_flags, dump_items
};
-static lc_opt_enum_const_ptr_var_t isa_var = {
- (const void **) &isa_if, isa_items
-};
-
static lc_opt_enum_int_var_t vrfy_var = {
&be_options.vrfy_option, vrfy_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_ENUM_PTR ("isa", "the instruction set architecture", &isa_var),
LC_OPT_ENT_NEGBOOL ("noomitfp", "do not omit frame pointer", &be_options.omit_fp),
LC_OPT_ENT_BOOL ("stabs", "enable stabs debug support", &be_options.stabs_debug_support),
LC_OPT_ENT_ENUM_PTR ("vrfy", "verify the backend irg", &vrfy_var),
#endif /* WITH_LIBCORE */
+static be_module_list_entry_t *isa_ifs = NULL;
+
+void be_register_isa_if(const char *name, const arch_isa_if_t *isa)
+{
+ if(isa_if == NULL)
+ isa_if = isa;
+
+ be_add_module_to_list(&isa_ifs, name, (void*) isa);
+}
+
void be_opt_register(void)
{
#ifdef WITH_LIBCORE
be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
lc_opt_add_table(be_grp, be_main_options);
+
+ be_add_module_list_opt(be_grp, "isa", "the instruction set architecture",
+ &isa_ifs, (void**) &isa_if);
#endif /* WITH_LIBCORE */
}
void be_init_arch_arm(void);
void be_init_ilpsched(void);
void be_init_copyilp(void);
-void be_init_spillremat(void);
void be_init_javacoal(void);
void be_init_ra(void);
+void be_init_spillbelady(void);
+void be_init_spillmorgan(void);
+void be_init_spillremat(void);
void be_quit_copystat(void);
be_init_raextern();
be_init_copystat();
be_init_ra();
+ be_init_spillbelady();
+ be_init_spillmorgan();
be_init_arch_ia32();
be_init_arch_ppc32();
#include "belive_t.h"
#include "benode_t.h"
#include "bechordal_t.h"
+#include "bespilloptions.h"
#define DBG_SPILL 1
#define DBG_WSETS 2
be_end_uses(env.uses);
obstack_free(&env.ob, NULL);
}
+
+void be_init_spillbelady(void)
+{
+ static be_spiller_t belady_spiller = {
+ be_spill_belady
+ };
+
+ be_register_spiller("belady", &belady_spiller);
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_spillbelady);
#include "bespillbelady.h"
#include "beverify.h"
#include "benodesets.h"
+#include "bespilloptions.h"
#define DBG_LIVE 1
#define DBG_LOOPANA 2
return outer_spills_needed;
}
-void be_spill_morgan(be_chordal_env_t *chordal_env) {
+void be_spill_morgan(const be_chordal_env_t *chordal_env) {
ir_graph *irg = chordal_env->irg;
morgan_env_t env;
be_delete_spill_env(env.senv);
obstack_free(&env.obst, NULL);
}
+
+void be_init_spillmorgan(void)
+{
+ static be_spiller_t morgan_spiller = {
+ be_spill_morgan
+ };
+
+ be_register_spiller("morgan", &morgan_spiller);
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_spillmorgan);
#include "be_t.h"
#include "bechordal.h"
-void be_spill_morgan(be_chordal_env_t *env);
+void be_spill_morgan(const be_chordal_env_t *env);
#endif
{ NULL }
};
+static be_module_list_entry_t *spillers = NULL;
+static be_spiller_t *selected_spiller = NULL;
+
+void be_register_spiller(const char *name, be_spiller_t *spiller)
+{
+ if(selected_spiller == NULL)
+ selected_spiller = spiller;
+ be_add_module_to_list(&spillers, name, spiller);
+}
+
+void be_do_spill(const be_chordal_env_t *env)
+{
+ assert(selected_spiller != NULL);
+ if(selected_spiller != NULL) {
+ selected_spiller->spill(env);
+ }
+}
+
void be_init_spill(void)
{
lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
lc_opt_entry_t *spill_grp = lc_opt_get_grp(be_grp, "spill");
lc_opt_add_table(spill_grp, be_spill_options);
+ be_add_module_list_opt(spill_grp, "spiller", "spill algorithm",
+ &spillers, (void**) &selected_spiller);
}
BE_REGISTER_MODULE_CONSTRUCTOR(be_init_spill);
#ifndef BESPILL_OPTIONS_H_
#define BESPILL_OPTIONS_H_
+#include "bechordal.h"
+
extern int be_coalesce_spill_slots;
extern int be_do_remats;
+typedef struct be_spiller_t {
+ void (*spill) (const be_chordal_env_t *env);
+} be_spiller_t;
+void be_register_spiller(const char *name, be_spiller_t *spiller);
+
+void be_do_spill(const be_chordal_env_t *env);
+
#endif
#include "bespill.h"
#include "bepressurestat.h"
#include "beprofile.h"
+#include "bespilloptions.h"
#include "bechordal_t.h"
{ NULL }
};
-void be_init_spillremat(void)
-{
- lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
- lc_opt_entry_t *ra_grp = lc_opt_get_grp(be_grp, "ra");
- lc_opt_entry_t *chordal_grp = lc_opt_get_grp(ra_grp, "chordal");
- lc_opt_entry_t *remat_grp = lc_opt_get_grp(chordal_grp, "remat");
-
- lc_opt_add_table(remat_grp, options);
-}
-
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_spillremat);
#endif
DBG((si.dbg, LEVEL_1, "\tdone.\n"));
}
+void be_init_spillremat(void)
+{
+ static be_spiller_t remat_spiller = {
+ be_spill_remat
+ };
+ lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
+ lc_opt_entry_t *ra_grp = lc_opt_get_grp(be_grp, "ra");
+ lc_opt_entry_t *chordal_grp = lc_opt_get_grp(ra_grp, "chordal");
+ lc_opt_entry_t *remat_grp = lc_opt_get_grp(chordal_grp, "remat");
+
+ be_register_spiller("remat", &remat_spiller);
+ lc_opt_add_table(remat_grp, options);
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_spillremat);
+
#else /* WITH_ILP */
static void INLINE
}
}
+const arch_isa_if_t ia32_isa_if;
/**
* The template that generates a new ISA object.
LC_OPT_ENT_ENUM_INT("gasmode", "set the GAS compatibility mode", &gas_var),
{ NULL }
};
-
-/**
- * Register command line options for the ia32 backend.
- *
- * Options so far:
- *
- * ia32-arch=arch create instruction for arch
- * ia32-opt=arch optimize for run on arch
- * ia32-fpunit=unit select floating point unit (x87 or SSE2)
- * ia32-incdec optimize for inc/dec
- * ia32-noaddrmode do not use address mode
- * ia32-nolea do not optimize for LEAs
- * ia32-noplacecnst do not place constants,
- * ia32-noimmop no operations with immediates
- * ia32-noextbb do not use extended basic block scheduling
- * ia32-nopushargs do not create pushs for function argument passing
- * ia32-gasmode set the GAS compatibility mode
- */
-void be_init_arch_ia32(void)
-{
- lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
- lc_opt_entry_t *ia32_grp = lc_opt_get_grp(be_grp, "ia32");
-
- lc_opt_add_table(ia32_grp, ia32_options);
-}
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_ia32);
#endif /* WITH_LIBCORE */
const arch_isa_if_t ia32_isa_if = {
ia32_get_allowed_execution_units,
ia32_get_machine,
};
+
+void be_init_arch_ia32(void)
+{
+ lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
+ lc_opt_entry_t *ia32_grp = lc_opt_get_grp(be_grp, "ia32");
+
+ lc_opt_add_table(ia32_grp, ia32_options);
+ be_register_isa_if("ia32", &ia32_isa_if);
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_ia32);
+++ /dev/null
-#ifndef _BEARCH_IA32_H_
-#define _BEARCH_IA32_H_
-
-#include "../bearch.h"
-
-extern const arch_isa_if_t ia32_isa_if;
-
-#endif /* _BEARCH_IA32_H_ */
#include "pmap.h"
#include "debug.h"
-#include "bearch_ia32.h"
#include "ia32_nodes_attr.h"
#include "set.h"
return &p;
}
-#ifdef WITH_LIBCORE
-void be_init_arch_mips(void)
-{
-}
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_mips);
-#endif /* WITH_LIBCORE */
-
const arch_isa_if_t mips_isa_if = {
mips_init,
mips_done,
mips_get_allowed_execution_units,
mips_get_machine,
};
+
+void be_init_arch_mips(void)
+{
+ be_register_isa_if("mips", &mips_isa_if);
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_mips);
return &p;
}
-void be_init_arch_ppc32(void)
-{
-}
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_ppc32);
-
const arch_isa_if_t ppc32_isa_if = {
ppc32_init,
ppc32_done,
ppc32_get_allowed_execution_units,
ppc32_get_machine,
};
+
+void be_init_arch_ppc32(void)
+{
+ be_register_isa_if("ppc32", &ppc32_isa_if);
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_ppc32);