#include "irnode_t.h"
#include "irgraph_t.h"
#include "irprog_t.h"
+#include "irmemory_t.h"
#include "irmemory.h"
#include "irflag.h"
#include "hashptr.h"
/**
* Check if a given Const node is greater or equal a given size.
*
+ * @param cns a Const node
+ * @param size a integer size
+ *
* @return ir_no_alias if the Const is greater, ir_may_alias else
*/
static ir_alias_relation check_const(ir_node *cns, int size) {
/**
* Treat idx1 and idx2 as integer indexes and check if they differ always more than size.
*
+ * @param idx1 a node representing the first index
+ * @param idx2 a node representing the second index
+ * @param size an integer size
+ *
* @return ir_sure_alias iff idx1 == idx2
* ir_no_alias iff they ALWAYS differ more than size
* ir_may_alias else
if (tp1 != tp2) {
#if 0
- if (is_Pointer_type(tp1) && is_Pointer_type(tp2)) {
- /* do deref until no pointer types are found */
- do {
- tp1 = get_pointer_points_to_type(tp1);
- tp2 = get_pointer_points_to_type(tp2);
- } while (is_Pointer_type(tp1) && is_Pointer_type(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);
}
#endif
/**
* Determine the alias relation between two addresses.
+ *
+ * @param irg the graph of both memory operations
+ * @param addr1 pointer address of the first memory operation
+ * @param mode1 the mode 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
+ *
+ * @return found memory relation
*/
static ir_alias_relation _get_alias_relation(
ir_graph *irg,
have_const_offsets = 1;
while (is_Add(adr1)) {
ir_node *add_right = get_Add_right(adr1);
- if (is_Const(add_right)) {
+ if (is_Const(add_right) && !mode_is_reference(get_irn_mode(add_right))) {
tarval *tv = get_Const_tarval(add_right);
offset1 += get_tarval_long(tv);
adr1 = get_Add_left(adr1);
}
while (is_Add(adr2)) {
ir_node *add_right = get_Add_right(adr2);
- if (is_Const(add_right)) {
+ if (is_Const(add_right) && !mode_is_reference(get_irn_mode(add_right))) {
tarval *tv = get_Const_tarval(add_right);
offset2 += get_tarval_long(tv);
adr2 = get_Add_left(adr2);
adr1 = skip_Bitfield_Sels(adr1);
adr2 = skip_Bitfield_Sels(adr2);
- /* skip sels */
+ /* skip Sels */
base1 = adr1;
base2 = adr2;
ent1 = NULL;
base2 = find_base_adr(adr2, &ent2);
}
- /* same base address -> compare sel entities */
+ /* same base address -> compare Sel entities */
if (base1 == base2 && ent1 != NULL && ent2 != NULL) {
if (ent1 != ent2)
return ir_no_alias;
return different_sel_offsets(adr1, adr2);
}
- /* Type based alias analysis */
+ class1 = classify_pointer(irg, base1, ent1);
+ class2 = classify_pointer(irg, base2, ent2);
+
+ if (class1 == ir_sc_pointer) {
+ if (class2 & ir_sc_modifier_nottaken) {
+ /* a pointer and an object whose objects was never taken */
+ return ir_no_alias;
+ }
+ } else if (class2 == ir_sc_pointer) {
+ if (class1 & ir_sc_modifier_nottaken) {
+ /* a pointer and an object whose objects was never taken */
+ return ir_no_alias;
+ }
+ } else if (class1 != class2) {
+ /* two objects from different memory spaces */
+ return ir_no_alias;
+ } else {
+ /* both classes are equal */
+ if (class1 == ir_sc_globalvar) {
+ ir_entity *entity1 = get_SymConst_entity(base1);
+ ir_entity *entity2 = get_SymConst_entity(base2);
+ if (entity1 != entity2)
+ return ir_no_alias;
+
+ /* for some reason CSE didn't happen yet for the 2 SymConsts... */
+ return ir_may_alias;
+ }
+ }
+
+ /* Type based alias analysis */
if (options & aa_opt_type_based) {
ir_alias_relation rel;
if (mode_is_reference(mode1) != mode_is_reference(mode2))
return ir_no_alias;
+ /* 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)
leave_type_based_alias:;
}
- class1 = classify_pointer(irg, base1, ent1);
- class2 = classify_pointer(irg, base2, ent2);
-
- if (class1 == ir_sc_pointer) {
- if (class2 & ir_sc_modifier_nottaken) {
- return ir_no_alias;
- } else {
- return ir_may_alias;
- }
- } else if (class2 == ir_sc_pointer) {
- if (class1 & ir_sc_modifier_nottaken) {
- return ir_no_alias;
- } else {
- return ir_may_alias;
- }
- }
-
- if (class1 != class2) {
- return ir_no_alias;
- }
-
- if (class1 == ir_sc_globalvar) {
- ir_entity *entity1 = get_SymConst_entity(base1);
- ir_entity *entity2 = get_SymConst_entity(base2);
- if (entity1 != entity2)
- return ir_no_alias;
-
- /* for some reason CSE didn't happen yet for the 2 SymConsts... */
- return ir_may_alias;
- }
-
/* do we have a language specific memory disambiguator? */
if (language_disambuigator) {
ir_alias_relation rel = (*language_disambuigator)(irg, orig_adr1, mode1, orig_adr2, mode2);
return;
}
}
- panic("invalid initialzier found");
-}
+ panic("invalid initializer found");
+} /* check_initializer_nodes */
/**
- * Mark all entities used in the initializer for the given entity as address taken
+ * Mark all entities used in the initializer for the given entity as address taken.
+ *
+ * @param ent the entity
*/
static void check_initializer(ir_entity *ent) {
ir_node *n;
if (get_entity_variability(ent) == variability_uninitialized)
return;
- /* Beware: Methods initialized with "themself". This does not count as a taken
- address. */
+ /* Beware: Methods are always initialized with "themself". This does not
+ count as a taken address. */
if (is_Method_type(get_entity_type(ent)))
return;
/**
- * Mark all entities used in initializers as address taken
+ * Mark all entities used in initializers as address taken.
+ *
+ * @param tp a compound type
*/
static void check_initializers(ir_type *tp) {
int i;
#ifdef DEBUG_libfirm
/**
* Print the address taken state of all entities of a given type for debugging.
+ *
+ * @param tp a compound type
*/
static void print_address_taken_state(ir_type *tp) {
int i;
static void analyse_irp_globals_address_taken(void) {
int i;
- FIRM_DBG_REGISTER(dbg, "firm.ana.irmemory");
-
init_taken_flag(get_glob_type());
init_taken_flag(get_tls_type());
analyse_irp_globals_address_taken();
} /* assure_irp_globals_address_taken_computed */
+void firm_init_memory_disambiguator(void) {
+ FIRM_DBG_REGISTER(dbg, "firm.ana.irmemory");
+}
+
#include <adt/pmap.h>
#include "typerep.h"
/**
* Clone a method type if not already cloned.
+ *
+ * @param tp the type to clone
*/
static ir_type *clone_type_and_cache(ir_type *tp) {
static ident *prefix = NULL;
} /* clone_type_and_cache */
/**
- * Copy the calling conventions from the entities to the call type.
+ * Walker: clone all call types of Calls to methods having the
+ * mtp_property_private property set.
*/
static void update_calls_to_private(ir_node *call, void *env) {
(void) env;