cleanup ia32 code (use private linkage where necessary, no need for a custom unique_id)
[libfirm] / ir / be / ia32 / ia32_transform.c
index 973e788..570f240 100644 (file)
 #define DFP_INTMAX "9223372036854775807"
 #define ULL_BIAS   "18446744073709551616"
 
-#define ENT_SFP_SIGN ".LC_ia32_sfp_sign"
-#define ENT_DFP_SIGN ".LC_ia32_dfp_sign"
-#define ENT_SFP_ABS  ".LC_ia32_sfp_abs"
-#define ENT_DFP_ABS  ".LC_ia32_dfp_abs"
-#define ENT_ULL_BIAS ".LC_ia32_ull_bias"
+#define ENT_SFP_SIGN "C_ia32_sfp_sign"
+#define ENT_DFP_SIGN "C_ia32_dfp_sign"
+#define ENT_SFP_ABS  "C_ia32_sfp_abs"
+#define ENT_DFP_ABS  "C_ia32_dfp_abs"
+#define ENT_ULL_BIAS "C_ia32_ull_bias"
 
 #define mode_vfp       (ia32_reg_classes[CLASS_ia32_vfp].mode)
 #define mode_xmm    (ia32_reg_classes[CLASS_ia32_xmm].mode)
@@ -520,7 +520,7 @@ ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
 
                set_entity_ld_ident(ent, get_entity_ident(ent));
                add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
-               set_entity_visibility(ent, ir_visibility_local);
+               set_entity_visibility(ent, ir_visibility_private);
 
                if (kct == ia32_ULLBIAS) {
                        ir_initializer_t *initializer = create_initializer_compound(2);
@@ -709,8 +709,8 @@ static int is_downconv(const ir_node *node)
                return 0;
 
        /* we only want to skip the conv when we're the only user
-        * (not optimal but for now...)
-        */
+        * (because this test is used in the context of address-mode selection
+        *  and we don't want to use address mode for multiple users) */
        if (get_irn_n_edges(node) > 1)
                return 0;
 
@@ -722,7 +722,7 @@ static int is_downconv(const ir_node *node)
                get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
 }
 
-/* Skip all Down-Conv's on a given node and return the resulting node. */
+/** Skip all Down-Conv's on a given node and return the resulting node. */
 ir_node *ia32_skip_downconv(ir_node *node)
 {
        while (is_downconv(node))
@@ -731,6 +731,37 @@ ir_node *ia32_skip_downconv(ir_node *node)
        return node;
 }
 
+static bool is_sameconv(ir_node *node)
+{
+       ir_mode *src_mode;
+       ir_mode *dest_mode;
+
+       if (!is_Conv(node))
+               return 0;
+
+       /* we only want to skip the conv when we're the only user
+        * (because this test is used in the context of address-mode selection
+        *  and we don't want to use address mode for multiple users) */
+       if (get_irn_n_edges(node) > 1)
+               return 0;
+
+       src_mode  = get_irn_mode(get_Conv_op(node));
+       dest_mode = get_irn_mode(node);
+       return
+               ia32_mode_needs_gp_reg(src_mode)  &&
+               ia32_mode_needs_gp_reg(dest_mode) &&
+               get_mode_size_bits(dest_mode) == get_mode_size_bits(src_mode);
+}
+
+/** Skip all signedness convs */
+static ir_node *ia32_skip_sameconv(ir_node *node)
+{
+       while (is_sameconv(node))
+               node = get_Conv_op(node);
+
+       return node;
+}
+
 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
 {
        ir_mode  *mode = get_irn_mode(node);
@@ -798,6 +829,11 @@ static void match_arguments(ia32_address_mode_t *am, ir_node *block,
                if (op1 != NULL) {
                        op1 = ia32_skip_downconv(op1);
                }
+       } else {
+               op2 = ia32_skip_sameconv(op2);
+               if (op1 != NULL) {
+                       op1 = ia32_skip_sameconv(op1);
+               }
        }
 
        /* match immediates. firm nodes are normalized: constants are always on the
@@ -2004,7 +2040,6 @@ static ir_node *gen_Load(ir_node *node)
        ir_node  *index;
        dbg_info *dbgi    = get_irn_dbg_info(node);
        ir_mode  *mode    = get_Load_mode(node);
-       ir_mode  *res_mode;
        ir_node  *new_node;
        ia32_address_t addr;
 
@@ -2030,11 +2065,9 @@ static ir_node *gen_Load(ir_node *node)
                if (ia32_cg_config.use_sse2) {
                        new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
                                                     mode);
-                       res_mode = mode_xmm;
                } else {
                        new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
                                                    mode);
-                       res_mode = mode_vfp;
                }
        } else {
                assert(mode != mode_b);
@@ -2046,7 +2079,6 @@ static ir_node *gen_Load(ir_node *node)
                } else {
                        new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
                }
-               res_mode = mode_Iu;
        }
 
        set_irn_pinned(new_node, get_irn_pinned(node));
@@ -2210,7 +2242,6 @@ static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
        ir_node        *mux_true  = get_Mux_true(node);
        ir_node        *mux_false = get_Mux_false(node);
        ir_node        *cond;
-       ir_node        *new_mem;
        dbg_info       *dbgi;
        ir_node        *block;
        ir_node        *new_block;
@@ -2244,7 +2275,6 @@ static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
        dbgi      = get_irn_dbg_info(node);
        block     = get_nodes_block(node);
        new_block = be_transform_node(block);
-       new_mem   = be_transform_node(mem);
        new_node  = new_bd_ia32_SetccMem(dbgi, new_block, addr.base,
                                         addr.index, addr.mem, flags, pnc);
        set_address(new_node, &addr);
@@ -3116,10 +3146,10 @@ static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **ne
        tp = ia32_create_float_type(mode, 4);
        tp = ia32_create_float_array(tp);
 
-       ent = new_entity(get_glob_type(), ia32_unique_id(".LC%u"), tp);
+       ent = new_entity(get_glob_type(), id_unique("C%u"), tp);
 
        set_entity_ld_ident(ent, get_entity_ident(ent));
-       set_entity_visibility(ent, ir_visibility_local);
+       set_entity_visibility(ent, ir_visibility_private);
        add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
 
        initializer = create_initializer_compound(2);
@@ -3442,13 +3472,6 @@ static ir_node *gen_Mux(ir_node *node)
                        setcc_transform_t res;
                        int step;
 
-                       /* check if flags is a cmp node and we are the only user,
-                          i.e no other user yet */
-                       int permutate_allowed = 0;
-                       if (is_ia32_Cmp(flags) && get_irn_n_edges(flags) == 0) {
-                               /* yes, we can permutate its inputs */
-                               permutate_allowed = 1;
-                       }
                        find_const_transform(pnc, tv_true, tv_false, &res);
                        new_node = node;
                        if (res.permutate_cmp_ins) {
@@ -4398,7 +4421,6 @@ static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
 static ir_node *bad_transform(ir_node *node)
 {
        panic("No transform function for %+F available.", node);
-       return NULL;
 }
 
 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
@@ -5558,7 +5580,7 @@ static ir_node *gen_Proj_Cmp(ir_node *node)
  */
 static ir_node *gen_Proj_Bound(ir_node *node)
 {
-       ir_node *new_node, *block;
+       ir_node *new_node;
        ir_node *pred = get_Proj_pred(node);
 
        switch (get_Proj_proj(node)) {
@@ -5566,11 +5588,9 @@ static ir_node *gen_Proj_Bound(ir_node *node)
                return be_transform_node(get_Bound_mem(pred));
        case pn_Bound_X_regular:
                new_node = be_transform_node(pred);
-               block    = get_nodes_block(new_node);
                return new_r_Proj(new_node, mode_X, pn_ia32_Jcc_true);
        case pn_Bound_X_except:
                new_node = be_transform_node(pred);
-               block    = get_nodes_block(new_node);
                return new_r_Proj(new_node, mode_X, pn_ia32_Jcc_false);
        case pn_Bound_res:
                return be_transform_node(get_Bound_index(pred));
@@ -5687,91 +5707,91 @@ static void register_transformers(void)
        clear_irp_opcodes_generic_func();
 
 #define GEN(a)   { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
-#define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
-
-       GEN(Add);
-       GEN(Sub);
-       GEN(Mul);
-       GEN(Mulh);
-       GEN(And);
-       GEN(Or);
-       GEN(Eor);
-
-       GEN(Shl);
-       GEN(Shr);
-       GEN(Shrs);
-       GEN(Rotl);
-
-       GEN(Quot);
-
-       GEN(Div);
-       GEN(Mod);
-       GEN(DivMod);
-
-       GEN(Minus);
-       GEN(Conv);
-       GEN(Abs);
-       GEN(Not);
-
-       GEN(Load);
-       GEN(Store);
-       GEN(Cond);
-
-       GEN(Cmp);
-       GEN(ASM);
-       GEN(CopyB);
-       GEN(Mux);
-       GEN(Proj);
-       GEN(Phi);
-       GEN(Jmp);
-       GEN(IJmp);
-       GEN(Bound);
+#define BAD(a)   { op_##a->ops.generic = (op_func)bad_transform; }
+
+       GEN(Add)
+       GEN(Sub)
+       GEN(Mul)
+       GEN(Mulh)
+       GEN(And)
+       GEN(Or)
+       GEN(Eor)
+
+       GEN(Shl)
+       GEN(Shr)
+       GEN(Shrs)
+       GEN(Rotl)
+
+       GEN(Quot)
+
+       GEN(Div)
+       GEN(Mod)
+       GEN(DivMod)
+
+       GEN(Minus)
+       GEN(Conv)
+       GEN(Abs)
+       GEN(Not)
+
+       GEN(Load)
+       GEN(Store)
+       GEN(Cond)
+
+       GEN(Cmp)
+       GEN(ASM)
+       GEN(CopyB)
+       GEN(Mux)
+       GEN(Proj)
+       GEN(Phi)
+       GEN(Jmp)
+       GEN(IJmp)
+       GEN(Bound)
 
        /* transform ops from intrinsic lowering */
-       GEN(ia32_l_Add);
-       GEN(ia32_l_Adc);
-       GEN(ia32_l_Mul);
-       GEN(ia32_l_IMul);
-       GEN(ia32_l_ShlDep);
-       GEN(ia32_l_ShrDep);
-       GEN(ia32_l_SarDep);
-       GEN(ia32_l_ShlD);
-       GEN(ia32_l_ShrD);
-       GEN(ia32_l_Sub);
-       GEN(ia32_l_Sbb);
-       GEN(ia32_l_LLtoFloat);
-       GEN(ia32_l_FloattoLL);
-
-       GEN(Const);
-       GEN(SymConst);
-       GEN(Unknown);
+       GEN(ia32_l_Add)
+       GEN(ia32_l_Adc)
+       GEN(ia32_l_Mul)
+       GEN(ia32_l_IMul)
+       GEN(ia32_l_ShlDep)
+       GEN(ia32_l_ShrDep)
+       GEN(ia32_l_SarDep)
+       GEN(ia32_l_ShlD)
+       GEN(ia32_l_ShrD)
+       GEN(ia32_l_Sub)
+       GEN(ia32_l_Sbb)
+       GEN(ia32_l_LLtoFloat)
+       GEN(ia32_l_FloattoLL)
+
+       GEN(Const)
+       GEN(SymConst)
+       GEN(Unknown)
 
        /* we should never see these nodes */
-       BAD(Raise);
-       BAD(Sel);
-       BAD(InstOf);
-       BAD(Cast);
-       BAD(Free);
-       BAD(Tuple);
-       BAD(Id);
-       //BAD(Bad);
-       BAD(Confirm);
-       BAD(Filter);
-       BAD(CallBegin);
-       BAD(EndReg);
-       BAD(EndExcept);
+       BAD(Raise)
+       BAD(Sel)
+       BAD(InstOf)
+       BAD(Cast)
+       BAD(Free)
+       BAD(Tuple)
+       BAD(Id)
+       //BAD(Bad)
+       BAD(Confirm)
+       BAD(Filter)
+       BAD(CallBegin)
+       BAD(EndReg)
+       BAD(EndExcept)
 
        /* handle builtins */
-       GEN(Builtin);
+       GEN(Builtin)
 
        /* handle generic backend nodes */
-       GEN(be_FrameAddr);
-       GEN(be_Call);
-       GEN(be_IncSP);
-       GEN(be_Return);
-       GEN(be_AddSP);
-       GEN(be_SubSP);
-       GEN(be_Copy);
+       GEN(be_FrameAddr)
+       GEN(be_Call)
+       GEN(be_IncSP)
+       GEN(be_Return)
+       GEN(be_AddSP)
+       GEN(be_SubSP)
+       GEN(be_Copy)
 
 #undef GEN
 #undef BAD
@@ -5784,9 +5804,6 @@ static void ia32_pretransform_node(void)
 {
        ia32_code_gen_t *cg = env_cg;
 
-       cg->unknown_gp  = be_pre_transform_node(cg->unknown_gp);
-       cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
-       cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
        cg->noreg_gp    = be_pre_transform_node(cg->noreg_gp);
        cg->noreg_vfp   = be_pre_transform_node(cg->noreg_vfp);
        cg->noreg_xmm   = be_pre_transform_node(cg->noreg_xmm);
@@ -5998,7 +6015,7 @@ void ia32_transform_graph(ia32_code_gen_t *cg)
 
        call_list  = NEW_ARR_F(ir_node *, 0);
        call_types = NEW_ARR_F(ir_type *, 0);
-       be_transform_graph(cg->birg, ia32_pretransform_node);
+       be_transform_graph(cg->irg, ia32_pretransform_node);
 
        if (ia32_cg_config.use_sse2)
                postprocess_fp_call_results();