- make spillslot coalescer pickup float-int convert loads which are folded
authorMatthias Braun <matze@braunis.de>
Thu, 1 Mar 2007 13:55:02 +0000 (13:55 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 1 Mar 2007 13:55:02 +0000 (13:55 +0000)
  into other nodes
- correctly fix Copies in x87 simulator

ir/be/benode.c
ir/be/benode_t.h
ir/be/ia32/bearch_ia32.c
ir/be/ia32/ia32_new_nodes.c
ir/be/ia32/ia32_new_nodes.h
ir/be/ia32/ia32_nodes_attr.h
ir/be/ia32/ia32_optimize.c
ir/be/ia32/ia32_x87.c

index d1caba4..9f29600 100644 (file)
@@ -199,7 +199,7 @@ void be_node_init(void) {
        op_be_Perm       = new_ir_op(beo_base + beo_Perm,       "be_Perm",       op_pin_state_pinned,     N, oparity_variable, 0, sizeof(be_node_attr_t),    &be_node_op_ops);
        op_be_MemPerm    = new_ir_op(beo_base + beo_MemPerm,    "be_MemPerm",    op_pin_state_mem_pinned, N, oparity_variable, 0, sizeof(be_memperm_attr_t), &be_node_op_ops);
        op_be_Copy       = new_ir_op(beo_base + beo_Copy,       "be_Copy",       op_pin_state_floats,     N, oparity_unary,    0, sizeof(be_node_attr_t),    &be_node_op_ops);
-       op_be_Keep       = new_ir_op(beo_base + beo_Keep,       "be_Keep",       op_pin_state_pinned,     K, oparity_variable, 0, sizeof(be_node_attr_t),    &be_node_op_ops);
+       op_be_Keep       = new_ir_op(beo_base + beo_Keep,       "be_Keep",       op_pin_state_pinned,     K, oparity_dynamic,  0, sizeof(be_node_attr_t),    &be_node_op_ops);
        op_be_CopyKeep   = new_ir_op(beo_base + beo_CopyKeep,   "be_CopyKeep",   op_pin_state_pinned,     K, oparity_variable, 0, sizeof(be_node_attr_t),    &be_node_op_ops);
        op_be_Call       = new_ir_op(beo_base + beo_Call,       "be_Call",       op_pin_state_pinned,     F, oparity_variable, 0, sizeof(be_call_attr_t),    &be_node_op_ops);
        op_be_Return     = new_ir_op(beo_base + beo_Return,     "be_Return",     op_pin_state_pinned,     X, oparity_variable, 0, sizeof(be_return_attr_t),  &be_node_op_ops);
@@ -212,7 +212,7 @@ void be_node_init(void) {
        op_be_FrameAddr  = new_ir_op(beo_base + beo_FrameAddr,  "be_FrameAddr",  op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_frame_attr_t),   &be_node_op_ops);
        op_be_FrameLoad  = new_ir_op(beo_base + beo_FrameLoad,  "be_FrameLoad",  op_pin_state_pinned,     N, oparity_any,      0, sizeof(be_frame_attr_t),   &be_node_op_ops);
        op_be_FrameStore = new_ir_op(beo_base + beo_FrameStore, "be_FrameStore", op_pin_state_pinned,     N, oparity_any,      0, sizeof(be_frame_attr_t),   &be_node_op_ops);
-       op_be_Barrier    = new_ir_op(beo_base + beo_Barrier,    "be_Barrier",    op_pin_state_pinned,     N, oparity_any,      0, sizeof(be_node_attr_t),    &be_node_op_ops);
+       op_be_Barrier    = new_ir_op(beo_base + beo_Barrier,    "be_Barrier",    op_pin_state_pinned,     N, oparity_dynamic,  0, sizeof(be_node_attr_t),    &be_node_op_ops);
 
        set_op_tag(op_be_Spill,      &be_node_tag);
        set_op_tag(op_be_Reload,     &be_node_tag);
@@ -240,28 +240,32 @@ void be_node_init(void) {
 /**
  * Initializes the generic attribute of all be nodes and return ir.
  */
-static void *init_node_attr(ir_node* irn, int max_reg_data)
+static void *init_node_attr(ir_node *node, int max_reg_data)
 {
-       ir_graph *irg     = get_irn_irg(irn);
+       ir_graph *irg     = get_irn_irg(node);
        struct obstack *obst = get_irg_obstack(irg);
-       be_node_attr_t *a = get_irn_attr(irn);
-       int i;
+       be_node_attr_t *a = get_irn_attr(node);
 
-       memset(a, 0, sizeof(get_op_attr_size(get_irn_op(irn))));
+       memset(a, 0, sizeof(get_op_attr_size(get_irn_op(node))));
 
        if(max_reg_data >= 0) {
                a->reg_data = NEW_ARR_D(be_reg_data_t, obst, max_reg_data);
                memset(a->reg_data, 0, max_reg_data * sizeof(a->reg_data[0]));
-       }
-
-       for(i = 0; i < max_reg_data; ++i) {
-               a->reg_data[i].req.req.cls  = NULL;
-               a->reg_data[i].req.req.type = arch_register_req_type_none;
+       } else {
+               a->reg_data = NEW_ARR_F(be_reg_data_t, 0);
        }
 
        return a;
 }
 
+static void add_register_req(ir_node *node)
+{
+       be_node_attr_t *a = get_irn_attr(node);
+       be_reg_data_t regreq;
+       memset(&regreq, 0, sizeof(regreq));
+       ARR_APP1(be_reg_data_t, a->reg_data, regreq);
+}
+
 int is_be_node(const ir_node *irn)
 {
        return get_op_tag(get_irn_op(irn)) == &be_node_tag;
@@ -474,15 +478,29 @@ void be_set_Copy_op(ir_node *cpy, ir_node *op) {
 ir_node *be_new_Keep(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, int n, ir_node *in[])
 {
        int i;
-       ir_node *irn;
+       ir_node *res;
+
+       res = new_ir_node(NULL, irg, bl, op_be_Keep, mode_ANY, -1, NULL);
+       init_node_attr(res, -1);
 
-       irn = new_ir_node(NULL, irg, bl, op_be_Keep, mode_ANY, n, in);
-       init_node_attr(irn, n);
        for(i = 0; i < n; ++i) {
-               be_node_set_reg_class(irn, i, cls);
+               add_irn_n(res, in[i]);
+               add_register_req(res);
+               be_node_set_reg_class(res, i, cls);
        }
-       keep_alive(irn);
-       return irn;
+       keep_alive(res);
+
+       return res;
+}
+
+void be_Keep_add_node(ir_node *keep, const arch_register_class_t *cls, ir_node *node)
+{
+       int n;
+
+       assert(be_is_Keep(keep));
+       n = add_irn_n(keep, node);
+       add_register_req(keep);
+       be_node_set_reg_class(keep, n, cls);
 }
 
 ir_node *be_new_Call(dbg_info *dbg, ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *sp, ir_node *ptr,
@@ -660,12 +678,37 @@ ir_node *be_new_StackParam(const arch_register_class_t *cls, const arch_register
 
 ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs)
 {
-       ir_node *irn;
-       ir_node *in[1];
+       ir_node *res;
+       int i;
 
-       irn = new_ir_node(NULL, irg, bl, op_be_RegParams, mode_T, 0, in);
-       init_node_attr(irn, n_outs);
-       return irn;
+       res = new_ir_node(NULL, irg, bl, op_be_RegParams, mode_T, 0, NULL);
+       init_node_attr(res, -1);
+       for(i = 0; i < n_outs; ++i)
+               add_register_req(res);
+
+       return res;
+}
+
+ir_node *be_RegParams_append_out_reg(ir_node *regparams,
+                                     const arch_env_t *arch_env,
+                                     const arch_register_t *reg)
+{
+       ir_graph *irg = get_irn_irg(regparams);
+       ir_node *block = get_nodes_block(regparams);
+       be_node_attr_t *attr = get_irn_attr(regparams);
+       const arch_register_class_t *cls = arch_register_get_class(reg);
+       ir_mode *mode = arch_register_class_mode(cls);
+       int n = ARR_LEN(attr->reg_data);
+
+       assert(be_is_RegParams(regparams));
+       ir_node *proj = new_r_Proj(irg, block, regparams, mode, n);
+       add_register_req(regparams);
+       be_set_constr_single_reg(regparams, n, reg);
+       arch_set_irn_register(arch_env, proj, reg);
+
+       /* TODO decide, whether we need to set ignore/modifysp flags here? */
+
+       return proj;
 }
 
 ir_node *be_new_FrameLoad(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
@@ -755,11 +798,29 @@ void be_set_CopyKeep_op(ir_node *cpy, ir_node *op) {
 
 ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
 {
-       ir_node *irn;
+       ir_node *res;
+       int i;
 
-       irn = new_ir_node(NULL, irg, bl, op_be_Barrier, mode_T, n, in);
-       init_node_attr(irn, n);
-       return irn;
+       res = new_ir_node(NULL, irg, bl, op_be_Barrier, mode_T, -1, NULL);
+       init_node_attr(res, -1);
+       for(i = 0; i < n; ++i) {
+               add_irn_n(res, in[i]);
+               add_register_req(res);
+       }
+
+       return res;
+}
+
+ir_node *be_Barrier_append_node(ir_node *barrier, ir_node *node)
+{
+       ir_graph *irg = get_irn_irg(barrier);
+       ir_node *block = get_nodes_block(barrier);
+       ir_mode *mode = get_irn_mode(node);
+       int n = add_irn_n(barrier, node);
+       ir_node *proj = new_r_Proj(irg, block, barrier, mode, n);
+       add_register_req(barrier);
+
+       return proj;
 }
 
 int be_is_Spill         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Spill          ; }
@@ -933,10 +994,11 @@ void be_node_set_reg_class(ir_node *irn, int pos, const arch_register_class_t *c
 
        r->req.cls = cls;
 
-       if (cls == NULL)
+       if (cls == NULL) {
                r->req.type = arch_register_req_type_none;
-       else if (r->req.type == arch_register_req_type_none)
+       } else if (r->req.type == arch_register_req_type_none) {
                r->req.type = arch_register_req_type_normal;
+       }
 }
 
 void be_node_set_req_type(ir_node *irn, int pos, arch_register_req_type_t type)
@@ -1525,7 +1587,11 @@ static void copy_attr(const ir_node *old_node, ir_node *new_node)
        else
                len = 0;
 
-       new_attr->reg_data = NEW_ARR_D(be_reg_data_t, obst, len);
+       if(be_is_Keep(old_node) || be_is_RegParams(old_node) || be_is_Barrier(old_node)) {
+               new_attr->reg_data = NEW_ARR_F(be_reg_data_t, len);
+       } else {
+               new_attr->reg_data = NEW_ARR_D(be_reg_data_t, obst, len);
+       }
 
        if(len > 0) {
                memcpy(new_attr->reg_data, old_attr->reg_data, len * sizeof(be_reg_data_t));
index 2c7760c..b978105 100644 (file)
@@ -150,6 +150,8 @@ ir_node *be_new_Perm(const arch_register_class_t *cls, ir_graph *irg, ir_node *b
 ir_node *be_new_MemPerm(const arch_env_t *arch_env, ir_graph *irg, ir_node *bl, int n, ir_node *in[]);
 ir_node *be_new_Keep(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, int arity, ir_node *in[]);
 
+void be_Keep_add_node(ir_node *keep, const arch_register_class_t *cls, ir_node *node);
+
 ir_node *be_new_FrameLoad(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
                                                  ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_entity *ent);
 ir_node *be_new_FrameStore(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
@@ -310,6 +312,19 @@ ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_out);
 
 ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[]);
 
+/**
+ * Appends a node to a barrier, returns the result proj of the node
+ */
+ir_node *be_Barrier_append_node(ir_node *barrier, ir_node *node);
+
+/**
+ * Appends a register out requirement to a RegParams node
+ *
+ * @returns the proj node for the new register
+ */
+ir_node *be_RegParams_append_out_req(ir_node *regparams,
+                                     const arch_register_t *reg);
+
 /**
  * Make a spill node.
  *
index 19ad640..36b89a7 100644 (file)
@@ -324,7 +324,7 @@ static arch_irn_class_t ia32_classify(const void *self, const ir_node *irn) {
        if (is_ia32_St(irn) || is_ia32_Store8Bit(irn))
                classification |= arch_irn_class_store;
 
-       if (is_ia32_got_reload(irn))
+       if (is_ia32_need_stackent(irn))
                classification |= arch_irn_class_reload;
 
        return classification;
@@ -992,7 +992,7 @@ static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node
        set_ia32_am_flavour(irn, ia32_B);
        set_ia32_ls_mode(irn, get_irn_mode(get_irn_n(irn, i)));
        set_ia32_use_frame(irn);
-       set_ia32_got_reload(irn);
+       set_ia32_need_stackent(irn);
 
        set_irn_n(irn, 0, get_irg_frame(get_irn_irg(irn)));
        set_irn_n(irn, 3, ia32_get_admissible_noreg(cg, irn, 3));
@@ -1460,7 +1460,7 @@ static void ia32_collect_frame_entity_nodes(ir_node *node, void *data)
                be_node_needs_frame_entity(env, node, mode, align);
        } else if(is_ia32_irn(node) && get_ia32_frame_ent(node) == NULL
                  && is_ia32_use_frame(node)) {
-               if (is_ia32_got_reload(node) || is_ia32_Load(node)) {
+               if (is_ia32_need_stackent(node) || is_ia32_Load(node)) {
                        const ir_mode *mode = get_ia32_ls_mode(node);
                        int align = get_mode_size_bytes(mode);
                        be_node_needs_frame_entity(env, node, mode, align);
index 2ec104d..3c7db40 100644 (file)
@@ -374,8 +374,8 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
                        /* got lea */
                        fprintf(F, "got loea = %d\n", is_ia32_got_lea(n));
 
-                       /* got reload */
-                       fprintf(F, "got reload = %d\n", is_ia32_got_reload(n));
+                       /* need stackent */
+                       fprintf(F, "need stackent = %d\n", is_ia32_need_stackent(n));
 
                        /* dump latency */
                        fprintf(F, "latency = %d\n", get_ia32_latency(n));
@@ -723,28 +723,19 @@ int is_ia32_got_lea(const ir_node *node) {
        return attr->data.got_lea;
 }
 
-/**
- * Sets node got_reload.
- */
-void set_ia32_got_reload(ir_node *node) {
+void set_ia32_need_stackent(ir_node *node) {
        ia32_attr_t *attr     = get_ia32_attr(node);
-       attr->data.got_reload = 1;
+       attr->data.need_stackent = 1;
 }
 
-/**
- * Clears node got_reload.
- */
-void clear_ia32_got_reload(ir_node *node) {
+void clear_ia32_need_stackent(ir_node *node) {
        ia32_attr_t *attr     = get_ia32_attr(node);
-       attr->data.got_reload = 0;
+       attr->data.need_stackent = 0;
 }
 
-/**
- * Checks if node got reload.
- */
-int is_ia32_got_reload(const ir_node *node) {
+int is_ia32_need_stackent(const ir_node *node) {
        ia32_attr_t *attr = get_ia32_attr(node);
-       return attr->data.got_reload;
+       return attr->data.need_stackent;
 }
 
 /**
index 1df4f3b..736e3e9 100644 (file)
@@ -199,19 +199,19 @@ void clear_ia32_got_lea(ir_node *node);
 int is_ia32_got_lea(const ir_node *node);
 
 /**
- * Sets node got_reload.
+ * Sets node needs_stackent
  */
-void set_ia32_got_reload(ir_node *node);
+void set_ia32_need_stackent(ir_node *node);
 
 /**
- * Clears node got_reload.
+ * Clears node needs_stackent
  */
-void clear_ia32_got_reload(ir_node *node);
+void clear_ia32_need_stackent(ir_node *node);
 
 /**
- * Checks if node got reload.
+ * Checks if node needs a stackentity assigned
  */
-int is_ia32_got_reload(const ir_node *node);
+int is_ia32_need_stackent(const ir_node *node);
 
 /**
  * Gets the mode of the stored/loaded value (only set for Store/Load)
index a607fa5..19d5202 100644 (file)
@@ -98,7 +98,7 @@ typedef struct _ia32_attr_t {
 
                unsigned got_lea:1;         /**< indicates whether or not this node already consumed a LEA */
 
-               unsigned got_reload:1;      /**< set to 1 if node cosumed a reload */
+               unsigned need_stackent:1;   /**< set to 1 if node need space on stack */
 
                unsigned n_res:6;           /**< number of results produced by this node */
        } data;
index 4636443..876564f 100644 (file)
@@ -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 <config.h>
 #endif
 
 #include "irnode.h"
@@ -1336,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 */
@@ -1420,8 +1414,13 @@ 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) {
+                               ir_fprintf(stderr, "Falte ent==NULL %+F, %+F\n", load, irn);
+                               set_ia32_need_stackent(irn);
+                       }
                        set_ia32_use_frame(irn);
+               }
 
                /* connect to Load memory and disconnect Load */
                if (get_irn_arity(irn) == 5) {
index 868f258..9cef9e4 100644 (file)
@@ -1554,6 +1554,8 @@ static ir_node *create_Copy(x87_state *state, ir_node *n) {
                /* copy a constant */
                res = (*cnstr)(n_dbg, irg, block, mode);
 
+               x87_push(state, arch_register_get_index(out), res);
+
                attr = get_ia32_attr(res);
                attr->x87[2] = out = &ia32_st_regs[0];
        } else {
@@ -1561,13 +1563,13 @@ static ir_node *create_Copy(x87_state *state, ir_node *n) {
 
                res = new_rd_ia32_fpushCopy(n_dbg, irg, block, pred, mode);
 
+               x87_push(state, arch_register_get_index(out), res);
+
                attr = get_ia32_attr(res);
                attr->x87[0] = op1 = &ia32_st_regs[op1_idx];
                attr->x87[2] = out = &ia32_st_regs[0];
        }
-
        arch_set_irn_register(sim->env, res, out);
-       x87_push(state, arch_register_get_index(out), res);
 
        DB((dbg, LEVEL_1, ">>> %+F -> %s\n", res, arch_register_get_name(out)));
        return res;