fixed warnings
[libfirm] / ir / be / ia32 / ia32_optimize.c
index a30c88a..f812d1b 100644 (file)
@@ -71,17 +71,6 @@ static INLINE int be_is_NoReg(ia32_code_gen_t *cg, const ir_node *irn) {
        return irn == cg->noreg_gp || irn == cg->noreg_xmm || irn == cg->noreg_vfp;
 }
 
-void ia32_pre_transform_phase(ia32_code_gen_t *cg) {
-       /*
-               We need to transform the consts twice:
-               - the psi condition tree transformer needs existing constants to be ia32 constants
-               - the psi condition tree transformer inserts new firm constants which need to be transformed
-       */
-       //ia32_transform_all_firm_consts(cg);
-       irg_walk_graph(cg->irg, NULL, ia32_transform_psi_cond_tree, cg);
-       //ia32_transform_all_firm_consts(cg);
-}
-
 /********************************************************************************************************
  *  _____                _           _         ____        _   _           _          _   _
  * |  __ \              | |         | |       / __ \      | | (_)         (_)        | | (_)
@@ -168,7 +157,8 @@ static int is_TestJmp_replacement(ir_node *cand, ir_node *irn) {
 /**
  * Tries to replace a TestJmp by a CJmp or CJmpAM (in case of And)
  */
-static void ia32_optimize_TestJmp(ir_node *irn, ia32_code_gen_t *cg) {
+static void ia32_optimize_TestJmp(ir_node *irn)
+{
        ir_node *cand    = ia32_determine_cjmp_cand(irn, is_TestJmp_cand);
        int      replace = 0;
 
@@ -210,7 +200,8 @@ static int is_CondJmp_replacement(ir_node *cand, ir_node *irn) {
 /**
  * Tries to replace a CondJmp by a CJmpAM
  */
-static void ia32_optimize_CondJmp(ir_node *irn, ia32_code_gen_t *cg) {
+static void ia32_optimize_CondJmp(ir_node *irn)
+{
        ir_node *cand    = ia32_determine_cjmp_cand(irn, is_CondJmp_cand);
        int      replace = 0;
 
@@ -332,7 +323,6 @@ static void ia32_create_Pushs(ir_node *irn, ia32_code_gen_t *cg) {
 
                // 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);
@@ -396,9 +386,9 @@ static void ia32_peephole_optimize_node(ir_node *irn, void *env) {
        /* AMD CPUs want explicit compare before conditional jump  */
        if (! ARCH_AMD(cg->opt_arch)) {
                if (is_ia32_TestJmp(irn))
-                       ia32_optimize_TestJmp(irn, cg);
+                       ia32_optimize_TestJmp(irn);
                else if (is_ia32_CondJmp(irn))
-                       ia32_optimize_CondJmp(irn, cg);
+                       ia32_optimize_CondJmp(irn);
        }
 
        if (be_is_IncSP(irn)) {
@@ -489,7 +479,8 @@ 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 *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;
@@ -512,6 +503,7 @@ static int is_addr_candidate(const ir_node *irn) {
        }
 #endif
 
+       (void) irn;
        return 1;
 }
 
@@ -529,7 +521,7 @@ static int is_addr_candidate(const ir_node *irn) {
  * @param irn         The irn to check
  * return 0 if irn is no candidate, 1 if left load can be used, 2 if right one, 3 for both
  */
-static ia32_am_cand_t is_am_candidate(ia32_code_gen_t *cg, heights_t *h, const ir_node *block, ir_node *irn) {
+static ia32_am_cand_t is_am_candidate(heights_t *h, const ir_node *block, ir_node *irn) {
        ir_node *in, *load, *other, *left, *right;
        int      is_cand = 0, cand;
        int arity;
@@ -980,6 +972,10 @@ 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_info, irg, block, base, index);
+               /* we don't want stuff before the barrier... */
+               if(be_is_NoReg(cg, base) && be_is_NoReg(cg, index)) {
+                       add_irn_dep(res, get_irg_frame(irg));
+               }
 
                /* add the old offset of a previous LEA */
                add_ia32_am_offs_int(res, offs);
@@ -1201,7 +1197,7 @@ static void optimize_lea(ia32_code_gen_t *cg, ir_node *irn) {
        }
 }
 
-static void optimize_conv_store(ia32_code_gen_t *cg, ir_node *node)
+static void optimize_conv_store(ir_node *node)
 {
        ir_node *pred;
        ir_mode *conv_mode;
@@ -1227,7 +1223,7 @@ static void optimize_conv_store(ia32_code_gen_t *cg, ir_node *node)
        }
 }
 
-static void optimize_load_conv(ia32_code_gen_t *cg, ir_node *node)
+static void optimize_load_conv(ir_node *node)
 {
        ir_node *pred, *predpred;
        ir_mode *load_mode;
@@ -1251,11 +1247,28 @@ static void optimize_load_conv(ia32_code_gen_t *cg, ir_node *node)
        if(get_mode_size_bits(conv_mode) < get_mode_size_bits(load_mode))
                return;
 
+       if(get_mode_sign(conv_mode) != get_mode_sign(load_mode)) {
+               /* change the load if it has only 1 user */
+               if(get_irn_n_edges(pred) == 1) {
+                       ir_mode *newmode;
+                       if(get_mode_sign(conv_mode)) {
+                               newmode = find_signed_mode(load_mode);
+                       } else {
+                               newmode = find_unsigned_mode(load_mode);
+                       }
+                       assert(newmode != NULL);
+                       set_ia32_ls_mode(predpred, newmode);
+               } else {
+                       /* otherwise we have to keep the conv */
+                       return;
+               }
+       }
+
        /* kill the conv */
        exchange(node, pred);
 }
 
-static void optimize_conv_conv(ia32_code_gen_t *cg, ir_node *node)
+static void optimize_conv_conv(ir_node *node)
 {
        ir_node *pred;
        ir_mode *pred_mode;
@@ -1264,7 +1277,8 @@ static void optimize_conv_conv(ia32_code_gen_t *cg, ir_node *node)
        if (!is_ia32_Conv_I2I(node) && !is_ia32_Conv_I2I8Bit(node))
                return;
 
-       pred = get_irn_n(node, 2);
+       assert(n_ia32_Conv_I2I_val == n_ia32_Conv_I2I8Bit_val);
+       pred = get_irn_n(node, n_ia32_Conv_I2I_val);
        if(!is_ia32_Conv_I2I(pred) && !is_ia32_Conv_I2I8Bit(pred))
                return;
 
@@ -1275,6 +1289,11 @@ static void optimize_conv_conv(ia32_code_gen_t *cg, ir_node *node)
        if(get_mode_size_bits(conv_mode) < get_mode_size_bits(pred_mode))
                return;
 
+       /* we can't eliminate an upconv signed->unsigned  */
+       if (get_mode_size_bits(conv_mode) != get_mode_size_bits(pred_mode) &&
+               !get_mode_sign(conv_mode) && get_mode_sign(pred_mode))
+               return;
+
        /* kill the conv */
        exchange(node, pred);
 }
@@ -1283,9 +1302,9 @@ static void optimize_node(ir_node *node, void *env)
 {
        ia32_code_gen_t *cg = env;
 
-       optimize_load_conv(cg, node);
-       optimize_conv_store(cg, node);
-       optimize_conv_conv(cg, node);
+       optimize_load_conv(node);
+       optimize_conv_store(node);
+       optimize_conv_conv(node);
        optimize_lea(cg, node);
 }
 
@@ -1344,7 +1363,7 @@ static void optimize_am(ir_node *irn, void *env) {
        if (get_ia32_am_support(irn) == ia32_am_None)
                return;
 
-       cand = is_am_candidate(cg, h, block, irn);
+       cand = is_am_candidate(h, block, irn);
        if (cand == IA32_AM_CAND_NONE)
                return;