*/
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);
* 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. */
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);
} 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. */
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);
},
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" ] },
},
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" ] },
# 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" ] },
},
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" ] },
},
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" ] },
},
Call => {
- op_flags => [ "fragile" ],
+ op_flags => [ "uses_memory", "fragile" ],
state => "exc_pinned",
reg_req => {
in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
},
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" ] },
},
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" ] },
},
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" ] },
},
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" ] },
},
CopyB_i => {
- op_flags => [ "fragile" ],
+ op_flags => [ "uses_memory", "fragile" ],
state => "pinned",
reg_req => { in => [ "edi", "esi", "none" ],
out => [ "edi", "esi", "none", "none", "none" ] },
},
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" ] },
},
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" ] },
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" ] },
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" ] },
},
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" ] },
# 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" ]},
# 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" ] },
},
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" ] },
$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)) {
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));
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)
{
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;
}
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
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;
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)) {
} 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 {
{{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 %}
attr_struct = "asm_attr"
attrs_name = "assem"
customSerializer = True
+ ins = [
+ ("mem", "memory dependency"),
+ ]
attrs = [
dict(
name = "input_constraints",
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"):