Commit 9fbdcb82 authored by Matthias Braun's avatar Matthias Braun
Browse files

correctly implement memop handling

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.
parent 4a91add5
......@@ -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. */
......
......@@ -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);
......
......@@ -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. */
......
......@@ -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);
......
......@@ -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" ] },
......
......@@ -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)) {
......
......@@ -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)
{
......
......@@ -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;
}
......
......@@ -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
......
......@@ -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;
......
......@@ -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 {
......
......@@ -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 %}
......
......@@ -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",
......
......@@ -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"):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment