Commit e95975c5 authored by Andreas Fried's avatar Andreas Fried
Browse files

Include the type of the objects in memory in alias analysis.

parent bbd65eef
......@@ -61,8 +61,10 @@ FIRM_API const char *get_ir_alias_relation_name(ir_alias_relation rel);
*
* @param addr1 The first address.
* @param type1 The type of the first memory access.
* @param objt1 The type of the object found at addr1 ("object type")
* @param addr2 The second address.
* @param type2 The type of the second memory access.
* @param objt2 The type of the object found at addr2 ("object type")
*
* The memory disambiguator tries to determine the alias state between
* two memory addresses. The following rules are used:
......@@ -90,8 +92,8 @@ FIRM_API const char *get_ir_alias_relation_name(ir_alias_relation rel);
* interrogated to detect the alias relation.
*/
FIRM_API ir_alias_relation get_alias_relation(
const ir_node *addr1, const ir_type *type1,
const ir_node *addr2, const ir_type *type2);
const ir_node *addr1, const ir_type *type1, const ir_type *objt1,
const ir_node *addr2, const ir_type *type2, const ir_type *objt2);
/**
* Assure that the entity usage flags have been computed for the given graph.
......
......@@ -104,53 +104,66 @@ static const ir_node *find_base_addr(const ir_node *node, ir_entity **pEnt)
}
/**
* Determine the alias relation by checking if addr1 and addr2 are pointer
* to different type.
* Returns true if @c compound is a compound type that contains a
* member with type @c member, including recursively, or if @c
* compound is an array type with a base type equal to or containing
* @c member.
*
* @param addr1 The first address.
* @param addr2 The second address.
* @param compound The compound type
* @param member The member type
*
* @return true, if @c compound contains @c member
*/
static ir_alias_relation different_types(const ir_node *addr1,
const ir_node *addr2)
static bool type_contains(const ir_type *compound,
const ir_type *member)
{
ir_entity *ent1 = NULL;
if (is_Address(addr1))
ent1 = get_Address_entity(addr1);
else if (is_Member(addr1))
ent1 = get_Member_entity(addr1);
ir_entity *ent2 = NULL;
if (is_Address(addr2))
ent2 = get_Address_entity(addr2);
else if (is_Member(addr2))
ent2 = get_Member_entity(addr2);
if (ent1 != NULL && ent2 != NULL) {
ir_type *tp1 = get_entity_type(ent1);
ir_type *tp2 = get_entity_type(ent2);
if (tp1 != tp2) {
/* do deref until no pointer types are found */
while (is_Pointer_type(tp1) && is_Pointer_type(tp2)) {
tp1 = get_pointer_points_to_type(tp1);
tp2 = get_pointer_points_to_type(tp2);
}
if (get_type_tpop(tp1) != get_type_tpop(tp2)) {
/* different type structure */
return ir_no_alias;
}
if (is_Class_type(tp1)) {
/* check class hierarchy */
if (!is_SubClass_of(tp1, tp2) && !is_SubClass_of(tp2, tp1))
return ir_no_alias;
} else {
/* different types */
return ir_no_alias;
if (is_Array_type(compound)) {
ir_type *elem = get_array_element_type(compound);
return elem == member ||
type_contains(elem, member);
} else if (is_compound_type(compound)) {
size_t n = get_compound_n_members(compound);
for (size_t pos = 0; pos < n; pos++) {
ir_entity *ent = get_compound_member(compound, pos);
ir_type *pos_type = get_entity_type(ent);
if (pos_type == member ||
type_contains(pos_type, member)) {
return true;
}
}
return false;
} else {
return false;
}
return ir_may_alias;
}
/**
* Determine the alias relation by checking if type1 and type2 are
* different types.
*
* @param addr1 The first type.
* @param addr2 The second type.
*/
static ir_alias_relation different_types(const ir_type *type1,
const ir_type *type2)
{
if (type1 == type2) {
return ir_may_alias;
}
/* do deref until no pointer types are found */
while (is_Pointer_type(type1) && is_Pointer_type(type2)) {
type1 = get_pointer_points_to_type(type1);
type2 = get_pointer_points_to_type(type2);
}
if (type_contains(type1, type2) || type_contains(type2, type1)) {
return ir_may_alias;
}
if (is_Class_type(type1) && is_Class_type(type2) &&
(is_SubClass_of(type1, type2) || is_SubClass_of(type2, type1))) {
return ir_may_alias;
}
return ir_no_alias;
}
/**
......@@ -228,15 +241,17 @@ analyze_entity:
* Determine the alias relation between two addresses.
*
* @param addr1 pointer address of the first memory operation
* @param type1 the type of the accessed data through addr1
* @param type1 the type of the operation accessing addr1
* @param objt1 the type of the object found at addr1 ("object type")
* @param addr2 pointer address of the second memory operation
* @param type2 the type of the accessed data through addr2
* @param type2 the type of the operation accessing addr2
* @param objt2 the type of the object found at addr2 ("object type")
*
* @return found memory relation
*/
static ir_alias_relation _get_alias_relation(
const ir_node *addr1, const ir_type *const type1,
const ir_node *addr2, const ir_type *const type2)
const ir_node *addr1, const ir_type *const type1, const ir_type *const objt1,
const ir_node *addr2, const ir_type *const type2, const ir_type *const objt2)
{
if (addr1 == addr2)
return ir_sure_alias;
......@@ -255,8 +270,6 @@ static ir_alias_relation _get_alias_relation(
long offset2 = 0;
const ir_node *sym_offset1 = NULL;
const ir_node *sym_offset2 = NULL;
const ir_node *orig_addr1 = addr1;
const ir_node *orig_addr2 = addr2;
bool have_const_offsets = true;
/*
......@@ -454,7 +467,7 @@ check_classes:;
ir_alias_relation rel;
if (options & aa_opt_byte_type_may_alias) {
if (get_type_size_bytes(type1) == 1 || get_type_size_bytes(type2) == 1) {
if (get_type_size_bytes(objt1) == 1 || get_type_size_bytes(objt2) == 1) {
/* One of the types address a byte. Assume a ir_may_alias and leave
the type based check. */
goto leave_type_based_alias;
......@@ -462,16 +475,18 @@ check_classes:;
}
/* cheap check: If the type sizes did not match, the types MUST be different */
if (get_type_size_bytes(type1) != get_type_size_bytes(type2))
return ir_no_alias;
/* No, one might be part of the other. */
/* if (get_type_size_bytes(objt1) != get_type_size_bytes(objt2)) */
/* return ir_no_alias; */
/* cheap test: if only one is a reference type, no alias */
if (is_Pointer_type(type1) != is_Pointer_type(type2))
if (is_Pointer_type(objt1) != is_Pointer_type(objt2)) {
return ir_no_alias;
}
if (is_Primitive_type(type1) && is_Primitive_type(type2)) {
const ir_mode *const mode1 = get_type_mode(type1);
const ir_mode *const mode2 = get_type_mode(type2);
if (is_Primitive_type(objt1) && is_Primitive_type(objt2)) {
const ir_mode *const mode1 = get_type_mode(objt1);
const ir_mode *const mode2 = get_type_mode(objt2);
/* cheap test: if arithmetic is different, no alias */
if (get_mode_arithmetic(mode1) != get_mode_arithmetic(mode2))
......@@ -481,7 +496,7 @@ check_classes:;
return ir_no_alias;
}
rel = different_types(orig_addr1, orig_addr2);
rel = different_types(objt1, objt2);
if (rel != ir_may_alias)
return rel;
leave_type_based_alias:;
......@@ -491,10 +506,10 @@ leave_type_based_alias:;
}
ir_alias_relation get_alias_relation(
const ir_node *const addr1, const ir_type *const type1,
const ir_node *const addr2, const ir_type *const type2)
const ir_node *const addr1, const ir_type *const type1, const ir_type *const objt1,
const ir_node *const addr2, const ir_type *const type2, const ir_type *const objt2)
{
ir_alias_relation rel = _get_alias_relation(addr1, type1, addr2, type2);
ir_alias_relation rel = _get_alias_relation(addr1, type1, objt1, addr2, type2, objt2);
DB((dbg, LEVEL_1, "alias(%+F, %+F) = %s\n", addr1, addr2,
get_ir_alias_relation_name(rel)));
return rel;
......
......@@ -118,7 +118,7 @@ static void replace_may_alias(ir_node *node)
ir_type *rtype = get_method_res_type(type, 0);
ir_mode *rmode = get_type_mode(rtype);
ir_alias_relation alias = get_alias_relation(in0, type0, in1, type1);
ir_alias_relation alias = get_alias_relation(in0, type0, type0, in1, type1, type1);
ir_graph *const irg = get_irn_irg(node);
ir_node *const result = (alias != ir_no_alias ? new_r_Const_one : new_r_Const_null)(irg, rmode);
......
......@@ -553,6 +553,14 @@ static bool try_update_ptr_CopyB(track_load_env_t *env, ir_node *copyb)
return true;
}
/* Note on terminology:
* In the following functions, two types are associated with each Load
* and Store: load_type/store_type are the types of the actual
* operations (derived from the modes of the IR nodes), whereas
* load_objt/store_objt are the types of the objects in memory which are
* accessed by the Load/Store nodes.
*/
/**
* Follow the memory chain as long as there are only Loads,
* alias free Stores, and constant Calls and try to replace the
......@@ -567,6 +575,7 @@ static changes_t follow_load_mem_chain(track_load_env_t *env, ir_node *start)
{
ir_node *load = env->load;
ir_mode *load_mode = get_Load_mode(load);
ir_type *load_objt = get_Load_type(load);
ir_node *node = start;
changes_t res = NO_CHANGES;
......@@ -580,13 +589,15 @@ static changes_t follow_load_mem_chain(track_load_env_t *env, ir_node *start)
return changes | res;
/* check if we can pass through this store */
const ir_node *ptr = get_Store_ptr(node);
const ir_node *value = get_Store_value(node);
const ir_mode *mode = get_irn_mode(value);
const ir_type *type = get_type_for_mode(mode);
const ir_type *load_type = get_type_for_mode(load_mode);
ir_alias_relation rel = get_alias_relation(ptr, type, env->ptr,
load_type);
const ir_node *ptr = get_Store_ptr(node);
const ir_node *value = get_Store_value(node);
const ir_type *store_objt = get_Store_type(node);
const ir_mode *mode = get_irn_mode(value);
const ir_type *store_type = get_type_for_mode(mode);
const ir_type *load_type = get_type_for_mode(load_mode);
ir_alias_relation rel = get_alias_relation(
ptr, store_type, store_objt,
env->ptr, load_type, load_objt);
/* if the might be an alias, we cannot pass this Store */
if (rel != ir_no_alias)
break;
......@@ -623,8 +634,9 @@ static changes_t follow_load_mem_chain(track_load_env_t *env, ir_node *start)
ir_node *dst = get_CopyB_dst(node);
ir_type *type = get_CopyB_type(node);
ir_type *load_type = get_type_for_mode(load_mode);
ir_alias_relation rel = get_alias_relation(dst, type, env->ptr,
load_type);
ir_alias_relation rel = get_alias_relation(
dst, type, type,
env->ptr, load_type, load_objt);
/* possible alias => we cannot continue */
if (rel != ir_no_alias)
break;
......@@ -764,6 +776,7 @@ static changes_t follow_store_mem_chain(ir_node *store, ir_node *start,
ir_node *ptr = get_Store_ptr(store);
ir_node *mem = get_Store_mem(store);
ir_node *value = get_Store_value(store);
ir_type *objt = get_Store_type(store);
ir_mode *mode = get_irn_mode(value);
ir_type *type = get_type_for_mode(mode);
ir_node *block = get_nodes_block(store);
......@@ -853,8 +866,10 @@ static changes_t follow_store_mem_chain(ir_node *store, ir_node *start,
ir_node *store_ptr = get_Store_ptr(node);
ir_node *store_value = get_Store_value(node);
ir_type *store_type = get_type_for_mode(get_irn_mode(store_value));
ir_alias_relation rel
= get_alias_relation(store_ptr, store_type, ptr, type);
ir_type *store_objt = get_Store_type(node);
ir_alias_relation rel = get_alias_relation(
store_ptr, store_type, store_objt,
ptr, type, objt);
/* if the might be an alias, we cannot pass this Store */
if (rel != ir_no_alias)
break;
......@@ -862,8 +877,10 @@ static changes_t follow_store_mem_chain(ir_node *store, ir_node *start,
} else if (is_Load(node)) {
ir_node *load_ptr = get_Load_ptr(node);
ir_type *load_type = get_type_for_mode(get_Load_mode(node));
ir_alias_relation rel
= get_alias_relation(load_ptr, load_type, ptr, type);
ir_type *load_objt = get_Load_type(node);
ir_alias_relation rel = get_alias_relation(
load_ptr, load_type, load_objt,
ptr, type, objt);
if (rel != ir_no_alias)
break;
......@@ -871,13 +888,15 @@ static changes_t follow_store_mem_chain(ir_node *store, ir_node *start,
} else if (is_CopyB(node)) {
ir_node *copyb_src = get_CopyB_src(node);
ir_type *copyb_type = get_CopyB_type(node);
ir_alias_relation src_rel
= get_alias_relation(copyb_src, copyb_type, ptr, type);
ir_alias_relation src_rel = get_alias_relation(
copyb_src, copyb_type, copyb_type,
ptr, type, objt);
if (src_rel != ir_no_alias)
break;
ir_node *copyb_dst = get_CopyB_dst(node);
ir_alias_relation dst_rel
= get_alias_relation(copyb_dst, copyb_type, ptr, type);
ir_alias_relation dst_rel = get_alias_relation(
copyb_dst, copyb_type, copyb_type,
ptr, type, objt);
if (dst_rel != ir_no_alias)
break;
} else {
......@@ -1014,7 +1033,10 @@ static changes_t follow_copyb_mem_chain(ir_node *copyb, ir_node *start,
*/
ir_node *store_ptr = get_Store_ptr(node);
ir_type *store_type = get_type_for_mode(get_irn_mode(store_ptr));
ir_alias_relation src_rel = get_alias_relation(src, type, store_ptr, store_type);
ir_type *store_objt = get_Store_type(node);
ir_alias_relation src_rel = get_alias_relation(
src, type, type,
store_ptr, store_type, store_objt);
if (src_rel == ir_no_alias
&& ptr_is_in_struct(store_ptr, store_type, dst, type)) {
......@@ -1031,13 +1053,16 @@ static changes_t follow_copyb_mem_chain(ir_node *copyb, ir_node *start,
ir_node *store_ptr = get_Store_ptr(node);
ir_node *store_value = get_Store_value(node);
ir_type *store_type = get_type_for_mode(get_irn_mode(store_value));
ir_type *store_objt = get_Store_type(node);
/* check if we can pass through this store */
ir_alias_relation src_rel
= get_alias_relation(store_ptr, store_type, src, type);
ir_alias_relation src_rel = get_alias_relation(
store_ptr, store_type, store_objt,
src, type, type);
if (src_rel != ir_no_alias)
break;
ir_alias_relation dst_rel
= get_alias_relation(store_ptr, store_type, dst, type);
ir_alias_relation dst_rel = get_alias_relation(
store_ptr, store_type, store_objt,
dst, type, type);
if (dst_rel != ir_no_alias)
break;
......@@ -1045,8 +1070,10 @@ static changes_t follow_copyb_mem_chain(ir_node *copyb, ir_node *start,
} else if (is_Load(node)) {
ir_node *load_ptr = get_Load_ptr(node);
ir_type *load_type = get_type_for_mode(get_Load_mode(node));
ir_alias_relation rel
= get_alias_relation(load_ptr, load_type, dst, type);
ir_type *load_objt = get_Load_type(node);
ir_alias_relation rel = get_alias_relation(
load_ptr, load_type, load_objt,
dst, type, type);
if (rel != ir_no_alias)
break;
......@@ -1074,16 +1101,19 @@ static changes_t follow_copyb_mem_chain(ir_node *copyb, ir_node *start,
return res | DF_CHANGED;
}
} else {
ir_alias_relation dst_dst_rel
= get_alias_relation(pred_dst, pred_type, dst, type);
ir_alias_relation dst_dst_rel = get_alias_relation(
pred_dst, pred_type, pred_type,
dst, type, type);
if (dst_dst_rel != ir_no_alias)
break;
ir_alias_relation src_dst_rel
= get_alias_relation(pred_src, pred_type, dst, type);
ir_alias_relation src_dst_rel = get_alias_relation(
pred_src, pred_type, pred_type,
dst, type, type);
if (src_dst_rel != ir_no_alias)
break;
ir_alias_relation dst_src_rel
= get_alias_relation(pred_dst, pred_type, src, type);
ir_alias_relation dst_src_rel = get_alias_relation(
pred_dst, pred_type, pred_type,
src, type, type);
if (dst_src_rel != ir_no_alias)
break;
}
......@@ -1628,7 +1658,8 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env)
if (!is_Address(ptr))
continue;
ir_mode *load_mode = get_Load_mode(load);
ir_type *load_type = get_Load_type(load);
ir_type *load_type = get_type_for_mode(load_mode);
ir_type *load_objt = get_Load_type(load);
ir_node *other;
ir_node *next_other;
for (other = pscc->head; other != NULL; other = next_other) {
......@@ -1640,9 +1671,11 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env)
ir_node *store_value = get_Store_value(other);
ir_type *store_type
= get_type_for_mode(get_irn_mode(store_value));
ir_alias_relation rel
= get_alias_relation(store_ptr, store_type, ptr,
load_type);
ir_type *store_objt = get_Store_type(other);
ir_alias_relation rel = get_alias_relation(
store_ptr, store_type, store_objt,
ptr, load_type, load_objt);
/* if the might be an alias, we cannot pass this Store */
if (rel != ir_no_alias)
break;
......@@ -1672,7 +1705,7 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env)
if (res != NULL) {
irn = res->load;
} else {
irn = new_rd_Load(db, pred, get_Phi_pred(phi, pos), ptr, load_mode, load_type, cons_none);
irn = new_rd_Load(db, pred, get_Phi_pred(phi, pos), ptr, load_mode, load_objt, cons_none);
entry.load = irn;
(void)set_insert(avail_entry_t, avail, &entry, sizeof(entry), hash_cache_entry(&entry));
DB((dbg, LEVEL_1, " Created %+F in %+F\n", irn, pred));
......
......@@ -922,8 +922,11 @@ static void kill_memops(const value_t *value)
for (pos = rbitset_next(env.curr_set, 0, 1); pos < end; pos = rbitset_next(env.curr_set, pos + 1, 1)) {
memop_t *op = env.curr_id_2_memop[pos];
if (ir_no_alias != get_alias_relation(value->address, get_type_for_mode(value->mode),
op->value.address, get_type_for_mode(op->value.mode))) {
ir_type *value_type = get_type_for_mode(value->mode);
ir_type *op_type = get_type_for_mode(op->value.mode);
if (ir_no_alias != get_alias_relation(value->address, value_type, value_type,
op->value.address, op_type, op_type)) {
rbitset_clear(env.curr_set, pos);
env.curr_id_2_memop[pos] = NULL;
DB((dbg, LEVEL_2, "KILLING %+F because of possible alias address %+F\n", op->node, value->address));
......
......@@ -30,7 +30,8 @@ typedef struct parallelize_info
{
ir_node *origin_block;
ir_node *origin_ptr;
ir_type *origin_type;
ir_type *origin_ldst_type; /**< Type derived from Load/Store mode */
ir_type *origin_obj_type; /**< Type of the object in memory */
ir_nodeset_t this_mem;
ir_nodeset_t user_mem;
ir_nodeset_t all_visited;
......@@ -55,11 +56,14 @@ static void parallelize_load(parallelize_info *pi, ir_node *irn)
return;
} else if (is_Store(pred) &&
get_Store_volatility(pred) == volatility_non_volatile) {
ir_type *org_type = pi->origin_type;
ir_type *org_type = pi->origin_ldst_type;
ir_type *org_objt = pi->origin_obj_type;
ir_node *org_ptr = pi->origin_ptr;
ir_type *store_type = get_type_for_mode(get_irn_mode(get_Store_value(pred)));
ir_type *store_objt = get_Store_type(pred);
ir_node *store_ptr = get_Store_ptr(pred);
if (get_alias_relation(org_ptr, org_type, store_ptr, store_type) == ir_no_alias) {
if (get_alias_relation(org_ptr, org_type, org_objt,
store_ptr, store_type, store_objt) == ir_no_alias) {
ir_node *mem = get_Store_mem(pred);
ir_nodeset_insert(&pi->user_mem, irn);
parallelize_load(pi, mem);
......@@ -74,11 +78,13 @@ static void parallelize_load(parallelize_info *pi, ir_node *irn)
return;
} else if (is_CopyB(irn) &&
get_CopyB_volatility(irn) == volatility_non_volatile) {
ir_type *org_type = pi->origin_type;
ir_type *org_type = pi->origin_ldst_type;
ir_type *org_objt = pi->origin_obj_type;
ir_node *org_ptr = pi->origin_ptr;
ir_type *copyB_type = get_CopyB_type(irn);
ir_node *copyB_dst = get_CopyB_dst(irn);
if (get_alias_relation(org_ptr, org_type, copyB_dst, copyB_type) == ir_no_alias) {
if (get_alias_relation(org_ptr, org_type, org_objt,
copyB_dst, copyB_type, copyB_type) == ir_no_alias) {
ir_node *mem = get_CopyB_mem(irn);
ir_nodeset_insert(&pi->user_mem, irn);
parallelize_load(pi, mem);
......@@ -102,11 +108,14 @@ static void parallelize_store(parallelize_info *pi, ir_node *irn)
ir_node *pred = get_Proj_pred(irn);
if (is_Load(pred)
&& get_Load_volatility(pred) == volatility_non_volatile) {
ir_type *org_type = pi->origin_type;
ir_type *org_type = pi->origin_ldst_type;
ir_type *org_objt = pi->origin_obj_type;
ir_node *org_ptr = pi->origin_ptr;
ir_type *load_type = get_type_for_mode(get_Load_mode(pred));
ir_type *load_objt = get_Load_type(pred);
ir_node *load_ptr = get_Load_ptr(pred);
if (get_alias_relation(org_ptr, org_type, load_ptr, load_type) == ir_no_alias) {
if (get_alias_relation(org_ptr, org_type, org_objt,
load_ptr, load_type, load_objt) == ir_no_alias) {
ir_node *mem = get_Load_mem(pred);
ir_nodeset_insert(&pi->user_mem, irn);
parallelize_store(pi, mem);
......@@ -114,11 +123,14 @@ static void parallelize_store(parallelize_info *pi, ir_node *irn)
}
} else if (is_Store(pred)
&& get_Store_volatility(pred) == volatility_non_volatile) {
ir_type *org_type = pi->origin_type;
ir_type *org_type = pi->origin_ldst_type;
ir_type *org_objt = pi->origin_obj_type;
ir_node *org_ptr = pi->origin_ptr;
ir_type *store_type = get_type_for_mode(get_irn_mode(get_Store_value(pred)));
ir_type *store_objt = get_Store_type(pred);
ir_node *store_ptr = get_Store_ptr(pred);
if (get_alias_relation(org_ptr, org_type, store_ptr, store_type) == ir_no_alias) {
if (get_alias_relation(org_ptr, org_type, org_objt,
store_ptr, store_type, store_objt) == ir_no_alias) {
ir_node *mem = get_Store_mem(pred);
ir_nodeset_insert(&pi->user_mem, irn);
parallelize_store(pi, mem);
......@@ -133,13 +145,16 @@ static void parallelize_store(parallelize_info *pi, ir_node *irn)
return;
} else if (is_CopyB(irn)
&& get_CopyB_volatility(irn) == volatility_non_volatile) {
ir_type *org_type = pi->origin_type;
ir_type *org_type = pi->origin_ldst_type;
ir_type *org_objt = pi->origin_obj_type;
ir_node *org_ptr = pi->origin_ptr;
ir_type *copyB_type = get_CopyB_type(irn);
ir_node *copyB_src = get_CopyB_src(irn);
ir_node *copyB_dst = get_CopyB_dst(irn);
if (get_alias_relation(org_ptr, org_type, copyB_src, copyB_type) == ir_no_alias &&
get_alias_relation(org_ptr, org_type, copyB_dst, copyB_type) == ir_no_alias) {
if (get_alias_relation(org_ptr, org_type, org_objt,
copyB_src, copyB_type, copyB_type) == ir_no_alias &&
get_alias_relation(org_ptr, org_type, org_objt,
copyB_dst, copyB_type, copyB_type) == ir_no_alias) {
ir_node *mem = get_CopyB_mem(irn);
ir_nodeset_insert(&pi->user_mem, irn);
parallelize_store(pi, mem);
......@@ -163,11 +178,14 @@ static void parallelize_copyB(parallelize_info *pi, ir_node *origin, ir_node *ir
ir_node *pred = get_Proj_pred(irn);
if (is_Load(pred)
&& get_Load_volatility(pred) == volatility_non_volatile) {
ir_type *org_type = pi->origin_type;
ir_type *org_type = pi->origin_ldst_type;
ir_type *org_objt = pi->origin_obj_type;
ir_node *org_ptr = get_CopyB_dst(origin);
ir_type *load_type = get_type_for_mode(get_Load_mode(pred));
ir_node *load_ptr = get_Load_ptr(pred);
if (get_alias_relation(org_ptr, org_type, load_ptr, load_type) == ir_no_alias) {
ir_type *load_objt = get_Load_type(pred);
if (get_alias_relation(org_ptr, org_type, org_objt,
load_ptr, load_type, load_objt) == ir_no_alias) {
ir_node *mem = get_Load_mem(pred);
ir_nodeset_insert(&pi->user_mem, irn);
parallelize_copyB(pi, origin, mem);
......@@ -175,13 +193,17 @@ static void parallelize_copyB(parallelize_info *pi, ir_node *origin, ir_node *ir
}
} else if (is_Store(pred)
&& get_Store_volatility(pred) == volatility_non_volatile) {
ir_type *org_type = pi->origin_type;
ir_type *org_type = pi->origin_ldst_type;
ir_type *org_objt = pi->origin_obj_type;
ir_node *org_src = get_CopyB_src(origin);
ir_node *org_dst = get_CopyB_dst(origin);
ir_type *store_type = get_type_for_mode(get_irn_mode(get_Store_value(pred)));
ir_node *store_ptr = get_Store_ptr(pred);
if (get_alias_relation(org_src, org_type, store_ptr, store_type) == ir_no_alias &&
get_alias_relation(org_dst, org_type, store_ptr, store_type) == ir_no_alias) {
ir_type *store_objt = get_Store_type(pred);
if (get_alias_relation(org_src, org_type, org_objt,
store_ptr, store_type, store_objt) == ir_no_alias &&
get_alias_relation(org_dst, org_type, org_objt,
store_ptr, store_type, store_objt) == ir_no_alias) {
ir_node *mem = get_Store_mem(pred);
ir_nodeset_insert(&pi->user_mem, irn);
parallelize_copyB(pi, origin, mem);
......@@ -196,15 +218,19 @@ static void parallelize_copyB(parallelize_info *pi, ir_node *origin, ir_node *ir
return;
} else if (is_CopyB(irn)
&& get_CopyB_volatility(irn) == volatility_non_volatile) {
ir_type *org_type = pi->origin_type;
ir_type *org_type = pi->origin_ldst_type;
ir_type *org_objt = pi->origin_obj_type;
ir_node *org_src = get_CopyB_src(origin);
ir_node *org_dst = get_CopyB_dst(origin);
ir_type *copyB_type = get_CopyB_type(irn);
ir_node *copyB_src = get_CopyB_src(irn);
ir_node *copyB_dst = get_CopyB_dst(irn);
if (get_alias_relation(org_src, org_type, copyB_dst, copyB_type) == ir_no_alias &&
get_alias_relation(org_dst, org_type, copyB_src, copyB_type) == ir_no_alias &&
get_alias_relation(org_dst, org_type, copyB_dst, copyB_type) == ir_no_alias) {
if (get_alias_relation(org_src, org_type, org_objt,
copyB_dst, copyB_type, copyB_type) == ir_no_alias &&
get_alias_relation(org_dst, org_type, org_objt,
copyB_src, copyB_type, copyB_type) == ir_no_alias &&
get_alias_relation(org_dst, org_type, org_objt,
copyB_dst, copyB_type, copyB_type) == ir_no_alias) {
ir_node *mem = get_CopyB_mem(irn);
ir_nodeset_insert(&pi->user_mem, irn);