fixed some minor bugs
authorChristian Würdig <chriswue@ipd.info.uni-karlsruhe.de>
Wed, 15 Mar 2006 14:06:37 +0000 (14:06 +0000)
committerChristian Würdig <chriswue@ipd.info.uni-karlsruhe.de>
Wed, 15 Mar 2006 14:06:37 +0000 (14:06 +0000)
code cleanups
fixed am optimizer
changed comments

ir/be/ia32/bearch_ia32.c
ir/be/ia32/ia32_map_regs.c
ir/be/ia32/ia32_optimize.c
ir/be/ia32/ia32_spec.pl
ir/be/ia32/ia32_transform.c

index 3a63d23..502f590 100644 (file)
@@ -21,6 +21,7 @@
 #include "iredges_t.h"
 #include "ircons.h"
 #include "irgmod.h"
+#include "irgopt.h"
 
 #include "bitset.h"
 #include "debug.h"
@@ -274,6 +275,10 @@ static void ia32_prepare_graph(void *self) {
        irg_walk_blkwise_graph(cg->irg, ia32_place_consts_set_modes, ia32_transform_node, cg);
        dump_ir_block_graph_sched(cg->irg, "-transformed");
 
+       edges_deactivate(cg->irg);
+       dead_node_elimination(cg->irg);
+       edges_activate(cg->irg);
+
        cg->mod = old_mod;
 
        if (cg->opt.doam) {
@@ -470,7 +475,8 @@ static void ia32_after_ra_walker(ir_node *node, void *env) {
        tenv.mode  = get_irn_mode(node);
        tenv.cg    = cg;
 
-       if (be_is_StackParam(node) || be_is_Reload(node)) {
+       /* be_is_StackParam(node) || */
+       if (be_is_Reload(node)) {
                transform_to_Load(&tenv);
        }
        else if (be_is_Spill(node)) {
index 7067c1f..6f02f2a 100644 (file)
@@ -202,7 +202,7 @@ long ia32_translate_proj_pos(const ir_node *proj) {
        long nr       = get_Proj_proj(proj);
 
        if (is_ia32_Ld(pred)) {
-               if (nr == pn_Load_res)
+               if (nr == pn_Load_res || nr == 0)
                        return 0;
                assert(0 && "unsupported Proj(Load) number");
        }
index 73ca2c1..3928a06 100644 (file)
@@ -12,6 +12,8 @@
 
 #include "../be_t.h"
 #include "../beabi.h"
+#include "../benode_t.h"
+#include "../besched_t.h"
 
 #include "ia32_new_nodes.h"
 #include "bearch_ia32_t.h"
@@ -271,7 +273,7 @@ static ir_node *get_mem_proj(const ir_node *irn) {
 }
 
 /**
- * Returns the Proj with number 0 connected to irn.
+ * Returns the first Proj with mode != mode_M connected to irn.
  */
 static ir_node *get_res_proj(const ir_node *irn) {
        const ir_edge_t *edge;
@@ -284,7 +286,7 @@ static ir_node *get_res_proj(const ir_node *irn) {
 
                assert(is_Proj(src) && "Proj expected");
 
-               if (get_Proj_proj(src) == 0)
+               if (get_irn_mode(src) != mode_M)
                        return src;
        }
 
@@ -328,9 +330,7 @@ static int pred_is_specific_nodeblock(const ir_node *bl, const ir_node *pred,
        return 0;
 }
 
-static int is_addr_candidate(const ir_node *block, const ir_node *irn) {
 
-}
 
 /**
  * Checks if irn is a candidate for address calculation or address mode.
@@ -351,22 +351,24 @@ static int is_addr_candidate(const ir_node *block, const ir_node *irn) {
  * return 1 if irn is a candidate for AC or AM, 0 otherwise
  */
 static int is_candidate(const ir_node *block, const ir_node *irn, int check_addr) {
-       ir_node *load_proj;
+       ir_node *in;
        int      n, is_cand = check_addr;
 
-       if (pred_is_specific_nodeblock(block, get_irn_n(irn, 2), is_ia32_Load)) {
-               load_proj = get_irn_n(irn, 2);
-               n         = ia32_get_irn_n_edges(load_proj);
+       in = get_irn_n(irn, 2);
+
+       if (pred_is_specific_nodeblock(block, in, is_ia32_Ld) || be_is_StackParam(in)) {
+               n         = ia32_get_irn_n_edges(in);
                is_cand   = check_addr ? (n == 1 ? 0 : is_cand) : (n == 1 ? 1 : is_cand);
        }
 
-       if (pred_is_specific_nodeblock(block, get_irn_n(irn, 3), is_ia32_Load)) {
-               load_proj = get_irn_n(irn, 3);
-               n         = ia32_get_irn_n_edges(load_proj);
+       in = get_irn_n(irn, 3);
+
+       if (pred_is_specific_nodeblock(block, in, is_ia32_Ld) || be_is_StackParam(in)) {
+               n         = ia32_get_irn_n_edges(in);
                is_cand   = check_addr ? (n == 1 ? 0 : is_cand) : (n == 1 ? 1 : is_cand);
        }
 
-       is_cand = get_ia32_frame_ent(irn) ? (check_addr ? 1 : 0) : (check_addr ? 0 : 1);
+       is_cand = get_ia32_frame_ent(irn) ? (check_addr ? 1 : 0) : is_cand;
 
        return is_cand;
 }
@@ -383,11 +385,16 @@ static int load_store_addr_is_equal(const ir_node *load, const ir_node *store,
        entity *sent     = get_ia32_frame_ent(store);
 
        /* are both entities set and equal? */
-       is_equal = (lent && sent && (lent == sent)) ? 1 : is_equal;
+       is_equal = lent && sent && (lent == sent);
+
+       /* are the load and the store of the same mode? */
+       is_equal = get_ia32_ls_mode(load) == get_ia32_ls_mode(store);
 
        return is_equal;
 }
 
+
+
 /**
  * Folds Add or Sub to LEA if possible
  */
@@ -412,12 +419,6 @@ static ir_node *fold_addr(be_abi_irg_t *babi, ir_node *irn, firm_dbg_module_t *m
        left  = get_irn_n(irn, 2);
        right = get_irn_n(irn, 3);
 
-       base    = left;
-       index   = noreg;
-       offs    = NULL;
-       scale   = 0;
-       am_flav = 0;
-
        /* "normalize" arguments in case of add with two operands */
        if  (isadd && ! be_is_NoReg(babi, right)) {
                /* put LEA == ia32_am_O as right operand */
@@ -448,6 +449,12 @@ static ir_node *fold_addr(be_abi_irg_t *babi, ir_node *irn, firm_dbg_module_t *m
                }
        }
 
+       base    = left;
+       index   = noreg;
+       offs    = NULL;
+       scale   = 0;
+       am_flav = 0;
+
        /* check if operand is either const */
        if (get_ia32_cnst(irn)) {
                DBG((mod, LEVEL_1, "\tfound op with imm"));
@@ -524,7 +531,7 @@ static ir_node *fold_addr(be_abi_irg_t *babi, ir_node *irn, firm_dbg_module_t *m
                /* 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(babi, index) && (am_flav & ia32_am_I)) || get_ia32_frame_ent(left))) {
+               if ((isadd && ((!be_is_NoReg(babi, index) && (am_flav & ia32_am_I))) || get_ia32_frame_ent(left))) {
                        DBG((mod, LEVEL_1, "\tleave old LEA, creating new one\n"));
                }
                else {
index 5c15a85..a2bc1c5 100644 (file)
@@ -405,7 +405,7 @@ $arch = "ia32";
   "comment"   => "construct Lea: Lea(a,b) = lea [a+b*const+offs] | res = a + b * const + offs with const = 0,1,2,4,8",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
-  "emit"      => '. lea %D1, %ia32_emit_am\t\t/* %D1 = %S1 + %S2 << scale + %O, (%A1, %A2) */'
+  "emit"      => '. lea %D1, %ia32_emit_am\t\t/* LEA(%A1, %A2) */'
 },
 
 #--------------------------------------------------------#
index a80d6db..df93fc1 100644 (file)
@@ -1476,6 +1476,37 @@ static ir_node *gen_Conv(ia32_transform_env_t *env, ir_node *op) {
  *
  ********************************************/
 
+static ir_node *gen_StackParam(ia32_transform_env_t *env) {
+       ir_node *new_op = NULL;
+       ir_node *node   = env->irn;
+       ir_node *noreg  = ia32_new_NoReg_gp(env->cg);
+       ir_node *mem    = new_rd_NoMem(env->irg);
+       ir_node *ptr    = get_irn_n(node, 0);
+       entity  *ent    = be_get_frame_entity(node);
+       ir_mode *mode   = env->mode;
+
+       if (mode_is_float(mode)) {
+               new_op = new_rd_ia32_fLoad(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
+       }
+       else {
+               new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
+       }
+
+       set_ia32_frame_ent(new_op, ent);
+       set_ia32_use_frame(new_op);
+
+       set_ia32_am_support(new_op, ia32_am_Source);
+       set_ia32_op_type(new_op, ia32_AddrModeS);
+       set_ia32_am_flavour(new_op, ia32_B);
+       set_ia32_ls_mode(new_op, mode);
+
+#ifndef NDEBUG
+       set_ia32_orig_node(new_op, get_old_node_name(env));
+#endif /* NDEBUG */
+
+       return new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, 0);
+}
+
 /**
  * Transforms a FrameAddr into an ia32 Add.
  */
@@ -1518,6 +1549,7 @@ static ir_node *gen_FrameLoad(ia32_transform_env_t *env) {
        }
 
        set_ia32_frame_ent(new_op, ent);
+       set_ia32_use_frame(new_op);
 
        set_ia32_am_support(new_op, ia32_am_Source);
        set_ia32_op_type(new_op, ia32_AddrModeS);
@@ -1551,7 +1583,9 @@ static ir_node *gen_FrameStore(ia32_transform_env_t *env) {
        else {
                new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, val, mem, mode_T);
        }
+
        set_ia32_frame_ent(new_op, ent);
+       set_ia32_use_frame(new_op);
 
        set_ia32_am_support(new_op, ia32_am_Dest);
        set_ia32_op_type(new_op, ia32_AddrModeD);
@@ -1755,6 +1789,7 @@ void ia32_transform_node(ir_node *node, void *env) {
                        BE_GEN(FrameAddr);
                        BE_GEN(FrameLoad);
                        BE_GEN(FrameStore);
+                       BE_GEN(StackParam);
                        break;
 bad:
                fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));