X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_optimize.c;h=068e9db629662495d4c0447ea81af6a87b600944;hb=4d5c3365a58cba59993045a9e08e686d8ae079a7;hp=46364438a52fd9c2822202931d83c83b74353724;hpb=ce4f90446b35c578e642a6e6a5d73b8bb6719942;p=libfirm diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index 46364438a..068e9db62 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -1,3 +1,22 @@ +/* + * 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. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + /** * Project: libFIRM * File name: ir/be/ia32/ia32_optimize.c @@ -7,7 +26,6 @@ * Copyright: (c) 2006 Universitaet Karlsruhe * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -35,6 +53,8 @@ #include "ia32_dbg_stat.h" #include "ia32_util.h" +DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;) + #define AGGRESSIVE_AM typedef enum { @@ -159,14 +179,14 @@ static void ia32_optimize_TestJmp(ir_node *irn, ia32_code_gen_t *cg) { replace = cand ? is_TestJmp_replacement(cand, irn) : 0; if (replace) { - DBG((cg->mod, LEVEL_1, "replacing %+F by ", irn)); + DBG((dbg, LEVEL_1, "replacing %+F by ", irn)); if (is_ia32_And(cand)) set_irn_op(irn, op_ia32_CJmpAM); else set_irn_op(irn, op_ia32_CJmp); - DB((cg->mod, LEVEL_1, "%+F\n", irn)); + DB((dbg, LEVEL_1, "%+F\n", irn)); } } @@ -201,12 +221,12 @@ static void ia32_optimize_CondJmp(ir_node *irn, ia32_code_gen_t *cg) { replace = cand ? is_CondJmp_replacement(cand, irn) : 0; if (replace) { - DBG((cg->mod, LEVEL_1, "replacing %+F by ", irn)); + DBG((dbg, LEVEL_1, "replacing %+F by ", irn)); DBG_OPT_CJMP(irn); set_irn_op(irn, op_ia32_CJmpAM); - DB((cg->mod, LEVEL_1, "%+F\n", irn)); + DB((dbg, LEVEL_1, "%+F\n", irn)); } } @@ -773,7 +793,7 @@ static INLINE void try_remove_from_sched(ir_node *node) { */ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn) { ir_graph *irg = get_irn_irg(irn); - dbg_info *dbg = get_irn_dbg_info(irn); + dbg_info *dbg_info = get_irn_dbg_info(irn); ir_node *block = get_nodes_block(irn); ir_node *res = irn; ir_node *shift = NULL; @@ -787,14 +807,13 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn) { int dolea = 0; int have_am_sc = 0; int am_sc_sign = 0; - ident *am_sc = NULL; + ir_entity *am_sc = NULL; ir_entity *lea_ent = NULL; ir_node *noreg = ia32_new_NoReg_gp(cg); ir_node *left, *right, *temp; ir_node *base, *index; int consumed_left_shift; ia32_am_flavour_t am_flav; - DEBUG_ONLY(firm_dbg_module_t *mod = cg->mod;) if (is_ia32_Add(irn)) isadd = 1; @@ -842,13 +861,13 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn) { if (is_ia32_ImmConst(irn)) { tarval *tv = get_ia32_Immop_tarval(irn); - DBG((mod, LEVEL_1, "\tfound op with imm const")); + DBG((dbg, LEVEL_1, "\tfound op with imm const")); offs_cnst = get_tarval_long(tv); dolea = 1; } else if (isadd && is_ia32_ImmSymConst(irn)) { - DBG((mod, LEVEL_1, "\tfound op with imm symconst")); + DBG((dbg, LEVEL_1, "\tfound op with imm symconst")); have_am_sc = 1; dolea = 1; @@ -863,7 +882,7 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn) { /* but we can only eat it up if there is no other symconst */ /* because the linker won't accept two symconsts */ if (! have_am_sc && is_ia32_Lea(temp) && get_ia32_am_flavour(temp) == ia32_am_O) { - DBG((mod, LEVEL_1, "\tgot op with LEA am_O")); + DBG((dbg, LEVEL_1, "\tgot op with LEA am_O")); offs_lea = get_ia32_am_offs_int(temp); am_sc = get_ia32_am_sc(temp); @@ -884,7 +903,7 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn) { dolea = 1; consumed_left_shift = -1; - DBG((mod, LEVEL_1, "\tgot LEA candidate with index %+F\n", index)); + DBG((dbg, LEVEL_1, "\tgot LEA candidate with index %+F\n", index)); /* determine the operand which needs to be checked */ temp = left; @@ -905,7 +924,7 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn) { shift = temp; scale = shiftval; - DBG((mod, LEVEL_1, "\tgot scaled index %+F\n", index)); + DBG((dbg, LEVEL_1, "\tgot scaled index %+F\n", index)); } } } @@ -929,10 +948,10 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn) { int take_attr = do_new_lea(irn, base, index, left, have_am_sc, cg); if (take_attr == IA32_LEA_ATTR_NONE) { - DBG((mod, LEVEL_1, "\tleave old LEA, creating new one\n")); + DBG((dbg, LEVEL_1, "\tleave old LEA, creating new one\n")); } else { - DBG((mod, LEVEL_1, "\tgot LEA as left operand ... assimilating\n")); + DBG((dbg, LEVEL_1, "\tgot LEA as left operand ... assimilating\n")); lea = left; /* for statistics */ if (take_attr & IA32_LEA_ATTR_OFFS) @@ -960,7 +979,7 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn) { /* ok, we can create a new LEA */ if (dolea) { - res = new_rd_ia32_Lea(dbg, irg, block, base, index); + res = new_rd_ia32_Lea(dbg_info, irg, block, base, index); /* add the old offset of a previous LEA */ add_ia32_am_offs_int(res, offs); @@ -1020,7 +1039,16 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn) { SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(cg, irn)); - DBG((mod, LEVEL_1, "\tLEA [%+F + %+F * %d + %d]\n", base, index, scale, get_ia32_am_offs_int(res))); + DBG((dbg, LEVEL_1, "\tLEA [%+F + %+F * %d + %d]\n", base, index, scale, get_ia32_am_offs_int(res))); + + assert(irn && "Couldn't find result proj"); + + /* get the result Proj of the Add/Sub */ + try_add_to_sched(irn, res); + + /* exchange the old op with the new LEA */ + try_remove_from_sched(irn); + exchange(irn, res); /* we will exchange it, report here before the Proj is created */ if (shift && lea && lea_o) { @@ -1028,45 +1056,30 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn) { try_remove_from_sched(lea); try_remove_from_sched(lea_o); DBG_OPT_LEA4(irn, lea_o, lea, shift, res); - } - else if (shift && lea) { + } else if (shift && lea) { try_remove_from_sched(shift); try_remove_from_sched(lea); DBG_OPT_LEA3(irn, lea, shift, res); - } - else if (shift && lea_o) { + } else if (shift && lea_o) { try_remove_from_sched(shift); try_remove_from_sched(lea_o); DBG_OPT_LEA3(irn, lea_o, shift, res); - } - else if (lea && lea_o) { + } else if (lea && lea_o) { try_remove_from_sched(lea); try_remove_from_sched(lea_o); DBG_OPT_LEA3(irn, lea_o, lea, res); - } - else if (shift) { + } else if (shift) { try_remove_from_sched(shift); DBG_OPT_LEA2(irn, shift, res); - } - else if (lea) { + } else if (lea) { try_remove_from_sched(lea); DBG_OPT_LEA2(irn, lea, res); - } - else if (lea_o) { + } else if (lea_o) { try_remove_from_sched(lea_o); DBG_OPT_LEA2(irn, lea_o, res); - } - else + } else { DBG_OPT_LEA1(irn, res); - - /* get the result Proj of the Add/Sub */ - try_add_to_sched(irn, res); - try_remove_from_sched(irn); - - assert(irn && "Couldn't find result proj"); - - /* exchange the old op with the new LEA */ - exchange(irn, res); + } } return res; @@ -1159,13 +1172,13 @@ static void optimize_lea(ir_node *irn, void *env) { if(!is_addr_candidate(irn)) return; - DBG((cg->mod, LEVEL_1, "\tfound address calculation candidate %+F ... ", irn)); + DBG((dbg, LEVEL_1, "\tfound address calculation candidate %+F ... ", irn)); res = fold_addr(cg, irn); if (res != irn) - DB((cg->mod, LEVEL_1, "transformed into %+F\n", res)); + DB((dbg, LEVEL_1, "transformed into %+F\n", res)); else - DB((cg->mod, LEVEL_1, "not transformed\n")); + DB((dbg, LEVEL_1, "not transformed\n")); } else if (is_ia32_Ld(irn) || is_ia32_St(irn) || is_ia32_Store8Bit(irn)) { /* - Load -> LEA into Load } TODO: If the LEA is used by more than one Load/Store */ /* - Store -> LEA into Store } it might be better to keep the LEA */ @@ -1180,7 +1193,7 @@ static void optimize_lea(ir_node *irn, void *env) { src = get_edge_src_irn(edge); if (src && (get_edge_src_pos(edge) == 0) && (is_ia32_Ld(src) || is_ia32_St(src) || is_ia32_Store8Bit(src))) { - DBG((cg->mod, LEVEL_1, "\nmerging %+F into %+F\n", left, irn)); + DBG((dbg, LEVEL_1, "\nmerging %+F into %+F\n", left, irn)); if (! is_ia32_got_lea(src)) merge_loadstore_lea(src, left); set_ia32_got_lea(src); @@ -1209,7 +1222,6 @@ static void optimize_am(ir_node *irn, void *env) { ia32_am_cand_t orig_cand; int dest_possible; int source_possible; - DEBUG_ONLY(firm_dbg_module_t *mod = cg->mod;) if (!is_ia32_irn(irn) || is_ia32_Ld(irn) || is_ia32_St(irn) || is_ia32_Store8Bit(irn)) return; @@ -1219,7 +1231,7 @@ static void optimize_am(ir_node *irn, void *env) { am_support = get_ia32_am_support(irn); block = get_nodes_block(irn); - DBG((mod, LEVEL_1, "checking for AM\n")); + DBG((dbg, LEVEL_1, "checking for AM\n")); /* fold following patterns: */ /* - op -> Load into AMop with am_Source */ @@ -1242,7 +1254,7 @@ static void optimize_am(ir_node *irn, void *env) { return; orig_cand = cand; - DBG((mod, LEVEL_1, "\tfound address mode candidate %+F ... ", irn)); + DBG((dbg, LEVEL_1, "\tfound address mode candidate %+F ... ", irn)); left = get_irn_n(irn, 2); if (get_irn_arity(irn) == 4) { @@ -1336,17 +1348,12 @@ static void optimize_am(ir_node *irn, void *env) { set_ia32_am_flavour(irn, get_ia32_am_flavour(load)); set_ia32_op_type(irn, ia32_AddrModeD); set_ia32_frame_ent(irn, get_ia32_frame_ent(load)); - if(is_ia32_use_frame(load)) - set_ia32_use_frame(irn); set_ia32_ls_mode(irn, get_ia32_ls_mode(load)); set_ia32_am_sc(irn, get_ia32_am_sc(load)); if (is_ia32_am_sc_sign(load)) set_ia32_am_sc_sign(irn); - if (is_ia32_use_frame(load)) - set_ia32_use_frame(irn); - /* connect to Load memory and disconnect Load */ if (get_irn_arity(irn) == 5) { /* binary AMop */ @@ -1371,7 +1378,7 @@ static void optimize_am(ir_node *irn, void *env) { try_remove_from_sched(store); DBG_OPT_AM_D(load, store, irn); - DB((mod, LEVEL_1, "merged with %+F and %+F into dest AM\n", load, store)); + DB((dbg, LEVEL_1, "merged with %+F and %+F into dest AM\n", load, store)); need_exchange_on_fail = 0; source_possible = 0; } @@ -1420,8 +1427,12 @@ static void optimize_am(ir_node *irn, void *env) { /* clear remat flag */ set_ia32_flags(irn, get_ia32_flags(irn) & ~arch_irn_flags_rematerializable); - if (is_ia32_use_frame(load)) + if (is_ia32_use_frame(load)) { + if(get_ia32_frame_ent(load) == NULL) { + set_ia32_need_stackent(irn); + } set_ia32_use_frame(irn); + } /* connect to Load memory and disconnect Load */ if (get_irn_arity(irn) == 5) { @@ -1464,7 +1475,7 @@ static void optimize_am(ir_node *irn, void *env) { } need_exchange_on_fail = 0; - DB((mod, LEVEL_1, "merged with %+F into source AM\n", load)); + DB((dbg, LEVEL_1, "merged with %+F into source AM\n", load)); } /* was exchanged but optimize failed: exchange back */ @@ -1479,8 +1490,10 @@ static void optimize_am(ir_node *irn, void *env) { void ia32_optimize_addressmode(ia32_code_gen_t *cg) { /* if we are supposed to do AM or LEA optimization: recalculate edges */ if (cg->opt & (IA32_OPT_DOAM | IA32_OPT_LEA)) { +#if 0 edges_deactivate(cg->irg); edges_activate(cg->irg); +#endif } else { /* no optimizations at all */ @@ -1498,6 +1511,13 @@ void ia32_optimize_addressmode(ia32_code_gen_t *cg) { if (cg->dump) be_dump(cg->irg, "-lea", dump_ir_block_graph_sched); + /* hack for now, so these don't get created during optimize, because then + * they will be unknown to the heights module + */ + ia32_new_NoReg_gp(cg); + ia32_new_NoReg_fp(cg); + ia32_new_NoReg_vfp(cg); + if (cg->opt & IA32_OPT_DOAM) { /* we need height information for am optimization */ heights_t *h = heights_new(cg->irg); @@ -1511,3 +1531,8 @@ void ia32_optimize_addressmode(ia32_code_gen_t *cg) { heights_free(h); } } + +void ia32_init_optimize(void) +{ + FIRM_DBG_REGISTER(dbg, "firm.be.ia32.optimize"); +}