X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_optimize.c;h=bfaa352092d4e12b076fc1b6b45e371292a1f93e;hb=1a1fe2580a53eaaadf545f474ebb67708d4e3d57;hp=2ed166cffa746047748abe46b17361a1049af5f4;hpb=eb3692350976be4efea32417a503d91f1a761ba9;p=libfirm diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index 2ed166cff..bfaa35209 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -7,9 +7,8 @@ * Copyright: (c) 2006 Universitaet Karlsruhe * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. */ - #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif #include "irnode.h" @@ -80,8 +79,18 @@ void ia32_pre_transform_phase(ia32_code_gen_t *cg) { * NOTE: THESE PEEPHOLE OPTIMIZATIONS MUST BE CALLED AFTER SCHEDULING AND REGISTER ALLOCATION. */ -static int ia32_cnst_compare(ir_node *n1, ir_node *n2) { - return get_ia32_id_cnst(n1) == get_ia32_id_cnst(n2); +static int ia32_const_equal(const ir_node *n1, const ir_node *n2) { + if(get_ia32_immop_type(n1) != get_ia32_immop_type(n2)) + return 0; + + if(get_ia32_immop_type(n1) == ia32_ImmConst) { + return get_ia32_Immop_tarval(n1) == get_ia32_Immop_tarval(n2); + } else if(get_ia32_immop_type(n1) == ia32_ImmSymConst) { + return get_ia32_Immop_symconst(n1) == get_ia32_Immop_symconst(n2); + } + + assert(get_ia32_immop_type(n1) == ia32_ImmNone); + return 1; } /** @@ -132,10 +141,10 @@ static int is_TestJmp_replacement(ir_node *cand, ir_node *irn) { } } - if (same_args) - return ia32_cnst_compare(cand, irn); + if (!same_args) + return 0; - return 0; + return ia32_const_equal(cand, irn); } /** @@ -168,20 +177,16 @@ static int is_CondJmp_cand(const ir_node *irn) { * Checks if the arguments of cand are the same of irn. */ static int is_CondJmp_replacement(ir_node *cand, ir_node *irn) { - int i, n = get_irn_arity(cand); - int same_args = 1; + int i, arity; - for (i = 0; i < n; i++) { + arity = get_irn_arity(cand); + for (i = 0; i < arity; i++) { if (get_irn_n(cand, i) != get_irn_n(irn, i)) { - same_args = 0; - break; + return 0; } } - if (same_args) - return ia32_cnst_compare(cand, irn); - - return 0; + return ia32_const_equal(cand, irn); } /** @@ -235,10 +240,8 @@ static void ia32_create_Pushs(ir_node *irn, ia32_code_gen_t *cg) { * attached to the node */ for(node = sched_next(irn); !sched_is_end(node); node = sched_next(node)) { - const char *am_offs; ir_node *mem; - int offset = -1; - int n; + int offset; int storeslot; // it has to be a store @@ -257,18 +260,7 @@ static void ia32_create_Pushs(ir_node *irn, ia32_code_gen_t *cg) { if( (get_ia32_am_flavour(node) & ia32_am_IS) != 0) break; - am_offs = get_ia32_am_offs(node); - if(am_offs == NULL) { - offset = 0; - } else { - // the am_offs has to be of the form "+NUMBER" - if(sscanf(am_offs, "+%d%n", &offset, &n) != 1 || am_offs[n] != '\0') { - // we shouldn't have any cases in the compiler at the moment - // that produce something different from esp+XX - assert(0); - break; - } - } + offset = get_ia32_am_offs_int(node); storeslot = offset / 4; if(storeslot >= MAXPUSH_OPTIMIZE) @@ -296,7 +288,7 @@ static void ia32_create_Pushs(ir_node *irn, ia32_code_gen_t *cg) { for( ; i >= 0; --i) { const arch_register_t *spreg; ir_node *push; - ir_node *val, *mem; + ir_node *val, *mem, *mem_proj; ir_node *store = stores[i]; ir_node *noreg = ia32_new_NoReg_gp(cg); @@ -309,9 +301,10 @@ static void ia32_create_Pushs(ir_node *irn, ia32_code_gen_t *cg) { // create a push push = new_rd_ia32_Push(NULL, irg, block, noreg, noreg, val, curr_sp, mem); - if(get_ia32_immop_type(store) != ia32_ImmNone) { - copy_ia32_Immop_attr(push, store); - } + + set_ia32_am_support(push, ia32_am_Source); + copy_ia32_Immop_attr(push, store); + sched_add_before(irn, push); // create stackpointer proj @@ -319,14 +312,14 @@ static void ia32_create_Pushs(ir_node *irn, ia32_code_gen_t *cg) { arch_set_irn_register(cg->arch_env, curr_sp, spreg); sched_add_before(irn, curr_sp); - // rewire users - edges_reroute(store, push, irg); + // create memory proj + mem_proj = new_r_Proj(irg, block, push, mode_M, pn_ia32_Push_M); + sched_add_before(irn, mem_proj); + + // use the memproj now + exchange(store, mem_proj); // we can remove the store now - set_irn_n(store, 0, new_Bad()); - set_irn_n(store, 1, new_Bad()); - set_irn_n(store, 2, new_Bad()); - set_irn_n(store, 3, new_Bad()); sched_remove(store); offset -= 4; @@ -352,6 +345,7 @@ static void ia32_create_Pushs(ir_node *irn, ia32_code_gen_t *cg) { } } +#if 0 /** * Tries to optimize two following IncSP. */ @@ -373,6 +367,7 @@ static void ia32_optimize_IncSP(ir_node *irn, ia32_code_gen_t *cg) { sched_remove(prev); } } +#endif /** * Performs Peephole Optimizations. @@ -391,7 +386,7 @@ static void ia32_peephole_optimize_node(ir_node *irn, void *env) { if (be_is_IncSP(irn)) { // optimize_IncSP doesn't respect dependency edges yet... //ia32_optimize_IncSP(irn, cg); - (void) ia32_optimize_IncSP; + if (cg->opt & IA32_OPT_PUSHARGS) ia32_create_Pushs(irn, cg); } @@ -476,8 +471,9 @@ static int pred_is_specific_nodeblock(const ir_node *bl, const ir_node *pred, * @param irn The irn to check * return 1 if irn is a candidate, 0 otherwise */ -static int is_addr_candidate(const ir_node *block, const ir_node *irn) { +static int is_addr_candidate(const ir_node *irn) { #ifndef AGGRESSIVE_AM + const ir_node *block = get_nodes_block(irn); ir_node *left, *right; int n; @@ -607,30 +603,24 @@ static ia32_am_cand_t is_am_candidate(ia32_code_gen_t *cg, heights_t *h, const i static int load_store_addr_is_equal(const ir_node *load, const ir_node *store, const ir_node *addr_b, const ir_node *addr_i) { - int is_equal = (addr_b == get_irn_n(load, 0)) && (addr_i == get_irn_n(load, 1)); - ir_entity *lent = get_ia32_frame_ent(load); - ir_entity *sent = get_ia32_frame_ent(store); - ident *lid = get_ia32_am_sc(load); - ident *sid = get_ia32_am_sc(store); - char *loffs = get_ia32_am_offs(load); - char *soffs = get_ia32_am_offs(store); - - /* are both entities set and equal? */ - if (is_equal && (lent || sent)) - is_equal = lent && sent && (lent == sent); - - /* are address mode idents set and equal? */ - if (is_equal && (lid || sid)) - is_equal = lid && sid && (lid == sid); - - /* are offsets set and equal */ - if (is_equal && (loffs || soffs)) - is_equal = loffs && soffs && strcmp(loffs, soffs) == 0; - - /* are the load and the store of the same mode? */ - is_equal = is_equal ? get_ia32_ls_mode(load) == get_ia32_ls_mode(store) : 0; - - return is_equal; + if(get_irn_n(load, 0) != addr_b) + return 0; + if(get_irn_n(load, 1) != addr_i) + return 0; + + if(get_ia32_frame_ent(load) != get_ia32_frame_ent(store)) + return 0; + + if(get_ia32_am_sc(load) != get_ia32_am_sc(store)) + return 0; + if(is_ia32_am_sc_sign(load) != is_ia32_am_sc_sign(store)) + return 0; + if(get_ia32_am_offs_int(load) != get_ia32_am_offs_int(store)) + return 0; + if(get_ia32_ls_mode(load) != get_ia32_ls_mode(store)) + return 0; + + return 1; } typedef enum _ia32_take_lea_attr { @@ -861,7 +851,7 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn) { have_am_sc = 1; dolea = 1; - am_sc = get_ia32_id_cnst(irn); + am_sc = get_ia32_Immop_symconst(irn); am_sc_sign = is_ia32_am_sc_sign(irn); } @@ -905,7 +895,7 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn) { /* check for SHL 1,2,3 */ if (pred_is_specific_node(temp, is_ia32_Shl)) { - if (get_ia32_Immop_tarval(temp)) { + if (is_ia32_ImmConst(temp)) { long shiftval = get_tarval_long(get_ia32_Immop_tarval(temp)); if (shiftval <= 3) { @@ -1029,7 +1019,7 @@ 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 + %s]\n", base, index, scale, get_ia32_am_offs(res))); + DBG((mod, LEVEL_1, "\tLEA [%+F + %+F * %d + %d]\n", base, index, scale, get_ia32_am_offs_int(res))); /* we will exchange it, report here before the Proj is created */ if (shift && lea && lea_o) { @@ -1165,7 +1155,7 @@ static void optimize_lea(ir_node *irn, void *env) { if (is_ia32_Sub(irn) || is_ia32_Add(irn)) { ir_node *res; - if(!is_addr_candidate(cg, irn)) + if(!is_addr_candidate(irn)) return; DBG((cg->mod, LEVEL_1, "\tfound address calculation candidate %+F ... ", irn)); @@ -1345,17 +1335,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 */ @@ -1429,8 +1414,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) { @@ -1488,8 +1477,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 */