X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fberaextern.c;h=36305a6584d48545759a1f4b7904a87402569adb;hb=9276447aec4972df060349e162f583c4898dfec8;hp=f0dd304902976484bb71a05eef24c9148048acd6;hpb=a51b19f667731104d1277df71b26daa2d3816189;p=libfirm diff --git a/ir/be/beraextern.c b/ir/be/beraextern.c index f0dd30490..36305a658 100644 --- a/ir/be/beraextern.c +++ b/ir/be/beraextern.c @@ -1,10 +1,28 @@ -/** - * Author: Daniel Grund - * Date: 17.01.2006 - * Copyright: (c) Universitaet Karlsruhe - * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. +/* + * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * + * This file is part of libFirm. + * + * This file may be distributed and/or modified under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. + * + * Licensees holding valid libFirm Professional Edition licenses may use + * this file in accordance with the libFirm Commercial License. + * Agreement provided with the Software. * - * Implementation of the RA-Interface for an external, (non-SSA) register allocator. + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/** + * @file + * @brief Implementation of the RA-Interface for an external, (non-SSA) register allocator. + * @author Daniel Grund + * @date 17.01.2006 + * @version $Id$ * * The external register allocator is a program: * PROG -i INPUTFILE -o OUTPUTFILE @@ -51,32 +69,24 @@ allocs ::= 'allocs' alloc* . alloc ::= node-nr reg-nr . - -******** End of file format docu ********/ - +*/ +#ifdef NOT_PORTED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#ifdef HAVE_MALLOC_H - #include -#endif -#ifdef HAVE_ALLOCA_H - #include -#endif - #include #include #include -#ifdef WITH_LIBCORE #include #include -#endif #include "set.h" #include "pset.h" #include "pmap.h" #include "bitset.h" +#include "raw_bitset.h" +#include "xmalloc.h" #include "irprintf_t.h" #include "irnode_t.h" @@ -86,9 +96,9 @@ alloc ::= node-nr reg-nr . #include "irdom_t.h" #include "phiclass.h" -#include "beraextern.h" +#include "bemodule.h" #include "beabi.h" -#include "bearch.h" +#include "bearch_t.h" #include "benode_t.h" #include "beirgmod.h" #include "besched_t.h" @@ -106,8 +116,8 @@ alloc ::= node-nr reg-nr . typedef struct _be_raext_env_t { arch_env_t *aenv; const arch_register_class_t *cls; + be_irg_t *birg; ir_graph *irg; - dom_front_info_t *dom_info; FILE *f; /**< file handle used for out- and input file */ set *vars; /**< contains all be_var_info_t */ @@ -203,7 +213,7 @@ static void handle_constraints_insn(be_raext_env_t *env, be_insn_t *insn) be_operand_t *op = &insn->ops[i]; if(op->has_constraints) { - ir_node *cpy = be_new_Copy(op->req.cls, env->irg, bl, op->carrier); + ir_node *cpy = be_new_Copy(op->req->cls, env->irg, bl, op->carrier); sched_add_before(insn->next_insn, cpy); edges_reroute(op->carrier, cpy, env->irg); } @@ -213,10 +223,10 @@ static void handle_constraints_insn(be_raext_env_t *env, be_insn_t *insn) be_operand_t *op = &insn->ops[i]; if(op->has_constraints) { - ir_node *cpy = be_new_Copy(op->req.cls, env->irg, bl, op->carrier); + ir_node *cpy = be_new_Copy(op->req->cls, env->irg, bl, op->carrier); sched_add_before(insn->irn, cpy); set_irn_n(insn->irn, op->pos, cpy); - be_set_constr_limited(cpy, BE_OUT_POS(0), &op->req); + be_set_constr_limited(cpy, BE_OUT_POS(0), op->req); } } } @@ -293,16 +303,16 @@ static void extract_vars_of_cls(be_raext_env_t *raenv) { * If yes, dump it to FILE raenv->f */ static INLINE void dump_constraint(be_raext_env_t *raenv, ir_node *irn, int pos) { - bitset_t *bs = bitset_alloca(raenv->cls->n_regs); - arch_register_req_t req; - - arch_get_register_req(raenv->aenv, &req, irn, pos); - if (arch_register_req_is(&req, limited)) { - int reg_nr; - req.limited(req.limited_env, bs); - reg_nr = bitset_next_set(bs, 0); + const arch_register_req_t *req; + + req = arch_get_register_req(raenv->aenv, irn, pos); + if (arch_register_req_is(req, limited)) { + unsigned reg_nr; + + reg_nr = rbitset_next(req->limited, 0, 1); fprintf(raenv->f, "<%d>", reg_nr); - assert(-1 == bitset_next_set(bs, reg_nr+1) && "Constraints with more than 1 possible register are not supported"); + assert(rbitset_popcnt(req->limited, raenv->cls->n_regs) <= 1 + && "Constraints with more than 1 possible register are not supported"); } } @@ -360,6 +370,7 @@ static void dump_interferences(be_raext_env_t *raenv) { be_var_info_t *vi1, *vi2; ir_node *irn1, *irn2; FILE *f = raenv->f; + be_lv_t *lv = raenv->birg->lv; fprintf(f, "\ninterferences {\n"); @@ -377,7 +388,7 @@ static void dump_interferences(be_raext_env_t *raenv) { pset_foreach(vi1->values, irn1) pset_foreach(vi2->values, irn2) - if (values_interfere(irn1, irn2)) { + if (values_interfere(lv, irn1, irn2)) { pset_break(vi1->values); pset_break(vi2->values); fprintf(f, "(%d, %d)\n", vi1->var_nr, vi2->var_nr); @@ -392,7 +403,7 @@ NextVar: ; static void dump_affinities_walker(ir_node *irn, void *env) { be_raext_env_t *raenv = env; - arch_register_req_t req; + const arch_register_req_t *req; int pos, max; be_var_info_t *vi1, *vi2; @@ -402,7 +413,7 @@ static void dump_affinities_walker(ir_node *irn, void *env) { vi1 = be_get_var_info(irn); /* copies have affinities */ - if (arch_irn_classify(raenv->aenv, irn) == arch_irn_class_copy) { + if (arch_irn_class_is(raenv->aenv, irn, copy)) { ir_node *other = be_get_Copy_op(irn); if (! arch_irn_is(raenv->aenv, other, ignore)) { @@ -415,12 +426,15 @@ static void dump_affinities_walker(ir_node *irn, void *env) { /* should_be_equal constraints are affinites */ for (pos = 0, max = get_irn_arity(irn); posaenv, &req, irn, pos); + req = arch_get_register_req(raenv->aenv, irn, pos); - if (arch_register_req_is(&req, should_be_same) && arch_irn_is(raenv->aenv, req.other_same, ignore)) { - vi2 = be_get_var_info(req.other_same); + if (arch_register_req_is(req, should_be_same)) { + ir_node *other = get_irn_n(skip_Proj(irn), req->other_same); + if(arch_irn_is(raenv->aenv, other, ignore)) { + vi2 = be_get_var_info(other); - fprintf(raenv->f, "(%d, %d, %d)\n", vi1->var_nr, vi2->var_nr, get_affinity_weight(irn)); + fprintf(raenv->f, "(%d, %d, %d)\n", vi1->var_nr, vi2->var_nr, get_affinity_weight(irn)); + } } } } @@ -503,6 +517,8 @@ static INLINE void var_add_spills_and_reloads(be_raext_env_t *raenv, int var_nr) const ir_edge_t *edge, *ne; pset *spills = pset_new_ptr(4); /* the spills of this variable */ pset *reloads = pset_new_ptr(4); /* the reloads of this variable */ + be_lv_t *lv = raenv->birg->lv; + be_dom_front_info_t *dom_front = raenv->birg->dom_front; int new_size, n_spills, n_reloads; assert(vi && "Variable nr does not exist!"); @@ -527,7 +543,7 @@ static INLINE void var_add_spills_and_reloads(be_raext_env_t *raenv, int var_nr) /* all ordinary nodes must be spilled */ DBG((raenv->dbg, LEVEL_2, " spilling %+F\n", irn)); - spill = be_spill(raenv->aenv, irn, ctx); + spill = be_spill(raenv->aenv, irn); /* remember the spill */ pset_insert_ptr(spills, spill); @@ -538,7 +554,7 @@ static INLINE void var_add_spills_and_reloads(be_raext_env_t *raenv, int var_nr) mode = get_irn_mode(get_irn_n(spill, be_pos_Spill_val)); /* insert reloads and wire them arbitrary*/ - pset_foreach(vi->values, irn) + pset_foreach(vi->values, irn) { foreach_out_edge_safe(irn, edge, ne) { ir_node *reload, *src = edge->src; if (is_Phi(src) || be_is_Spill(src)) @@ -552,9 +568,10 @@ static INLINE void var_add_spills_and_reloads(be_raext_env_t *raenv, int var_nr) /* remember the reload */ pset_insert_ptr(reloads, reload); } + } /* correct the reload->spill pointers... */ - be_ssa_constr_set(raenv->dom_info, spills); + be_ssa_constr_set_ignore(dom_front, lv, spills, NULL); /****** correct the variable <--> values mapping: ****** @@ -650,6 +667,7 @@ static int read_and_apply_results(be_raext_env_t *raenv, char *filename) { static void check_allocation(be_raext_env_t *raenv) { int i, o; + be_lv_t *lv = raenv->birg->lv; for (i=0; in_cls_vars; ++i) { be_var_info_t *vi1 = raenv->cls_vars[i]; @@ -666,9 +684,9 @@ static void check_allocation(be_raext_env_t *raenv) { pset_foreach(vi1->values, irn1) pset_foreach(vi2->values, irn2) - if (values_interfere(irn1, irn2) && arch_get_irn_register(raenv->aenv, irn1) == arch_get_irn_register(raenv->aenv, irn2)) { + if (values_interfere(lv, irn1, irn2) && arch_get_irn_register(raenv->aenv, irn1) == arch_get_irn_register(raenv->aenv, irn2)) { dump_ir_block_graph_sched(raenv->irg, "ERROR"); - ir_fprintf(stdout, "SSA values %+F and %+F interfere. They belong to varible %d and %d respectively.\n", irn1, irn2, vi1->var_nr, vi2->var_nr); + ir_fprintf(stdout, "SSA values %+F and %+F interfere. They belong to variable %d and %d respectively.\n", irn1, irn2, vi1->var_nr, vi2->var_nr); assert(0 && "ERROR graph dumped"); } } @@ -687,7 +705,6 @@ static void check_allocation(be_raext_env_t *raenv) { /** * Default values for options */ -static set* (*ssa_destr)(ir_graph*,const arch_env_t*) = be_ssa_destr_simple; static char callee[128] = "\"E:/user/kimohoff/public/register allocator\""; //static char callee[128] = "/ben/kimohoff/ipd-registerallocator/register_allocator"; @@ -701,19 +718,20 @@ static char callee[128] = "\"E:/user/kimohoff/public/register allocator\""; * Read in results and apply them * */ -static void be_ra_extern_main(const be_irg_t *bi) { - be_main_env_t *env = bi->main_env; - ir_graph *irg = bi->irg; +static void be_ra_extern_main(be_irg_t *birg) { + be_main_env_t *env = birg->main_env; + ir_graph *irg = birg->irg; be_raext_env_t raenv; int clsnr, clss; - compute_doms(irg); + be_assure_dom_front(birg); + be_assure_liveness(birg); edges_assure(irg); raenv.irg = irg; + raenv.birg = birg; raenv.aenv = env->arch_env; - raenv.dom_info = be_compute_dominance_frontiers(irg); FIRM_DBG_REGISTER(raenv.dbg, "firm.be.raextern"); /* Insert copies for constraints */ @@ -747,7 +765,7 @@ static void be_ra_extern_main(const be_irg_t *bi) { dump_to_file(&raenv, out); execute(callee, out, in); done = read_and_apply_results(&raenv, in); - be_abi_fix_stack_nodes(bi->abi); + be_abi_fix_stack_nodes(birg->abi); ir_snprintf(in, sizeof(in), "-extern-%s-round-%d", raenv.cls->name, round); be_dump(irg, in, dump_ir_block_graph_sched); @@ -764,7 +782,8 @@ static void be_ra_extern_main(const be_irg_t *bi) { /* Clean up */ free_ssa_destr_simple(raenv.vars); - be_free_dominance_frontiers(raenv.dom_info); + + be_invalidate_liveness(birg); } /****************************************************************************** @@ -778,16 +797,15 @@ static void be_ra_extern_main(const be_irg_t *bi) { |_| *****************************************************************************/ -#ifdef WITH_LIBCORE - - static const lc_opt_enum_func_ptr_items_t ssa_destr_items[] = { - { "simple", (int (*)()) be_ssa_destr_simple }, /* TODO make (void*) casts nicer */ + { "simple", (int (*)(void)) be_ssa_destr_simple }, /* TODO make (void*) casts nicer */ { NULL, NULL } }; +static set* (*ssa_destr)(ir_graph*,const arch_env_t*) = be_ssa_destr_simple; + static lc_opt_enum_func_ptr_var_t ssa_destr_var = { - (int (**)()) &ssa_destr, ssa_destr_items + (int (**)(void)) &ssa_destr, ssa_destr_items }; static const lc_opt_table_entry_t be_ra_extern_options[] = { @@ -796,17 +814,19 @@ static const lc_opt_table_entry_t be_ra_extern_options[] = { { NULL } }; -static void be_ra_extern_register_options(lc_opt_entry_t *root) { - lc_opt_entry_t *grp = lc_opt_get_grp(root, "ext"); +static be_ra_t be_ra_external_allocator = { + be_ra_extern_main +}; - lc_opt_add_table(grp, be_ra_extern_options); -} +void be_init_raextern(void) { + 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, "ra"); + lc_opt_entry_t *ext_grp = lc_opt_get_grp(blocksched_grp, "ext"); -#endif /* WITH_LIBCORE */ + lc_opt_add_table(ext_grp, be_ra_extern_options); -const be_ra_t be_ra_external_allocator = { -#ifdef WITH_LIBCORE - be_ra_extern_register_options, -#endif - be_ra_extern_main -}; + be_register_allocator("ext", &be_ra_external_allocator); +} +BE_REGISTER_MODULE_CONSTRUCTOR(be_init_raextern); + +#endif /* NOT_PORTED */