@@ -1562,6 +1562,57 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg,
jfunc->agg.by_ref = by_ref;
build_agg_jump_func_from_list (list, const_count, arg_offset, jfunc);
}
+ else if ((TREE_CODE (arg) == VAR_DECL)
+ && is_global_var (arg))
+ {
+ /* PR69708: Figure out aggregate jump-function with constant init
+ value. */
+ struct ipa_known_agg_contents_list *n, **p;
+ HOST_WIDE_INT offset = 0, size, max_size;
+ varpool_node *node = varpool_node::get (arg);
+ if (node
+ && DECL_INITIAL (node->decl)
+ && TREE_READONLY (node->decl)
+ && TREE_CODE (DECL_INITIAL (node->decl)) == CONSTRUCTOR)
+ {
+ tree exp = DECL_INITIAL (node->decl);
+ unsigned HOST_WIDE_INT ix;
+ tree field, val;
+ bool reverse;
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), ix, field, val)
+ {
+ bool already_there = false;
+ if (!field)
+ break;
+ get_ref_base_and_extent (field, &offset, &size,
+ &max_size, &reverse);
+ if (max_size == -1
+ || max_size != size)
+ break;
+ p = get_place_in_agg_contents_list (&list, offset, size,
+ &already_there);
+ if (!p)
+ break;
+ n = XALLOCA (struct ipa_known_agg_contents_list);
+ n->size = size;
+ n->offset = offset;
+ if (is_gimple_ip_invariant (val))
+ {
+ n->constant = val;
+ const_count++;
+ }
+ else
+ n->constant = NULL_TREE;
+ n->next = *p;
+ *p = n;
+ }
+ }
+ if (const_count)
+ {
+ jfunc->agg.by_ref = by_ref;
+ build_agg_jump_func_from_list (list, const_count, arg_offset, jfunc);
+ }
+ }
}
static tree