X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbecopyopt.c;h=d1799bc3d17ecf47fa5248d9e242a6d17895b534;hb=9d771b942da18ee0b220ade731b35852cdff759e;hp=a610d409871a13c5704d65e2984975c6d6df0376;hpb=c73aa5d0ca9dca431f45a4698cd30b5b4b9b8b40;p=libfirm diff --git a/ir/be/becopyopt.c b/ir/be/becopyopt.c index a610d4098..d1799bc3d 100644 --- a/ir/be/becopyopt.c +++ b/ir/be/becopyopt.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -65,9 +65,8 @@ #include "beirg_t.h" #include "error.h" -#include -#include -#include +#include "lc_opts.h" +#include "lc_opts_enum.h" #define DUMP_BEFORE 1 #define DUMP_AFTER 2 @@ -198,7 +197,7 @@ copy_opt_t *new_copy_opt(be_chordal_env_t *chordal_env, cost_fct_t get_costs) co = xcalloc(1, sizeof(*co)); co->cenv = chordal_env; - co->aenv = chordal_env->birg->main_env->arch_env; + co->aenv = &chordal_env->birg->main_env->arch_env; co->irg = chordal_env->irg; co->cls = chordal_env->cls; co->get_costs = get_costs; @@ -870,7 +869,7 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f) ir_node *irn; void *it, *nit; int n, n_regs; - unsigned i, j; + unsigned i; n_regs = 0; for(i = 0; i < co->cls->n_regs; ++i) { @@ -894,17 +893,6 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f) fprintf(f, "%d %d\n", n, n_regs); -#if 0 - printf("debut\n"); - for (i = 0; i < n_regs; ++i) { - for (j = 0; j < i; ++j) { - fprintf(f, "%d %d -1\n", i, j); - printf("%d %d\n", i, j); - } - } - printf("fin\n"); -#endif - be_ifg_foreach_node(ifg, it, irn) { if(!arch_irn_is(co->aenv, irn, ignore)) { int idx = node_map[get_irn_idx(irn)]; @@ -946,333 +934,6 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f) xfree(node_map); } -typedef struct _appel_clique_walker_t { - ir_phase ph; - const copy_opt_t *co; - int curr_nr; - int node_count; - FILE *f; - int dumb; - int *color_map; - struct obstack obst; -} appel_clique_walker_t; - -typedef struct _appel_block_info_t { - int *live_end_nr; - int *live_in_nr; - int *phi_nr; - ir_node **live_end; - ir_node **live_in; - ir_node **phi; - int n_live_end; - int n_live_in; - int n_phi; -} appel_block_info_t; - -static int appel_aff_weight(const appel_clique_walker_t *env, ir_node *bl) -{ -#if 0 - double freq = get_block_execfreq(env->co->cenv->execfreq, bl); - int res = (int) freq; - return res == 0 ? 1 : res; -#else - ir_loop *loop = get_irn_loop(bl); - (void) env; - if(loop) { - int d = get_loop_depth(loop); - return 1 + d * d; - } - return 1; -#endif -} - -static void *appel_clique_walker_irn_init(ir_phase *phase, ir_node *irn, void *old) -{ - appel_block_info_t *res = NULL; - (void) old; - - if(is_Block(irn)) { - appel_clique_walker_t *d = (void *) phase; - res = phase_alloc(phase, sizeof(res[0])); - res->phi_nr = phase_alloc(phase, d->co->cls->n_regs * sizeof(res->live_end_nr)); - res->live_end_nr = phase_alloc(phase, d->co->cls->n_regs * sizeof(res->live_end_nr)); - res->live_in_nr = phase_alloc(phase, d->co->cls->n_regs * sizeof(res->live_in_nr)); - res->live_end = phase_alloc(phase, d->co->cls->n_regs * sizeof(res->live_end)); - res->live_in = phase_alloc(phase, d->co->cls->n_regs * sizeof(res->live_in)); - res->phi = phase_alloc(phase, d->co->cls->n_regs * sizeof(res->live_in)); - } - - return res; -} - -typedef struct _insn_list_t { - be_insn_t *insn; - struct list_head list; -} insn_list_t; - -static int appel_get_live_end_nr(appel_clique_walker_t *env, ir_node *bl, ir_node *irn) -{ - appel_block_info_t *bli = phase_get_irn_data(&env->ph, bl); - int i; - - for(i = 0; i < bli->n_live_end; ++i) - if(bli->live_end[i] == irn) - return bli->live_end_nr[i]; - - return -1; -} - -static int appel_dump_clique(appel_clique_walker_t *env, const ir_nodeset_t *live, ir_node *bl, int curr_nr, int start_nr) -{ - ir_node **live_arr = alloca(env->co->cls->n_regs * sizeof(live_arr[0])); - ir_node *irn; - int n_live; - int j; - ir_nodeset_iterator_t iter; - - n_live = 0; - foreach_ir_nodeset(live, irn, iter) - live_arr[n_live++] = irn; - - /* dump the live after clique */ - if(!env->dumb) { - for(j = 0; j < n_live; ++j) { - int k; - - for(k = j + 1; k < n_live; ++k) { - fprintf(env->f, "%d %d -1 ", curr_nr + j, curr_nr + k); - } - fprintf(env->f, "\n"); - } - } - - /* dump the affinities */ - for(j = 0; !env->dumb && j < n_live; ++j) { - ir_node *irn = live_arr[j]; - int old_nr = PTR_TO_INT(get_irn_link(irn)); - - /* if the node was already live in the last insn dump the affinity */ - if(old_nr > start_nr) { - int weight = appel_aff_weight(env, bl); - fprintf(env->f, "%d %d %d\n", old_nr, curr_nr + j, weight); - } - } - - /* set the current numbers into the link field. */ - for(j = 0; j < n_live; ++j) { - ir_node *irn = live_arr[j]; - set_irn_link(irn, INT_TO_PTR(curr_nr + j)); - } - - return curr_nr + n_live; -} - -static void appel_walker(ir_node *bl, void *data) -{ - appel_clique_walker_t *env = data; - appel_block_info_t *bli = phase_get_or_set_irn_data(&env->ph, bl); - struct obstack *obst = &env->obst; - void *base = obstack_base(obst); - ir_nodeset_t live; - ir_nodeset_iterator_t iter; - be_lv_t *lv = env->co->cenv->birg->lv; - - int n_insns = 0; - int n_nodes = 0; - int start_nr = env->curr_nr; - int curr_nr = start_nr; - - be_insn_env_t insn_env; - int i, j; - ir_node *irn; - be_insn_t **insns; - - insn_env.aenv = env->co->aenv; - insn_env.cls = env->co->cls; - insn_env.obst = obst; - insn_env.ignore_colors = env->co->cenv->ignore_colors; - - /* Guess how many insns will be in this block. */ - sched_foreach(bl, irn) - n_nodes++; - - bli->n_phi = 0; - insns = xmalloc(n_nodes * sizeof(insns[0])); - - /* Put all insns in an array. */ - irn = sched_first(bl); - while(!sched_is_end(irn)) { - be_insn_t *insn; - insn = be_scan_insn(&insn_env, irn); - insns[n_insns++] = insn; - irn = insn->next_insn; - } - - DBG((dbg, LEVEL_2, "%+F\n", bl)); - ir_nodeset_init(&live); - be_liveness_end_of_block(lv, env->co->aenv, env->co->cls, bl, &live); - - /* Generate the bad and ugly. */ - for(i = n_insns - 1; i >= 0; --i) { - be_insn_t *insn = insns[i]; - - /* The first live set has to be saved in the block border set. */ - if(i == n_insns - 1) { - j = 0; - foreach_ir_nodeset(&live, irn, iter) { - bli->live_end[j] = irn; - bli->live_end_nr[j] = curr_nr + j; - ++j; - } - bli->n_live_end = j; - } - - if(!env->dumb) { - for(j = 0; j < insn->use_start; ++j) { - ir_node *op = insn->ops[j].carrier; - bitset_t *adm = insn->ops[j].regs; - unsigned k; - size_t nr; - - if(!insn->ops[j].has_constraints) - continue; - - nr = 0; - foreach_ir_nodeset(&live, irn, iter) { - if(irn == op) { - break; - } - ++nr; - } - - assert(nr < ir_nodeset_size(&live)); - - for(k = 0; k < env->co->cls->n_regs; ++k) { - int mapped_col = env->color_map[k]; - if(mapped_col >= 0 && !bitset_is_set(adm, k) && !bitset_is_set(env->co->cenv->ignore_colors, k)) - fprintf(env->f, "%d %d -1\n", curr_nr + nr, mapped_col); - } - } - } - - /* dump the clique and update the stuff. */ - curr_nr = appel_dump_clique(env, &live, bl, curr_nr, start_nr); - - /* remove all defs. */ - for(j = 0; j < insn->use_start; ++j) - ir_nodeset_remove(&live, insn->ops[j].carrier); - - if(is_Phi(insn->irn) && arch_irn_consider_in_reg_alloc(env->co->aenv, env->co->cls, insn->irn)) { - bli->phi[bli->n_phi] = insn->irn; - bli->phi_nr[bli->n_phi] = PTR_TO_INT(get_irn_link(insn->irn)); - bli->n_phi++; - } - - /* add all uses */ - else - for(j = insn->use_start; j < insn->n_ops; ++j) - ir_nodeset_insert(&live, insn->ops[j].carrier); - } - - /* print the start clique. */ - curr_nr = appel_dump_clique(env, &live, bl, curr_nr, start_nr); - - i = 0; - foreach_ir_nodeset(&live, irn, iter) { - bli->live_in[i] = irn; - bli->live_in_nr[i] = PTR_TO_INT(get_irn_link(irn)); - ++i; - } - bli->n_live_in = i; - - ir_nodeset_destroy(&live); - free(insns); - obstack_free(obst, base); - env->curr_nr = curr_nr; -} - -static void appel_inter_block_aff(ir_node *bl, void *data) -{ - appel_clique_walker_t *env = data; - appel_block_info_t *bli = phase_get_irn_data(&env->ph, bl); - - int i, j, n; - - for(i = 0; i < bli->n_live_in; ++i) { - ir_node *irn = bli->live_in[i]; - - for(j = 0, n = get_Block_n_cfgpreds(bl); j < n; ++j) { - ir_node *pred = get_Block_cfgpred_block(bl, j); - - int nr = appel_get_live_end_nr(env, pred, irn); - assert(nr >= 0); - fprintf(env->f, "%d %d 1\n", bli->live_in_nr[i], nr); - } - } - - for(i = 0; i < bli->n_phi; ++i) { - ir_node *irn = bli->phi[i]; - - for(j = 0, n = get_Block_n_cfgpreds(bl); j < n; ++j) { - ir_node *pred = get_Block_cfgpred_block(bl, j); - ir_node *op = get_irn_n(irn, j); - - int nr = appel_get_live_end_nr(env, pred, op); - assert(nr >= 0); - fprintf(env->f, "%d %d 1\n", bli->phi_nr[i], nr); - } - } - -} - -void co_dump_appel_graph_cliques(const copy_opt_t *co, FILE *f) -{ - unsigned i; - unsigned n_colors; - appel_clique_walker_t env; - bitset_t *adm = bitset_alloca(co->cls->n_regs); - be_lv_t *lv = co->cenv->birg->lv; - - be_liveness_recompute(lv); - obstack_init(&env.obst); - phase_init(&env.ph, "appel_clique_dumper", co->irg, PHASE_DEFAULT_GROWTH, appel_clique_walker_irn_init, NULL); - env.curr_nr = co->cls->n_regs; - env.co = co; - env.f = f; - - bitset_copy(adm, co->cenv->ignore_colors); - bitset_flip_all(adm); - - /* Make color map. */ - env.color_map = alloca(co->cls->n_regs * sizeof(env.color_map[0])); - for(i = 0, n_colors = 0; i < co->cls->n_regs; ++i) { - const arch_register_t *reg = &co->cls->regs[i]; - env.color_map[i] = arch_register_type_is(reg, ignore) ? -1 : (int) n_colors++; - } - - env.dumb = 1; - env.curr_nr = n_colors; - irg_block_walk_graph(co->irg, firm_clear_link, NULL, NULL); - irg_block_walk_graph(co->irg, appel_walker, NULL, &env); - - fprintf(f, "%d %d\n", env.curr_nr, n_colors); - - /* make the first k nodes interfere */ - for(i = 0; i < n_colors; ++i) { - unsigned j; - for(j = i + 1; j < n_colors; ++j) - fprintf(f, "%d %d -1 ", i, j); - fprintf(f, "\n"); - } - - env.dumb = 0; - env.curr_nr = n_colors; - irg_block_walk_graph(co->irg, firm_clear_link, NULL, NULL); - irg_block_walk_graph(co->irg, appel_walker, NULL, &env); - irg_block_walk_graph(co->irg, appel_inter_block_aff, NULL, &env); - obstack_free(&env.obst, NULL); -} - /* ___ _____ ____ ____ ___ _____ ____ _ |_ _| ___/ ___| | _ \ / _ \_ _| | _ \ _ _ _ __ ___ _ __ (_)_ __ __ _ @@ -1499,7 +1160,7 @@ static FILE *my_open(const be_chordal_env_t *env, const char *prefix, const char void co_driver(be_chordal_env_t *cenv) { - lc_timer_t *timer = lc_timer_register("firm.be.copyopt", "runtime"); + ir_timer_t *timer = ir_timer_register("firm.be.copyopt", "runtime"); co_complete_stats_t before, after; copy_opt_t *co; co_algo_t *algo_func; @@ -1556,11 +1217,11 @@ void co_driver(be_chordal_env_t *cenv) algo_func = algos[algo].algo; /* perform actual copy minimization */ - lc_timer_reset_and_start(timer); + ir_timer_reset_and_start(timer); was_optimal = algo_func(co); - lc_timer_stop(timer); + ir_timer_stop(timer); - be_stat_ev("co_time", lc_timer_elapsed_msec(timer)); + be_stat_ev("co_time", ir_timer_elapsed_msec(timer)); be_stat_ev_ull("co_optimal", was_optimal); if (dump_flags & DUMP_AFTER) {