X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbelistsched.c;h=498cf28d469139dae495e8acd9192dae3d1934d4;hb=80a6158fdd766f42ee6c508a773bc114ff1b61f3;hp=6c2ff32f0eaa5ba1f26f0018ea8cbcc8c6a75531;hpb=7a83ec4ed8aad4ed16a3c03dc009c4650c281f2e;p=libfirm diff --git a/ir/be/belistsched.c b/ir/be/belistsched.c index 6c2ff32f0..498cf28d4 100644 --- a/ir/be/belistsched.c +++ b/ir/be/belistsched.c @@ -32,14 +32,81 @@ #include "debug.h" #include "irtools.h" +#include "bemodule.h" #include "besched_t.h" #include "beutil.h" #include "belive_t.h" #include "belistsched.h" #include "beschedmris.h" +#include "beschedrss.h" #include "bearch.h" #include "bestat.h" +#ifdef WITH_LIBCORE +#include +#include +#endif /* WITH_LIBCORE */ + +enum { + BE_SCHED_SELECT_TRIVIAL = 0, + BE_SCHED_SELECT_REGPRESS = 1, + BE_SCHED_SELECT_MUCHNIK = 2, + BE_SCHED_SELECT_HEUR = 3, + BE_SCHED_SELECT_HMUCHNIK = 4, + BE_SCHED_SELECT_RANDOM = 5 +}; + +enum { + BE_SCHED_PREP_NONE = 0, + BE_SCHED_PREP_MRIS = 2, + BE_SCHED_PREP_RSS = 3 +}; + +typedef struct _list_sched_options_t { + int select; /**< the node selector */ + int prep; /**< schedule preparation */ +} list_sched_options_t; + +static list_sched_options_t list_sched_options = { + BE_SCHED_SELECT_HEUR, /* mueller heuristic selector */ + BE_SCHED_PREP_NONE, /* no scheduling preparation */ +}; + +#ifdef WITH_LIBCORE +/* schedule selector options. */ +static const lc_opt_enum_int_items_t sched_select_items[] = { + { "trivial", BE_SCHED_SELECT_TRIVIAL }, + { "random", BE_SCHED_SELECT_RANDOM }, + { "regpress", BE_SCHED_SELECT_REGPRESS }, + { "muchnik", BE_SCHED_SELECT_MUCHNIK }, + { "heur", BE_SCHED_SELECT_HEUR }, + { "hmuchnik", BE_SCHED_SELECT_HMUCHNIK }, + { NULL, 0 } +}; + +/* schedule preparation options. */ +static const lc_opt_enum_int_items_t sched_prep_items[] = { + { "none", BE_SCHED_PREP_NONE }, + { "mris", BE_SCHED_PREP_MRIS }, + { "rss", BE_SCHED_PREP_RSS }, + { NULL, 0 } +}; + +static lc_opt_enum_int_var_t sched_select_var = { + &list_sched_options.select, sched_select_items +}; + +static lc_opt_enum_int_var_t sched_prep_var = { + &list_sched_options.prep, sched_prep_items +}; + +static const lc_opt_table_entry_t list_sched_option_table[] = { + LC_OPT_ENT_ENUM_PTR("prep", "schedule preparation", &sched_prep_var), + LC_OPT_ENT_ENUM_PTR("select", "node selector", &sched_select_var), + { NULL } +}; +#endif /* WITH_LIBCORE */ + /** * All scheduling info needed per node. */ @@ -107,7 +174,7 @@ static INLINE int make_ready(block_sched_env_t *env, ir_node *pred, ir_node *irn int i, n; /* Blocks cannot be scheduled. */ - if (is_Block(irn)) + if (is_Block(irn) || get_irn_n_edges(irn) == 0) return 0; /* @@ -287,9 +354,6 @@ static ir_node *add_to_sched(block_sched_env_t *env, ir_node *irn) /* If the node consumes/produces data, it is appended to the schedule * list, otherwise, it is not put into the list */ if (must_appear_in_schedule(env->selector, env->selector_block_env, irn)) { - sched_info_t *info = get_irn_sched_info(irn); - INIT_LIST_HEAD(&info->list); - info->scheduled = 1; update_sched_liveness(env, irn); sched_add_before(env->block, irn); @@ -329,8 +393,16 @@ static void add_tuple_projs(block_sched_env_t *env, ir_node *irn) if(is_Bad(irn)) return; + + /* non-proj nodes can have dependency edges to tuple nodes. */ + foreach_out_edge_kind(irn, edge, EDGE_KIND_DEP) { + ir_node *out = get_edge_src_irn(edge); + make_ready(env, irn, out); + } + + /* schedule the normal projs */ foreach_out_edge(irn, edge) { - ir_node *out = edge->src; + ir_node *out = get_edge_src_irn(edge); assert(is_Proj(out) && "successor of a modeT node must be a proj"); @@ -359,7 +431,6 @@ static void list_sched_block(ir_node *block, void *env_ptr) sched_env_t *env = env_ptr; const list_sched_selector_t *selector = env->selector; ir_node *start_node = get_irg_start(get_irn_irg(block)); - sched_info_t *info = get_irn_sched_info(block); block_sched_env_t be; const ir_edge_t *edge; @@ -367,15 +438,15 @@ static void list_sched_block(ir_node *block, void *env_ptr) int j, m; /* Initialize the block's list head that will hold the schedule. */ - INIT_LIST_HEAD(&info->list); + sched_init_block(block); /* Initialize the block scheduling environment */ - be.sched_info = env->sched_info; - be.block = block; - be.cands = new_nodeset(get_irn_n_edges(block)); - be.live = new_nodeset(get_irn_n_edges(block)); - be.selector = selector; - be.sched_env = env; + be.sched_info = env->sched_info; + be.block = block; + be.cands = new_nodeset(get_irn_n_edges(block)); + be.live = new_nodeset(get_irn_n_edges(block)); + be.selector = selector; + be.sched_env = env; FIRM_DBG_REGISTER(be.dbg, "firm.be.sched"); DBG((be.dbg, LEVEL_1, "scheduling %+F\n", block)); @@ -391,6 +462,9 @@ static void list_sched_block(ir_node *block, void *env_ptr) if (get_irn_opcode(irn) == iro_End) continue; + if (get_irn_n_edges(irn) == 0) + continue; + if (is_Phi(irn)) { /* Phi functions are scheduled immediately, since they only @@ -438,7 +512,7 @@ static void list_sched_block(ir_node *block, void *env_ptr) /* Keeps must be scheduled immediatly */ foreach_nodeset(be.cands, irn) { - if (be_is_Keep(irn) || be_is_CopyKeep(irn)) { + if (be_is_Keep(irn) || be_is_CopyKeep(irn) || get_irn_mode(irn) == mode_M) { nodeset_break(be.cands); break; } @@ -474,19 +548,22 @@ static void list_sched_block(ir_node *block, void *env_ptr) /* List schedule a graph. */ void list_sched(const be_irg_t *birg, be_options_t *be_opts) { - const arch_env_t *arch_env = birg->main_env->arch_env; - ir_graph *irg = birg->irg; + const arch_env_t *arch_env = birg->main_env->arch_env; + ir_graph *irg = birg->irg; int num_nodes; sched_env_t env; - mris_env_t *mris; + mris_env_t *mris = NULL; list_sched_selector_t sel; /* Select a scheduler based on backend options */ - switch (be_opts->sched_select) { + switch (list_sched_options.select) { case BE_SCHED_SELECT_TRIVIAL: memcpy(&sel, trivial_selector, sizeof(sel)); break; + case BE_SCHED_SELECT_RANDOM: + memcpy(&sel, random_selector, sizeof(sel)); + break; case BE_SCHED_SELECT_REGPRESS: memcpy(&sel, reg_pressure_selector, sizeof(sel)); break; @@ -502,10 +579,19 @@ void list_sched(const be_irg_t *birg, be_options_t *be_opts) } /* Assure, that the out edges are computed */ - edges_assure(irg); + edges_deactivate(birg->irg); + edges_activate(birg->irg); - if (be_opts->mris) - mris = be_sched_mris_preprocess(birg); + switch (list_sched_options.prep) { + case BE_SCHED_PREP_MRIS: + mris = be_sched_mris_preprocess(birg); + break; + case BE_SCHED_PREP_RSS: + rss_schedule_preparation(birg); + break; + default: + break; + } num_nodes = get_irg_last_idx(irg); @@ -527,8 +613,22 @@ void list_sched(const be_irg_t *birg, be_options_t *be_opts) if (env.selector->finish_graph) env.selector->finish_graph(env.selector_env); - if (be_opts->mris) + if (list_sched_options.prep == BE_SCHED_PREP_MRIS) be_sched_mris_free(mris); DEL_ARR_F(env.sched_info); } + +#ifdef WITH_LIBCORE +/** + * Register list scheduler options. + */ +void be_init_listsched(void) { + lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be"); + lc_opt_entry_t *sched_grp = lc_opt_get_grp(be_grp, "listsched"); + + lc_opt_add_table(sched_grp, list_sched_option_table); +} + +BE_REGISTER_MODULE_CONSTRUCTOR(be_init_listsched); +#endif /* WITH_LIBCORE */