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

Change the interface of get_alias_relation to take types instead of modes.

Code using get_alias_relation is converted by calling get_type_for_mode at
the appropriate locations.

This is in preparation for optimizations involving CopyB, which needs this
additional flexibility.
parent 5fd9fcfb
......@@ -77,8 +77,8 @@ FIRM_API ir_storage_class_class_t get_base_sc(ir_storage_class_class_t x);
* Called by get_alias_relation().
*/
typedef ir_alias_relation (*DISAMBIGUATOR_FUNC)(
const ir_node *adr1, const ir_mode *mode1,
const ir_node *adr2, const ir_mode *mode2);
const ir_node *adr1, const ir_type *type1,
const ir_node *adr2, const ir_type *type2);
/**
* Classify a base pointer.
......@@ -98,9 +98,9 @@ FIRM_API const char *get_ir_alias_relation_name(ir_alias_relation rel);
* Determine the alias relation between two addresses.
*
* @param adr1 The first address.
* @param mode1 The mode of the first memory access.
* @param type1 The type of the first memory access.
* @param adr2 The second address.
* @param mode2 The mode of the second memory access.
* @param type2 The type of the second memory access.
*
* The memory disambiguator tries to determine the alias state between
* two memory addresses. The following rules are used:
......@@ -128,8 +128,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 *adr1, const ir_mode *mode1,
const ir_node *adr2, const ir_mode *mode2);
const ir_node *adr1, const ir_type *type1,
const ir_node *adr2, const ir_type *type2);
/**
* Sets a source language specific memory disambiguator function.
......@@ -148,15 +148,15 @@ FIRM_API void mem_disambig_init(void);
* cache the result.
*
* @param adr1 The first address.
* @param mode1 The mode of the first memory access.
* @param type1 The type of the first memory access.
* @param adr2 The second address.
* @param mode2 The mode of the second memory access.
* @param type2 The type of the second memory access.
*
* @see get_alias_relation()
*/
FIRM_API ir_alias_relation get_alias_relation_ex(
const ir_node *adr1, const ir_mode *mode1,
const ir_node *adr2, const ir_mode *mode2);
const ir_node *adr1, const ir_type *type1,
const ir_node *adr2, const ir_type *type2);
/**
* Free the relation cache.
......
......@@ -27,6 +27,7 @@
#include "debug.h"
#include "error.h"
#include "typerep.h"
#include "type_t.h"
/** The debug handle. */
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
......@@ -301,7 +302,7 @@ static ir_alias_relation different_sel_offsets(const ir_node *sel1,
if (tp1 == tp2)
check_arr = 1;
else if (get_type_state(tp1) == layout_fixed && get_type_state(tp2) == layout_fixed &&
get_type_size_bits(tp1) == get_type_size_bits(tp2))
get_type_size_bytes(tp1) == get_type_size_bytes(tp2))
check_arr = 1;
}
if (check_arr) {
......@@ -450,16 +451,17 @@ static const ir_node *skip_bitfield_sels(const ir_node *adr)
* Determine the alias relation between two addresses.
*
* @param addr1 pointer address of the first memory operation
* @param mode1 the mode of the accessed data through addr1
* @param type1 the type of the accessed data through addr1
* @param addr2 pointer address of the second memory operation
* @param mode2 the mode of the accessed data through addr2
* @param type2 the type of the accessed data through addr2
*
* @return found memory relation
*/
static ir_alias_relation _get_alias_relation(
const ir_node *adr1, const ir_mode *const mode1,
const ir_node *adr2, const ir_mode *const mode2)
const ir_node *adr1, const ir_type *const type1,
const ir_node *adr2, const ir_type *const type2)
{
if (!get_opt_alias_analysis())
return ir_may_alias;
......@@ -547,16 +549,16 @@ static ir_alias_relation _get_alias_relation(
adr2 = ptr_node;
}
unsigned mode_size = get_mode_size_bytes(mode1);
if (get_mode_size_bytes(mode2) > mode_size) {
mode_size = get_mode_size_bytes(mode2);
unsigned type_size = get_type_size_bytes(type1);
if (get_type_size_bytes(type2) > type_size) {
type_size = get_type_size_bytes(type2);
}
/* same base address -> compare offsets if possible.
* FIXME: type long is not sufficient for this task ...
*/
if (adr1 == adr2 && sym_offset1 == sym_offset2 && have_const_offsets) {
if ((unsigned long)labs(offset2 - offset1) >= mode_size)
if ((unsigned long)labs(offset2 - offset1) >= type_size)
return ir_no_alias;
else
return ir_sure_alias;
......@@ -650,7 +652,7 @@ static ir_alias_relation _get_alias_relation(
tv = get_Const_tarval(base2);
offset2 += get_tarval_long(tv);
if ((unsigned long)labs(offset2 - offset1) >= mode_size)
if ((unsigned long)labs(offset2 - offset1) >= type_size)
return ir_no_alias;
else
return ir_sure_alias;
......@@ -662,24 +664,31 @@ static ir_alias_relation _get_alias_relation(
ir_alias_relation rel;
if (options & aa_opt_byte_type_may_alias) {
if (get_mode_size_bits(mode1) == 8 || get_mode_size_bits(mode2) == 8) {
/* One of the modes address a byte. Assume a ir_may_alias and leave
if (get_type_size_bytes(type1) == 1 || get_type_size_bytes(type2) == 1) {
/* One of the types address a byte. Assume a ir_may_alias and leave
the type based check. */
goto leave_type_based_alias;
}
}
/* cheap check: If the mode sizes did not match, the types MUST be different */
if (get_mode_size_bits(mode1) != get_mode_size_bits(mode2))
return ir_no_alias;
/* cheap test: if only one is a reference mode, no alias */
if (mode_is_reference(mode1) != mode_is_reference(mode2))
/* 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;
/* cheap test: if arithmetic is different, no alias */
if (get_mode_arithmetic(mode1) != get_mode_arithmetic(mode2))
/* cheap test: if only one is a reference type, no alias */
if (is_Pointer_type(type1) != is_Pointer_type(type2))
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);
/* cheap test: if arithmetic is different, no alias */
if (get_mode_arithmetic(mode1) != get_mode_arithmetic(mode2))
return ir_no_alias;
}
/* try rule R5 */
rel = different_types(orig_adr1, orig_adr2);
if (rel != ir_may_alias)
......@@ -689,7 +698,7 @@ leave_type_based_alias:;
/* do we have a language specific memory disambiguator? */
if (language_disambuigator != NULL) {
ir_alias_relation rel = language_disambuigator(orig_adr1, mode1, orig_adr2, mode2);
ir_alias_relation rel = language_disambuigator(orig_adr1, type1, orig_adr2, type2);
if (rel != ir_may_alias)
return rel;
}
......@@ -699,10 +708,10 @@ leave_type_based_alias:;
}
ir_alias_relation get_alias_relation(
const ir_node *const adr1, const ir_mode *const mode1,
const ir_node *const adr2, const ir_mode *const mode2)
const ir_node *const adr1, const ir_type *const type1,
const ir_node *const adr2, const ir_type *const type2)
{
ir_alias_relation rel = _get_alias_relation(adr1, mode1, adr2, mode2);
ir_alias_relation rel = _get_alias_relation(adr1, type1, adr2, type2);
DB((dbg, LEVEL_1, "alias(%+F, %+F) = %s\n", adr1, adr2, get_ir_alias_relation_name(rel)));
return rel;
}
......@@ -718,9 +727,9 @@ static set *result_cache = NULL;
/** An entry in the relation cache. */
typedef struct mem_disambig_entry {
const ir_node *adr1; /**< The first address. */
const ir_mode *mode1; /**< The first address mode. */
const ir_type *type1; /**< The first address type. */
const ir_node *adr2; /**< The second address. */
const ir_mode *mode2; /**< The second address mode. */
const ir_type *type2; /**< The second address type. */
ir_alias_relation result; /**< The alias relation result. */
} mem_disambig_entry;
......@@ -735,7 +744,7 @@ static int cmp_mem_disambig_entry(const void *elt, const void *key, size_t size)
const mem_disambig_entry *p1 = (const mem_disambig_entry*) elt;
const mem_disambig_entry *p2 = (const mem_disambig_entry*) key;
return p1->adr1 == p2->adr1 && p1->adr2 == p2->adr2 &&
p1->mode1 == p2->mode1 && p1->mode2 == p2->mode2;
p1->type1 == p2->type1 && p1->type2 == p2->type2;
}
void mem_disambig_init(void)
......@@ -744,8 +753,8 @@ void mem_disambig_init(void)
}
ir_alias_relation get_alias_relation_ex(
const ir_node *adr1, const ir_mode *mode1,
const ir_node *adr2, const ir_mode *mode2)
const ir_node *adr1, const ir_type *type1,
const ir_node *adr2, const ir_type *type2)
{
ir_fprintf(stderr, "%+F <-> %+F\n", adr1, adr2);
......@@ -761,13 +770,13 @@ ir_alias_relation get_alias_relation_ex(
mem_disambig_entry key;
key.adr1 = adr1;
key.adr2 = adr2;
key.mode1 = mode1;
key.mode2 = mode2;
key.type1 = type1;
key.type2 = type2;
mem_disambig_entry *entry = set_find(mem_disambig_entry, result_cache, &key, sizeof(key), HASH_ENTRY(adr1, adr2));
if (entry != NULL)
return entry->result;
key.result = get_alias_relation(adr1, mode1, adr2, mode2);
key.result = get_alias_relation(adr1, type1, adr2, type2);
(void)set_insert(mem_disambig_entry, result_cache, &key, sizeof(key), HASH_ENTRY(adr1, adr2));
return key.result;
......
......@@ -16,6 +16,7 @@
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
#include "type_t.h"
#include "iropt_t.h"
#include "ircons_t.h"
#include "irgmod.h"
......@@ -673,8 +674,9 @@ static unsigned follow_Mem_chain(ir_node *load, ir_node *curr)
/* check if we can pass through this store */
ir_alias_relation rel = get_alias_relation(
get_Store_ptr(pred),
get_irn_mode(get_Store_value(pred)),
ptr, load_mode);
get_type_for_mode(get_irn_mode(get_Store_value(pred))),
ptr,
get_type_for_mode(load_mode));
/* if the might be an alias, we cannot pass this Store */
if (rel != ir_no_alias)
break;
......@@ -930,16 +932,19 @@ static unsigned follow_Mem_chain_for_Store(ir_node *store, ir_node *curr, bool h
/* check if we can pass through this store */
ir_alias_relation rel = get_alias_relation(
get_Store_ptr(pred),
get_irn_mode(get_Store_value(pred)),
ptr, mode);
get_type_for_mode(get_irn_mode(get_Store_value(pred))),
ptr,
get_type_for_mode(mode));
/* if the might be an alias, we cannot pass this Store */
if (rel != ir_no_alias)
break;
pred = skip_Proj(get_Store_mem(pred));
} else if (is_Load(pred)) {
ir_alias_relation rel = get_alias_relation(
get_Load_ptr(pred), get_Load_mode(pred),
ptr, mode);
get_Load_ptr(pred),
get_type_for_mode(get_Load_mode(pred)),
ptr,
get_type_for_mode(mode));
if (rel != ir_no_alias)
break;
......@@ -1541,8 +1546,9 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env)
if (is_Store(other)) {
ir_alias_relation rel = get_alias_relation(
get_Store_ptr(other),
get_irn_mode(get_Store_value(other)),
ptr, load_mode);
get_type_for_mode(get_irn_mode(get_Store_value(other))),
ptr,
get_type_for_mode(load_mode));
/* if the might be an alias, we cannot pass this Store */
if (rel != ir_no_alias)
break;
......
......@@ -24,6 +24,7 @@
#include "raw_bitset.h"
#include "debug.h"
#include "error.h"
#include "type_t.h"
/* maximum number of output Proj's */
#define MAX_PROJ ((long)pn_Load_max > (long)pn_Store_max ? (long)pn_Load_max : (long)pn_Store_max)
......@@ -988,8 +989,8 @@ 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, value->mode,
op->value.address, op->value.mode)) {
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))) {
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));
......
......@@ -24,6 +24,7 @@
#include "irdump.h"
#include "irflag_t.h"
#include "iredges.h"
#include "type_t.h"
typedef struct parallelize_info
{
......@@ -58,7 +59,7 @@ static void parallelize_load(parallelize_info *pi, ir_node *irn)
ir_node *org_ptr = pi->origin_ptr;
ir_mode *store_mode = get_irn_mode(get_Store_value(pred));
ir_node *store_ptr = get_Store_ptr(pred);
if (get_alias_relation(org_ptr, org_mode, store_ptr, store_mode) == ir_no_alias) {
if (get_alias_relation(org_ptr, get_type_for_mode(org_mode), store_ptr, get_type_for_mode(store_mode)) == ir_no_alias) {
ir_node *mem = get_Store_mem(pred);
ir_nodeset_insert(&pi->user_mem, irn);
parallelize_load(pi, mem);
......@@ -95,7 +96,7 @@ static void parallelize_store(parallelize_info *pi, ir_node *irn)
ir_node *org_ptr = pi->origin_ptr;
ir_mode *load_mode = get_Load_mode(pred);
ir_node *load_ptr = get_Load_ptr(pred);
if (get_alias_relation(org_ptr, org_mode, load_ptr, load_mode) == ir_no_alias) {
if (get_alias_relation(org_ptr, get_type_for_mode(org_mode), load_ptr, get_type_for_mode(load_mode)) == ir_no_alias) {
ir_node *mem = get_Load_mem(pred);
ir_nodeset_insert(&pi->user_mem, irn);
parallelize_store(pi, mem);
......@@ -107,7 +108,7 @@ static void parallelize_store(parallelize_info *pi, ir_node *irn)
ir_node *org_ptr = pi->origin_ptr;
ir_mode *store_mode = get_irn_mode(get_Store_value(pred));
ir_node *store_ptr = get_Store_ptr(pred);
if (get_alias_relation(org_ptr, org_mode, store_ptr, store_mode) == ir_no_alias) {
if (get_alias_relation(org_ptr, get_type_for_mode(org_mode), store_ptr, get_type_for_mode(store_mode)) == ir_no_alias) {
ir_node *mem;
ir_nodeset_insert(&pi->user_mem, irn);
......
Supports Markdown
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