Commit 643ad9be authored by Matthias Braun's avatar Matthias Braun
Browse files

introduce const_memory opcode flag and is_irn_const_memory()

parent 58879e0a
......@@ -472,6 +472,10 @@ FIRM_API int is_fragile_op(const ir_node *node);
* operation: Cond. */
FIRM_API int is_irn_forking(const ir_node *node);
/** Returns true if the operation does not change anymemory contents although
* it has a memory input/output. */
FIRM_API int is_irn_const_memory(const ir_node *node);
/**
* Copies attributes stored in the old node to a new node.
* Assumes both have the same opcode and sufficient size.
......
......@@ -61,6 +61,10 @@ typedef enum {
* conservative aproximation in this case. You cannot change the destination
* of an unknown_jump */
irop_flag_unknown_jump = 1U << 11,
/** The opcode has a memory input/output but does not actually change the
* contents of any memory block known to the program. The input/output is
* just necessary for scheduling reasons. Implies irop_flag_uses_memory. */
irop_flag_const_memory = 1U << 12,
} irop_flags;
ENUM_BITSET(irop_flags)
......
......@@ -948,6 +948,56 @@ int (is_irn_forking)(const ir_node *node)
return is_irn_forking_(node);
}
static bool is_call_no_write(const ir_node *node)
{
ir_type *call_tp = get_Call_type(node);
unsigned prop = get_method_additional_properties(call_tp);
/* check first the call type */
if ((prop & (mtp_property_const|mtp_property_pure)) == 0) {
/* try the called entity */
ir_entity *callee = get_Call_callee(node);
if (callee != NULL) {
prop = get_entity_additional_properties(callee);
}
}
return prop & (mtp_property_const|mtp_property_pure);
}
int is_irn_const_memory(const ir_node *node)
{
const ir_op *op = get_irn_op(node);
if (get_op_flags(op) & irop_flag_const_memory)
return true;
if (is_Builtin(node)) {
switch (get_Builtin_kind(node)) {
case ir_bk_trap:
case ir_bk_debugbreak:
case ir_bk_compare_swap:
return false;
case ir_bk_return_address:
case ir_bk_frame_address:
case ir_bk_prefetch:
case ir_bk_ffs:
case ir_bk_clz:
case ir_bk_ctz:
case ir_bk_popcount:
case ir_bk_parity:
case ir_bk_bswap:
case ir_bk_inport:
case ir_bk_outport:
case ir_bk_inner_trampoline:
case ir_bk_saturating_increment:
case ir_bk_may_alias:
return true;
}
panic("invalid Builtin %+F", node);
}
if (is_Call(node))
return is_call_no_write(node);
return false;
}
void (copy_node_attr)(ir_graph *irg, const ir_node *old_node, ir_node *new_node)
{
copy_node_attr_(irg, old_node, new_node);
......
......@@ -78,7 +78,7 @@ class Alloc:
Attribute("alignment", type="unsigned",
comment="alignment of the memory block (must be a power of 2)"),
]
flags = [ "uses_memory" ]
flags = [ "uses_memory", "const_memory" ]
pinned = "yes"
attr_struct = "alloc_attr"
......@@ -433,7 +433,7 @@ class Div:
("X_regular", "control flow when no exception occurs"),
("X_except", "control flow when exception occured"),
]
flags = [ "fragile", "uses_memory" ]
flags = [ "fragile", "uses_memory", "const_memory" ]
attrs = [
Attribute("resmode", type="ir_mode*",
comment="mode of the result value"),
......@@ -482,7 +482,7 @@ class Free:
("ptr", "pointer to the object to free"),
]
mode = "mode_M"
flags = [ "uses_memory" ]
flags = [ "uses_memory", "const_memory" ]
pinned = "yes"
@op
......@@ -530,7 +530,7 @@ class Load:
("X_regular", "control flow when no exception occurs"),
("X_except", "control flow when exception occured"),
]
flags = [ "fragile", "uses_memory" ]
flags = [ "fragile", "uses_memory", "const_memory" ]
pinned = "exception"
attrs = [
Attribute("mode", type="ir_mode*",
......@@ -583,7 +583,7 @@ class Mod:
("X_regular", "control flow when no exception occurs"),
("X_except", "control flow when exception occured"),
]
flags = [ "fragile", "uses_memory" ]
flags = [ "fragile", "uses_memory", "const_memory" ]
attrs = [
Attribute("resmode", type="ir_mode*", comment="mode of the result"),
]
......
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