#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
ir_type *tp2 = get_entity_type(ent2);
if (tp1 != tp2) {
- 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));
+#if 0
+ /* 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
if (get_type_tpop(tp1) != get_type_tpop(tp2)) {
/* different type structure */
/**
* 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;
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 {
- return ir_may_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 {
- return ir_may_alias;
}
- }
-
- if (class1 != class2) {
+ } else if (class1 != class2) {
+ /* two objects from different memory spaces */
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;
+ } 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;
+ /* for some reason CSE didn't happen yet for the 2 SymConsts... */
+ return ir_may_alias;
+ }
}
- /* Type based alias analysis */
+ /* 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)
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;
ir_entity *ent = get_irg_entity(irg);
ir_address_taken_state state = get_entity_address_taken(ent);
+ /* If an entity is sticky, it might be called from external
+ places (like inline assembler), so do NOT mark it as private. */
if (get_entity_visibility(ent) == visibility_local &&
- state == ir_address_not_taken) {
+ state == ir_address_not_taken &&
+ get_entity_stickyness(ent) != stickyness_sticky) {
ir_type *mtp = get_entity_type(ent);
set_entity_additional_property(ent, mtp_property_private);