+/**
+ * Check if an offset is a constant and these constant is bigger or equal
+ * than a given size.
+ */
+static int check_const_offset(ir_node *offset, int size) {
+ ir_mode *mode = get_irn_mode(offset);
+
+ /* ok, we found an offset, check for constant */
+ if (is_Const(offset) && mode_is_int(mode)) {
+ tarval *tv = new_tarval_from_long(size, mode);
+
+ /* size <= offset ? */
+ if (tarval_cmp(tv, get_Const_tarval(offset)) & (pn_Cmp_Eq|pn_Cmp_Lt))
+ return 1;
+ }
+ return 0;
+} /* check_const_offset */
+
+/**
+ * Check if we can determine that the two pointers always have an offset bigger then size
+ */
+static ir_alias_relation _different_pointer(ir_node *adr1, ir_node *adr2, int size) {
+ int found = 0;
+
+ if (is_Add(adr1)) {
+ /* first address is the result of a pointer addition */
+ ir_node *l1 = get_Add_left(adr1);
+ ir_node *r1 = get_Add_right(adr1);
+
+ if (l1 == adr2) {
+ found = check_const_offset(r1, size);
+ } else if (r1 == adr2) {
+ found = check_const_offset(l1, size);
+ } else if (is_Add(adr2)) {
+ /* second address is the result of a pointer addition */
+ ir_node *l2 = get_Add_left(adr2);
+ ir_node *r2 = get_Add_right(adr2);
+
+ if (l1 == l2) {
+ return _different_pointer(r1, r2, size);
+ } else if (l1 == r2) {
+ return _different_pointer(r1, l2, size);
+ } else if (r1 == l2) {
+ return _different_pointer(l1, r2, size);
+ } else if (r1 == r2) {
+ return _different_pointer(l1, l2, size);
+ }
+ }
+ } else if (is_Add(adr2)) {
+ /* second address is the result of a pointer addition */
+ ir_node *l2 = get_Add_left(adr2);
+ ir_node *r2 = get_Add_right(adr2);
+
+ if (l2 == adr1) {
+ found = check_const_offset(r2, size);
+ } else if (r2 == adr1) {
+ found = check_const_offset(l2, size);
+ }
+ } else {
+ return different_index(adr1, adr2, size);
+ }
+ return found ? no_alias : may_alias;
+} /* _different_pointer */
+
+/**
+ * Check if we can determine that the two pointers always have an offset bigger then the maximum size of mode1, mode2
+ */
+static ir_alias_relation different_pointer(ir_node *adr1, ir_mode *mode1, ir_node *adr2, ir_mode *mode2) {
+ int size = get_mode_size_bytes(mode1);
+ int n = get_mode_size_bytes(mode2);
+
+ if (n > size)
+ size = n;
+ return _different_pointer(adr1, adr2, size);
+} /* different_pointer */
+
+/**
+ * Returns non-zero if a node is a routine parameter.
+ *
+ * @param node the node to test
+ */
+static int is_arg_Proj(ir_node *node) {
+ if (! is_Proj(node))
+ return 0;
+ node = get_Proj_pred(node);
+ if (! is_Proj(node))
+ return 0;
+ return pn_Start_T_args == get_Proj_proj(node) && is_Start(get_Proj_pred(node));
+} /* is_arg_Proj */
+
+/**
+ * Returns true if an address represents a global variable.
+ */
+static INLINE int is_global_var(ir_node *irn) {
+ return is_SymConst(irn) && get_SymConst_kind(irn) == symconst_addr_ent;
+} /* is_global_var */
+