+/**
+ * returns a entity if the address ptr points to a constant one.
+ */
+static entity *find_constant_entity(ir_node *ptr)
+{
+ for (;;) {
+ ir_op *op = get_irn_op(ptr);
+
+ if (op == op_SymConst && (get_SymConst_kind(ptr) == symconst_addr_ent)) {
+ return get_SymConst_entity(ptr);
+ }
+ else if (op == op_Sel) {
+ entity *ent = get_Sel_entity(ptr);
+ type *tp = get_entity_owner(ent);
+
+ if (is_Array_type(tp)) {
+ /* check bounds */
+ int i, n;
+
+ for (i = 0, n = get_Sel_n_indexs(ptr); i < n; ++i) {
+ ir_node *bound;
+ tarval *tlower, *tupper;
+ ir_node *index = get_Sel_index(ptr, i);
+ tarval *tv = computed_value(index);
+
+ /* check if the index is constant */
+ if (tv == tarval_bad)
+ return NULL;
+
+ bound = get_array_lower_bound(tp, i);
+ tlower = computed_value(bound);
+ bound = get_array_upper_bound(tp, i);
+ tupper = computed_value(bound);
+
+ if (tlower == tarval_bad || tupper == tarval_bad)
+ return NULL;
+
+ if (tarval_cmp(tv, tlower) & pn_Cmp_Lt)
+ return NULL;
+ if (tarval_cmp(tupper, tv) & pn_Cmp_Lt)
+ return NULL;
+
+ /* ok, bounds check finished */
+ }
+ }
+
+ /* try next */
+ ptr = get_Sel_ptr(ptr);
+ }
+ else
+ return NULL;
+ }
+}
+