correctly implement memop handling
authorMatthias Braun <matze@braunis.de>
Wed, 7 Dec 2011 22:26:39 +0000 (23:26 +0100)
committerMatthias Braun <matze@braunis.de>
Wed, 7 Dec 2011 22:28:34 +0000 (23:28 +0100)
memops are nodes that have memory inputs, you can generically query them
for their memory input. We can also get rid of get_fragile_op_mem in
favor of get_memop_mem.

14 files changed:
include/libfirm/irnode.h
include/libfirm/irop.h
ir/ana/trouts.c
ir/be/benode.c
ir/be/ia32/ia32_spec.pl
ir/be/scripts/generate_new_opcodes.pl
ir/ir/irnode.c
ir/ir/irop.c
ir/ir/irtypes.h
ir/opt/gvn_pre.c
ir/opt/ldstopt.c
scripts/gen_ir.py
scripts/ir_spec.py
scripts/spec_util.py

index 807b553..dcb6e4e 100644 (file)
@@ -519,16 +519,15 @@ FIRM_API ir_node  *get_Phi_next(const ir_node *phi);
  */
 FIRM_API void      set_Phi_next(ir_node *phi, ir_node *next);
 
-/** Return true if parameter is a memory operation.
+/** Return true if @p node is a memory operation.
  *
  *  A memory operation is an operation that changes the
  *  memory.  I.e., a Load or a Store operation.
+ *  memops have a memory input and output
  */
 FIRM_API int      is_memop(const ir_node *node);
 FIRM_API ir_node *get_memop_mem(const ir_node *node);
 FIRM_API void     set_memop_mem(ir_node *node, ir_node *mem);
-FIRM_API ir_node *get_memop_ptr(const ir_node *node);
-FIRM_API void     set_memop_ptr(ir_node *node, ir_node *ptr);
 
 FIRM_API ir_node **get_Sync_preds_arr(ir_node *node);
 FIRM_API int       get_Sync_n_preds(const ir_node *node);
@@ -584,8 +583,6 @@ FIRM_API int is_unknown_jump(const ir_node *node);
  * Bad. Raise is not fragile, but a unconditional jump.
  */
 FIRM_API int is_fragile_op(const ir_node *node);
-/** Returns the memory operand of fragile operations. */
-FIRM_API ir_node *get_fragile_op_mem(ir_node *node);
 
 /** Returns true if the operation is a forking control flow
  *  operation: Cond. */
index 5c1112f..538d3df 100644 (file)
@@ -277,12 +277,17 @@ FIRM_API ir_op *new_ir_op(unsigned code, const char *name, op_pin_state p,
                           unsigned flags, op_arity opar, int op_index,
                           size_t attr_size, const ir_op_ops *ops);
 
+/**
+ * set memory input of operation using memory
+ */
+FIRM_API void ir_op_set_memory_index(ir_op *op, int memory_index);
+
 /**
  * Set proj-number for X_regular and X_except projs of fragile nodes.
  * Note: should only be used immediately after new_ir_op
  */
-FIRM_API void ir_op_set_fragile_indices(ir_op *op, int fragile_mem_index,
-                                        int pn_x_regular, int pn_x_except);
+FIRM_API void ir_op_set_fragile_indices(ir_op *op, int pn_x_regular,
+                                        int pn_x_except);
 
 /** Returns the ir_op_ops of an ir_op. */
 FIRM_API const ir_op_ops *get_op_ops(const ir_op *op);
index e8e2d09..55b294b 100644 (file)
@@ -603,8 +603,10 @@ static void chain_accesses(ir_node *n, void *env)
        } else if (is_SymConst_addr_ent(n)) {
                add_entity_reference(get_SymConst_entity(n), n);
                return;
-       } else if (is_memop(n)) {
-               addr = get_memop_ptr(n);
+       } else if (is_Store(n)) {
+               addr = get_Store_ptr(n);
+       } else if (is_Load(n)) {
+               addr = get_Load_ptr(n);
        } else if (is_Call(n)) {
                addr = get_Call_ptr(n);
                if (! is_Sel(addr)) return;  /* Sels before Calls mean a Load / polymorphic Call. */
index decc044..80ca173 100644 (file)
@@ -1332,7 +1332,8 @@ void be_init_op(void)
        op_be_Keep      = new_ir_op(beo_Keep,      "be_Keep",      op_pin_state_exc_pinned, irop_flag_keep,                          oparity_dynamic,  0, sizeof(be_node_attr_t),    &be_node_op_ops);
        op_be_CopyKeep  = new_ir_op(beo_CopyKeep,  "be_CopyKeep",  op_pin_state_exc_pinned, irop_flag_keep,                          oparity_variable, 0, sizeof(be_node_attr_t),    &be_node_op_ops);
        op_be_Call      = new_ir_op(beo_Call,      "be_Call",      op_pin_state_exc_pinned, irop_flag_fragile|irop_flag_uses_memory, oparity_variable, 0, sizeof(be_call_attr_t),    &be_node_op_ops);
-       ir_op_set_fragile_indices(op_be_Call, n_be_Call_mem, pn_be_Call_X_regular, pn_be_Call_X_except);
+       ir_op_set_memory_index(op_be_Call, n_be_Call_mem);
+       ir_op_set_fragile_indices(op_be_Call, pn_be_Call_X_regular, pn_be_Call_X_except);
        op_be_Return    = new_ir_op(beo_Return,    "be_Return",    op_pin_state_exc_pinned, irop_flag_cfopcode,                      oparity_dynamic,  0, sizeof(be_return_attr_t),  &be_node_op_ops);
        op_be_AddSP     = new_ir_op(beo_AddSP,     "be_AddSP",     op_pin_state_exc_pinned, irop_flag_none,                          oparity_unary,    0, sizeof(be_node_attr_t),    &be_node_op_ops);
        op_be_SubSP     = new_ir_op(beo_SubSP,     "be_SubSP",     op_pin_state_exc_pinned, irop_flag_none,                          oparity_unary,    0, sizeof(be_node_attr_t),    &be_node_op_ops);
index f907451..e0ca388 100644 (file)
@@ -587,7 +587,7 @@ l_Sbb => {
 },
 
 IDiv => {
-       op_flags  => [ "fragile", "labeled" ],
+       op_flags  => [ "fragile", "uses_memory", "labeled" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
                       out => [ "eax", "flags", "none", "edx", "none", "none" ] },
@@ -601,7 +601,7 @@ IDiv => {
 },
 
 Div => {
-       op_flags  => [ "fragile", "labeled" ],
+       op_flags  => [ "fragile", "uses_memory", "labeled" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
                       out => [ "eax", "flags", "none", "edx", "none", "none" ] },
@@ -1195,7 +1195,7 @@ Cltd => {
 # lateny of 0 for load is correct
 
 Load => {
-       op_flags  => [ "fragile", "labeled" ],
+       op_flags  => [ "uses_memory", "fragile", "labeled" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none" ],
                       out => [ "gp", "none", "none", "none", "none" ] },
@@ -1207,7 +1207,7 @@ Load => {
 },
 
 Store => {
-       op_flags  => [ "fragile", "labeled" ],
+       op_flags  => [ "uses_memory", "fragile", "labeled" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none", "gp" ],
                       out => [ "none", "none", "none" ] },
@@ -1219,7 +1219,7 @@ Store => {
 },
 
 Store8Bit => {
-       op_flags  => [ "fragile", "labeled" ],
+       op_flags  => [ "uses_memory", "fragile", "labeled" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
                       out => ["none", "none", "none" ] },
@@ -1429,7 +1429,7 @@ Popcnt => {
 },
 
 Call => {
-       op_flags  => [ "fragile" ],
+       op_flags  => [ "uses_memory", "fragile" ],
        state     => "exc_pinned",
        reg_req   => {
                in  => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
@@ -1853,7 +1853,7 @@ Ucomi => {
 },
 
 xLoad => {
-       op_flags  => [ "fragile", "labeled" ],
+       op_flags  => [ "uses_memory", "fragile", "labeled" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none" ],
                       out => [ "xmm", "none", "none", "none", "none" ] },
@@ -1867,7 +1867,7 @@ xLoad => {
 },
 
 xStore => {
-       op_flags => [ "fragile", "labeled" ],
+       op_flags => [ "uses_memory", "fragile", "labeled" ],
        state    => "exc_pinned",
        reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
                      out => [ "none", "none", "none" ] },
@@ -1879,7 +1879,7 @@ xStore => {
 },
 
 xStoreSimple => {
-       op_flags => [ "fragile", "labeled" ],
+       op_flags => [ "uses_memory", "fragile", "labeled" ],
        state    => "exc_pinned",
        reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
                      out => [ "none", "none", "none" ] },
@@ -1929,7 +1929,7 @@ l_FloattoLL => {
 },
 
 CopyB => {
-       op_flags  => [ "fragile" ],
+       op_flags  => [ "uses_memory", "fragile" ],
        state     => "pinned",
        reg_req   => { in => [ "edi", "esi", "ecx", "none" ],
                       out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
@@ -1944,7 +1944,7 @@ CopyB => {
 },
 
 CopyB_i => {
-       op_flags  => [ "fragile" ],
+       op_flags  => [ "uses_memory", "fragile" ],
        state     => "pinned",
        reg_req   => { in => [ "edi", "esi", "none" ],
                       out => [  "edi", "esi", "none", "none", "none" ] },
@@ -1970,7 +1970,7 @@ Cwtl => {
 },
 
 Conv_I2I => {
-       op_flags  => [ "fragile" ],
+       op_flags  => [ "uses_memory", "fragile" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none", "gp" ],
                       out => [ "gp", "none", "none", "none", "none" ] },
@@ -1985,7 +1985,7 @@ Conv_I2I => {
 },
 
 Conv_I2I8Bit => {
-       op_flags  => [ "fragile" ],
+       op_flags  => [ "uses_memory", "fragile" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
                       out => [ "gp", "none", "none", "none", "none" ] },
@@ -2117,7 +2117,7 @@ vfchs => {
 
 vfld => {
        irn_flags => [ "rematerializable" ],
-       op_flags  => [ "fragile", "labeled" ],
+       op_flags  => [ "uses_memory", "fragile", "labeled" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none" ],
                       out => [ "vfp", "none", "none", "none", "none" ] },
@@ -2132,7 +2132,7 @@ vfld => {
 
 vfst => {
        irn_flags => [ "rematerializable" ],
-       op_flags  => [ "fragile", "labeled" ],
+       op_flags  => [ "uses_memory", "fragile", "labeled" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none", "vfp" ],
                       out => [ "none", "none", "none" ] },
@@ -2157,7 +2157,7 @@ vfild => {
 },
 
 vfist => {
-       op_flags  => [ "fragile" ],
+       op_flags  => [ "uses_memory", "fragile" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none", "vfp", "fpcw" ],
                       out => [ "none", "none", "none", "none" ] },
@@ -2170,7 +2170,7 @@ vfist => {
 
 # SSE3 fisttp instruction
 vfisttp => {
-       op_flags  => [ "fragile" ],
+       op_flags  => [ "uses_memory", "fragile" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none", "vfp" ],
                       out => [ "in_r4", "none", "none", "none" ]},
@@ -2693,7 +2693,7 @@ FtstFnstsw => {
 # Spilling and reloading of SSE registers, hardcoded, not generated #
 
 xxLoad => {
-       op_flags  => [ "fragile", "labeled" ],
+       op_flags  => [ "uses_memory", "fragile", "labeled" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none" ],
                       out => [ "xmm", "none", "none", "none" ] },
@@ -2705,7 +2705,7 @@ xxLoad => {
 },
 
 xxStore => {
-       op_flags => [ "fragile", "labeled" ],
+       op_flags => [ "uses_memory", "fragile", "labeled" ],
        state    => "exc_pinned",
        reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
                      out => [ "none", "none", "none" ] },
index 205a01d..4bf8132 100755 (executable)
@@ -700,7 +700,8 @@ EOF
        $temp .= ", ".translate_arity($arity).", 0, ${attr_size}, &ops);\n";
        push(@obst_new_irop, $temp);
        if ($is_fragile) {
-               push(@obst_new_irop, "\tir_op_set_fragile_indices(op_${op}, n_${op}_mem, pn_${op}_X_regular, pn_${op}_X_except);\n");
+               push(@obst_new_irop, "\tir_op_set_memory_index(op_${op}, n_${op}_mem);\n");
+               push(@obst_new_irop, "\tir_op_set_fragile_indices(op_${op}, pn_${op}_X_regular, pn_${op}_X_except);\n");
        }
        push(@obst_new_irop, "\tset_op_tag(op_$op, $arch\_op_tag);\n");
        if(defined($default_op_attr_type)) {
index 76eb158..ce383e8 100644 (file)
@@ -1194,39 +1194,23 @@ void (set_Phi_next)(ir_node *phi, ir_node *next)
 
 int is_memop(const ir_node *node)
 {
-       unsigned code = get_irn_opcode(node);
-       return (code == iro_Load || code == iro_Store);
+       return is_op_uses_memory(get_irn_op(node));
 }
 
 ir_node *get_memop_mem(const ir_node *node)
 {
+       const ir_op *op = get_irn_op(node);
        assert(is_memop(node));
-       assert(n_Load_mem == 0 && n_Store_mem == 0);
-       return get_irn_n(node, 0);
+       return get_irn_n(node, op->memory_index);
 }
 
 void set_memop_mem(ir_node *node, ir_node *mem)
 {
+       const ir_op *op = get_irn_op(node);
        assert(is_memop(node));
-       assert(n_Load_mem == 0 && n_Store_mem == 0);
-       set_irn_n(node, 0, mem);
+       set_irn_n(node, op->memory_index, mem);
 }
 
-ir_node *get_memop_ptr(const ir_node *node)
-{
-       assert(is_memop(node));
-       assert(n_Load_mem == 1 && n_Store_mem == 1);
-       return get_irn_n(node, 1);
-}
-
-void set_memop_ptr(ir_node *node, ir_node *ptr)
-{
-       assert(is_memop(node));
-       assert(n_Load_mem == 1 && n_Store_mem == 1);
-       set_irn_n(node, 1, ptr);
-}
-
-
 ir_node **get_Sync_preds_arr(ir_node *node)
 {
        assert(is_Sync(node));
@@ -1520,13 +1504,6 @@ int is_fragile_op(const ir_node *node)
        return is_op_fragile(get_irn_op(node));
 }
 
-/* Returns the memory operand of fragile operations. */
-ir_node *get_fragile_op_mem(ir_node *node)
-{
-       assert(node && is_fragile_op(node));
-       return get_irn_n(node, node->op->fragile_mem_index);
-}
-
 /* Returns true if the operation is a forking control flow operation. */
 int (is_irn_forking)(const ir_node *node)
 {
index c28d9b4..3fd3d72 100644 (file)
@@ -201,10 +201,15 @@ void free_ir_op(ir_op *code)
        free(code);
 }
 
-void ir_op_set_fragile_indices(ir_op *op, int fragile_mem_index,
-                               int pn_x_regular, int pn_x_except)
+void ir_op_set_memory_index(ir_op *op, int memory_index)
 {
-       op->fragile_mem_index = fragile_mem_index;
+       assert(op->flags & irop_flag_uses_memory);
+       op->memory_index = memory_index;
+}
+
+void ir_op_set_fragile_indices(ir_op *op, int pn_x_regular, int pn_x_except)
+{
+       assert(op->flags & irop_flag_fragile);
        op->pn_x_regular = pn_x_regular;
        op->pn_x_except = pn_x_except;
 }
index 53cd474..27c5db0 100644 (file)
@@ -60,7 +60,7 @@ struct ir_op {
        op_arity opar;            /**< The arity of operator. */
        int op_index;             /**< The index of the first data operand, 0 for
                                       most cases, 1 for Div etc. */
-       int fragile_mem_index;    /**< index of memory input for fragile nodes */
+       int memory_index;         /**< index of memory input for memory nodes */
        int pn_x_regular;         /**< for fragile ops the position of the
                                       X_regular output */
        int pn_x_except;          /**< for fragile ops the position of the
index 54e1a9f..56229ef 100644 (file)
@@ -192,7 +192,7 @@ static int is_nice_value(ir_node *n)
        if (!mode_is_data(mode)) {
                if (! is_Div(n) && ! is_Mod(n))
                        return 0;
-               if (! is_NoMem(get_fragile_op_mem(n)))
+               if (! is_NoMem(get_memop_mem(n)))
                        return 0;
        }
        return 1;
index 9bb8de6..2711ac4 100644 (file)
@@ -2142,7 +2142,7 @@ static void dfs(ir_node *irn, loop_env *env)
                                node->low = MIN(o->DFSnum, node->low);
                }
        } else if (is_fragile_op(irn)) {
-               ir_node *pred = get_fragile_op_mem(irn);
+               ir_node *pred = get_memop_mem(irn);
                node_entry *o = get_irn_ne(pred, env);
 
                if (!irn_visited(pred)) {
@@ -2209,7 +2209,7 @@ static void do_dfs(ir_graph *irg, loop_env *env)
                } else if (is_Raise(pred)) {
                        dfs(get_Raise_mem(pred), env);
                } else if (is_fragile_op(pred)) {
-                       dfs(get_fragile_op_mem(pred), env);
+                       dfs(get_memop_mem(pred), env);
                } else if (is_Bad(pred)) {
                        /* ignore non-optimized block predecessor */
                } else {
index f6438ba..6a80642 100755 (executable)
@@ -481,8 +481,11 @@ void init_op(void)
                        {{node|attr_size}}
                        NULL
                {% endfilter %});
+       {%- if "uses_memory" in node.flags: %}
+       ir_op_set_memory_index(op_{{node.name}}, n_{{node.name}}_mem);
+       {%- endif -%}
        {%- if "fragile" in node.flags: %}
-       ir_op_set_fragile_indices(op_{{node.name}}, n_{{node.name}}_mem, pn_{{node.name}}_X_regular, pn_{{node.name}}_X_except);
+       ir_op_set_fragile_indices(op_{{node.name}}, pn_{{node.name}}_X_regular, pn_{{node.name}}_X_except);
        {%- endif -%}
        {%- endfor %}
 
index 2650299..b6a6d10 100755 (executable)
@@ -92,6 +92,9 @@ class ASM(Op):
        attr_struct      = "asm_attr"
        attrs_name       = "assem"
        customSerializer = True
+       ins   = [
+               ("mem",    "memory dependency"),
+       ]
        attrs = [
                dict(
                        name    = "input_constraints",
index 6e15063..2c71bcd 100644 (file)
@@ -29,13 +29,14 @@ def verify_node(node):
                print "ERROR: flags of %s not a list" % node.__name__
        if hasattr(node, "pinned_init") and not is_dynamic_pinned(node):
                print "ERROR: node %s has pinned_init attribute but is not marked as dynamically pinned" % node.__name__
+       if hasattr(node, "flags") and "uses_memory" in node.flags:
+               if not inout_contains(node.ins, "mem"):
+                       print "ERROR: memory op %s needs an input named 'mem'" % node.__name__
        if is_fragile(node):
                if not is_dynamic_pinned(node):
                        print "ERROR: fragile node %s must be dynamically pinned" % node.__name__
                if not hasattr(node, "throws_init"):
                        print "ERROR: fragile node %s needs a throws_init attribute" % node.__name__
-               if not inout_contains(node.ins, "mem"):
-                       print "ERROR: fragile node %s needs an input named 'mem'" % node.__name__
                if not inout_contains(node.outs, "X_regular"):
                        print "ERROR: fragile node %s needs an output named 'X_regular'" % node.__name__
                if not inout_contains(node.outs, "X_except"):