X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeblocksched.c;h=3a0ed11364e4bb34c71441a8d4731ca929b07666;hb=d16d39df6772995a29ecdc8de1904ccb2e523599;hp=c11ef72628d3a23199815278ff6f1b3c1128c9f8;hpb=e0822116e037578eb77dff69bec13ae3bcdc7b91;p=libfirm diff --git a/ir/be/beblocksched.c b/ir/be/beblocksched.c index c11ef7262..3a0ed1136 100644 --- a/ir/be/beblocksched.c +++ b/ir/be/beblocksched.c @@ -7,7 +7,7 @@ */ #ifdef HAVE_CONFIG_H #include "config.h" -#endif /* HAVE_CONFIG_H */ +#endif #include "beblocksched.h" @@ -25,18 +25,20 @@ #include "irtools.h" #include "debug.h" #include "beirgmod.h" +#include "bemodule.h" +#include "be.h" -#ifdef WITH_LIBCORE #include #include #include -#endif /* WITH_LIBCORE */ #ifdef WITH_ILP #include #include #endif /* WITH_ILP */ +DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;) + typedef enum _blocksched_algos_t { BLOCKSCHED_NAIV, BLOCKSCHED_EXTBB, BLOCKSCHED_GREEDY, BLOCKSCHED_ILP } blocksched_algos_t; @@ -92,7 +94,6 @@ typedef struct _blocksched_env_t { edge_t *edges; pdeq *worklist; int blockcount; - DEBUG_ONLY(firm_dbg_module_t *dbg;) } blocksched_env_t; /** @@ -101,9 +102,7 @@ typedef struct _blocksched_env_t { */ static void collect_egde_frequency(ir_node *block, void *data) { - blocksched_env_t *env = data; - ir_graph *irg = env->irg; - ir_node *startblock = get_irg_start_block(irg); + blocksched_env_t *env = data; int arity; edge_t edge; blocksched_entry_t *entry; @@ -114,7 +113,7 @@ static void collect_egde_frequency(ir_node *block, void *data) entry->prev = NULL; set_irn_link(block, entry); - if (block == startblock) + if (block == get_irg_start_block(env->irg)) return; arity = get_irn_arity(block); @@ -127,8 +126,8 @@ static void collect_egde_frequency(ir_node *block, void *data) ARR_APP1(edge_t, env->edges, edge); } else { int i; - double highest_execfreq = -1; - int highest_edge_num; + double highest_execfreq = -1.0; + int highest_edge_num = -1; edge.block = block; for (i = 0; i < arity; ++i) { @@ -148,7 +147,8 @@ static void collect_egde_frequency(ir_node *block, void *data) } } - env->edges[highest_edge_num].highest_execfreq = 1; + if(highest_edge_num >= 0) + env->edges[highest_edge_num].highest_execfreq = 1; } } @@ -192,7 +192,7 @@ static void coalesce_blocks(blocksched_env_t *env) continue; /* schedule the 2 blocks behind each other */ - DBG((env->dbg, LEVEL_1, "Coalesce (Jump) %+F -> %+F (%.3g)\n", + DBG((dbg, LEVEL_1, "Coalesce (Jump) %+F -> %+F (%.3g)\n", pred_entry->block, entry->block, edge->execfreq)); pred_entry->next = entry; entry->prev = pred_entry; @@ -213,12 +213,12 @@ static void coalesce_blocks(blocksched_env_t *env) entry = get_irn_link(block); pred_entry = get_irn_link(pred_block); - /* TODO: what's this check for? */ + /* is 1 of the blocks already attached to another block? */ if (pred_entry->next != NULL || entry->prev != NULL) continue; /* schedule the 2 blocks behind each other */ - DBG((env->dbg, LEVEL_1, "Coalesce (CondJump) %+F -> %+F (%.3g)\n", + DBG((dbg, LEVEL_1, "Coalesce (CondJump) %+F -> %+F (%.3g)\n", pred_entry->block, entry->block, edge->execfreq)); pred_entry->next = entry; entry->prev = pred_entry; @@ -239,7 +239,7 @@ static void pick_block_successor(blocksched_entry_t *entry, blocksched_env_t *en env->blockcount++; mark_irn_visited(block); - DBG((env->dbg, LEVEL_1, "Pick succ of %+F\n", block)); + DBG((dbg, LEVEL_1, "Pick succ of %+F\n", block)); /* put all successors into the worklist */ foreach_block_succ(block, edge) { @@ -264,7 +264,7 @@ static void pick_block_successor(blocksched_entry_t *entry, blocksched_env_t *en if (irn_visited(succ_entry->block)) continue; - DBG((env->dbg, LEVEL_1, "Put %+F into worklist\n", succ_entry->block)); + DBG((dbg, LEVEL_1, "Put %+F into worklist\n", succ_entry->block)); pdeq_putr(env->worklist, succ_entry->block); } @@ -273,7 +273,7 @@ static void pick_block_successor(blocksched_entry_t *entry, blocksched_env_t *en return; } - DBG((env->dbg, LEVEL_1, "deciding...\n")); + DBG((dbg, LEVEL_1, "deciding...\n")); best_succ_execfreq = -1; /* no successor yet: pick the successor block with the highest execution @@ -298,11 +298,11 @@ static void pick_block_successor(blocksched_entry_t *entry, blocksched_env_t *en } if (succ == NULL) { - DBG((env->dbg, LEVEL_1, "pick from worklist\n")); + DBG((dbg, LEVEL_1, "pick from worklist\n")); do { if (pdeq_empty(env->worklist)) { - DBG((env->dbg, LEVEL_1, "worklist empty\n")); + DBG((dbg, LEVEL_1, "worklist empty\n")); return; } succ = pdeq_getl(env->worklist); @@ -322,6 +322,7 @@ static blocksched_entry_t *finish_block_schedule(blocksched_env_t *env) ir_node *startblock = get_irg_start_block(irg); blocksched_entry_t *entry = get_irn_link(startblock); + set_using_visited(irg); inc_irg_visited(irg); env->worklist = new_pdeq(); @@ -329,6 +330,8 @@ static blocksched_entry_t *finish_block_schedule(blocksched_env_t *env) assert(pdeq_empty(env->worklist)); del_pdeq(env->worklist); + clear_using_visited(irg); + return entry; } @@ -340,12 +343,12 @@ static ir_node **create_blocksched_array(blocksched_env_t *env, blocksched_entry blocksched_entry_t *entry; block_list = NEW_ARR_D(ir_node *, obst, count); - DBG((env->dbg, LEVEL_1, "Blockschedule:\n")); + DBG((dbg, LEVEL_1, "Blockschedule:\n")); for (entry = first; entry != NULL; entry = entry->next) { assert(i < count); block_list[i++] = entry->block; - DBG((env->dbg, LEVEL_1, "\t%+F\n", entry->block)); + DBG((dbg, LEVEL_1, "\t%+F\n", entry->block)); } assert(i == count); @@ -367,7 +370,6 @@ static ir_node **create_block_schedule_greedy(ir_graph *irg, ir_exec_freq *execf env.edges = NEW_ARR_F(edge_t, 0); env.worklist = NULL; env.blockcount = 0; - FIRM_DBG_REGISTER(env.dbg, "firm.be.blocksched"); // collect edge execution frequencies irg_block_walk_graph(irg, collect_egde_frequency, NULL, &env); @@ -375,7 +377,7 @@ static ir_node **create_block_schedule_greedy(ir_graph *irg, ir_exec_freq *execf // sort interblock edges by execution frequency qsort(env.edges, ARR_LEN(env.edges), sizeof(env.edges[0]), cmp_edges); - be_remove_empty_blocks(irg); + (void)be_remove_empty_blocks(irg); if (algo != BLOCKSCHED_NAIV) coalesce_blocks(&env); @@ -490,8 +492,6 @@ static void coalesce_blocks_ilp(blocksched_ilp_env_t *env) { int i; int edge_count = ARR_LEN(env->ilpedges); - FILE *f; - char fname[256]; /* complete out constraints */ for(i = 0; i < edge_count; ++i) { @@ -507,16 +507,23 @@ static void coalesce_blocks_ilp(blocksched_ilp_env_t *env) pred = get_Block_cfgpred_block(block, edge->pos); entry = get_irn_link(pred); - DBG((env->env.dbg, LEVEL_1, "Adding out cst to %+F from %+F,%d\n", + DBG((dbg, LEVEL_1, "Adding out cst to %+F from %+F,%d\n", pred, block, edge->pos)); lpp_set_factor_fast(env->lpp, entry->out_cst, edge->ilpvar, 1.0); } - lpp_dump(env->lpp, "lpp.out"); - snprintf(fname, sizeof(fname), "lpp_%s.plain", get_irg_dump_name(env->env.irg)); - f = fopen(fname, "w"); - lpp_dump_plain(env->lpp, f); - fclose(f); +#if 0 + { + FILE *f; + char fname[256]; + lpp_dump(env->lpp, "lpp.out"); + snprintf(fname, sizeof(fname), "lpp_%s.plain", get_irg_dump_name(env->env.irg)); + f = fopen(fname, "w"); + lpp_dump_plain(env->lpp, f); + fclose(f); + } +#endif + //lpp_solve_net(env->lpp, main_env->options->ilp_server, main_env->options->ilp_solver); lpp_solve_net(env->lpp, "i44pc52", "cplex"); assert(lpp_is_sol_valid(env->lpp)); @@ -563,7 +570,6 @@ static ir_node **create_block_schedule_ilp(ir_graph *irg, ir_exec_freq *execfreq env.env.worklist = NULL; env.env.blockcount = 0; env.ilpedges = NEW_ARR_F(ilp_edge_t, 0); - FIRM_DBG_REGISTER(env.env.dbg, "firm.be.blocksched"); env.lpp = new_lpp("blockschedule", lpp_minimize); lpp_set_time_limit(env.lpp, 20); @@ -571,7 +577,7 @@ static ir_node **create_block_schedule_ilp(ir_graph *irg, ir_exec_freq *execfreq irg_block_walk_graph(irg, collect_egde_frequency_ilp, NULL, &env); - be_remove_empty_blocks(irg); + (void)be_remove_empty_blocks(irg); coalesce_blocks_ilp(&env); start_entry = finish_block_schedule(&env.env); @@ -605,8 +611,7 @@ static void add_block(anchor *list, ir_node *block) { if (list->start == NULL) { list->start = block; list->end = block; - } - else { + } else { set_irn_link(list->end, block); list->end = block; } @@ -666,7 +671,11 @@ static ir_node **create_extbb_block_schedule(ir_graph *irg, ir_exec_freq *execfr list.start = NULL; list.end = NULL; list.n_blks = 0; + + set_using_irn_link(irg); + set_using_visited(irg); inc_irg_block_visited(irg); + create_block_list(get_irg_start_block(irg), &list); /** create an array, so we can go forward and backward */ @@ -677,6 +686,9 @@ static ir_node **create_extbb_block_schedule(ir_graph *irg, ir_exec_freq *execfr blk_list[i] = b; } + clear_using_irn_link(irg); + clear_using_visited(irg); + return blk_list; } @@ -688,22 +700,17 @@ static ir_node **create_extbb_block_schedule(ir_graph *irg, ir_exec_freq *execfr * |_| |_|\__,_|_|_| |_| * */ - -#ifdef WITH_LIBCORE -void be_block_schedule_register_options(lc_opt_entry_t *grp) +void be_init_blocksched(void) { - static int run_once = 0; - lc_opt_entry_t *blocksched_grp; - - if (run_once) - return; - - run_once = 1; - blocksched_grp = lc_opt_get_grp(grp, "blocksched"); + lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be"); + lc_opt_entry_t *blocksched_grp = lc_opt_get_grp(be_grp, "blocksched"); lc_opt_add_table(blocksched_grp, be_blocksched_options); + + FIRM_DBG_REGISTER(dbg, "firm.be.blocksched"); } -#endif /* WITH_LIBCORE */ + +BE_REGISTER_MODULE_CONSTRUCTOR(be_init_blocksched); ir_node **be_create_block_schedule(ir_graph *irg, ir_exec_freq *execfreqs) {