X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_optimize.c;h=6a88bda3d31d25d2d42964d302d9865d042b8b8e;hb=fa4ec191e159484f0fcbea2ef044deaa2ab2d293;hp=6d7c40fe6cb3431f0156b4480f863682aecd2165;hpb=f65c73689e58bdbec2209cb7014b53d32aea244c;p=libfirm diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index 6d7c40fe6..6a88bda3d 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -18,6 +18,26 @@ #include "ia32_new_nodes.h" #include "bearch_ia32_t.h" #include "gen_ia32_regalloc_if.h" /* the generated interface (register type and class defenitions) */ +#include "ia32_transform.h" + +/*----*/ + +#include "irhooks.h" +#include "dbginfo_t.h" +#include "firmstat.h" + +/** + * Merge the debug info due to a LEA creation. + * + * @param oldn the node + * @param n the new constant holding the value + */ +#define DBG_OPT_LEA(oldn, n) \ + do { \ + hook_merge_nodes(&n, 1, &oldn, 1, FS_BE_IA32_LEA); \ + __dbg_info_merge_pair(n, oldn, dbg_backend); \ + } while(0) + #undef is_NoMem #define is_NoMem(irn) (get_irn_op(irn) == op_NoMem) @@ -119,7 +139,7 @@ static ir_type *get_prim_type(pmap *types, ir_mode *mode) static entity *get_entity_for_tv(ia32_code_gen_t *cg, ir_node *cnst) { tarval *tv = get_Const_tarval(cnst); - pmap_entry *e = pmap_find(cg->tv_ent, tv); + pmap_entry *e = pmap_find(cg->isa->tv_ent, tv); entity *res; ir_graph *rem; @@ -127,7 +147,7 @@ static entity *get_entity_for_tv(ia32_code_gen_t *cg, ir_node *cnst) ir_mode *mode = get_irn_mode(cnst); ir_type *tp = get_Const_type(cnst); if (tp == firm_unknown_type) - tp = get_prim_type(cg->types, mode); + tp = get_prim_type(cg->isa->types, mode); res = new_entity(get_glob_type(), unique_id("ia32FloatCnst_%u"), tp); @@ -142,6 +162,8 @@ static entity *get_entity_for_tv(ia32_code_gen_t *cg, ir_node *cnst) current_ir_graph = get_const_code_irg(); set_atomic_ent_value(res, new_Const_type(tv, tp)); current_ir_graph = rem; + + pmap_insert(cg->isa->tv_ent, tv, res); } else res = e->value; @@ -404,17 +426,6 @@ static void ia32_optimize_IncSP(ir_node *irn, ia32_code_gen_t *cg) { ir_node *prev = be_get_IncSP_pred(irn); int real_uses = get_irn_n_edges(prev); - if (real_uses != 1) { - /* - This is a hack that should be removed if be_abi_fix_stack_nodes() - is fixed. Currently it leaves some IncSP's outside the chain ... - The previous IncSp is NOT our prev, but directly scheduled before ... - Impossible in a bug-free implementation :-) - */ - prev = sched_prev(irn); - real_uses = 1; - } - if (be_is_IncSP(prev) && real_uses == 1) { /* first IncSP has only one IncSP user, kill the first one */ unsigned prev_offs = be_get_IncSP_offset(prev); @@ -781,16 +792,23 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn, ir_node *noreg) { /* Try to assimilate a LEA as left operand */ if (is_ia32_Lea(left) && (get_ia32_am_flavour(left) != ia32_am_O)) { - am_flav = get_ia32_am_flavour(left); + ir_node *assim_lea_idx, *assim_lea_base; + + am_flav = get_ia32_am_flavour(left); + assim_lea_base = get_irn_n(left, 0); + assim_lea_idx = get_irn_n(left, 1); + /* If we have an Add with a real right operand (not NoReg) and */ /* the LEA contains already an index calculation then we create */ /* a new LEA. */ /* If the LEA contains already a frame_entity then we also */ /* create a new one otherwise we would loose it. */ - if ((isadd && !be_is_NoReg(cg, index) && (am_flav & ia32_am_I)) || /* no new LEA if index already set */ - get_ia32_frame_ent(left) || /* no new LEA if stack access */ - (have_am_sc && get_ia32_am_sc(left))) /* no new LEA if AM symconst already present */ + if ((isadd && ! be_is_NoReg(cg, index) && (am_flav & ia32_I)) || /* no new LEA if index already set */ + get_ia32_frame_ent(left) || /* no new LEA if stack access */ + (have_am_sc && get_ia32_am_sc(left)) || /* no new LEA if AM symconst already present */ + /* at least on of the LEA operands must be NOREG */ + (!be_is_NoReg(cg, assim_lea_base) && !be_is_NoReg(cg, assim_lea_idx))) { DBG((mod, LEVEL_1, "\tleave old LEA, creating new one\n")); } @@ -800,9 +818,18 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn, ir_node *noreg) { am_sc = have_am_sc ? am_sc : get_ia32_am_sc(left); have_am_sc = am_sc ? 1 : 0; am_sc_sign = is_ia32_am_sc_sign(left); - base = get_irn_n(left, 0); - index = get_irn_n(left, 1); scale = get_ia32_am_scale(left); + + if (be_is_NoReg(cg, assim_lea_base) && ! be_is_NoReg(cg, assim_lea_idx)) { + /* assimilate index */ + assert(be_is_NoReg(cg, index) && ! be_is_NoReg(cg, base) && "operand mismatch for LEA assimilation"); + index = assim_lea_idx; + } + else if (! be_is_NoReg(cg, assim_lea_base) && be_is_NoReg(cg, assim_lea_idx)) { + /* assimilate base */ + assert(! be_is_NoReg(cg, index) && (base == left) && "operand mismatch for LEA assimilation"); + base = assim_lea_base; + } } } @@ -873,8 +900,13 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn, ir_node *noreg) { set_ia32_op_type(res, ia32_AddrModeS); + 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))); + /* we will exchange it, report here before the Proj is created */ + DBG_OPT_LEA(irn, res); + /* get the result Proj of the Add/Sub */ irn = get_res_proj(irn);