diff options
Diffstat (limited to 'gcc/tree-nested.c')
-rw-r--r-- | gcc/tree-nested.c | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index cd15307..db704b7 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -84,6 +84,7 @@ struct nesting_info struct pointer_map_t *field_map; struct pointer_map_t *var_map; + struct pointer_set_t *mem_refs; bitmap suppress_expansion; tree context; @@ -717,6 +718,7 @@ create_nesting_tree (struct cgraph_node *cgn) struct nesting_info *info = XCNEW (struct nesting_info); info->field_map = pointer_map_create (); info->var_map = pointer_map_create (); + info->mem_refs = pointer_set_create (); info->suppress_expansion = BITMAP_ALLOC (&nesting_info_bitmap_obstack); info->context = cgn->decl; @@ -758,7 +760,7 @@ get_static_chain (struct nesting_info *info, tree target_context, { tree field = get_chain_field (i); - x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); + x = build_simple_mem_ref (x); x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); x = init_tmp_var (info, x, gsi); } @@ -793,12 +795,12 @@ get_frame_field (struct nesting_info *info, tree target_context, { tree field = get_chain_field (i); - x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); + x = build_simple_mem_ref (x); x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); x = init_tmp_var (info, x, gsi); } - x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); + x = build_simple_mem_ref (x); } x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); @@ -841,16 +843,16 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl) for (i = info->outer; i->context != target_context; i = i->outer) { field = get_chain_field (i); - x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); + x = build_simple_mem_ref (x); x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); } - x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); + x = build_simple_mem_ref (x); } field = lookup_field_for_decl (i, decl, INSERT); x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); if (use_pointer_in_frame (decl)) - x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); + x = build_simple_mem_ref (x); /* ??? We should be remapping types as well, surely. */ new_decl = build_decl (DECL_SOURCE_LOCATION (decl), @@ -927,7 +929,7 @@ convert_nonlocal_reference_op (tree *tp, int *walk_subtrees, void *data) if (use_pointer_in_frame (t)) { x = init_tmp_var (info, x, &wi->gsi); - x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); + x = build_simple_mem_ref (x); } } @@ -1498,6 +1500,21 @@ convert_local_reference_op (tree *tp, int *walk_subtrees, void *data) wi->val_only = save_val_only; break; + case MEM_REF: + save_val_only = wi->val_only; + wi->val_only = true; + wi->is_lhs = false; + walk_tree (&TREE_OPERAND (t, 0), convert_local_reference_op, + wi, NULL); + /* We need to re-fold the MEM_REF as component references as + part of a ADDR_EXPR address are not allowed. But we cannot + fold here, as the chain record type is not yet finalized. */ + if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR + && !DECL_P (TREE_OPERAND (TREE_OPERAND (t, 0), 0))) + pointer_set_insert (info->mem_refs, tp); + wi->val_only = save_val_only; + break; + case VIEW_CONVERT_EXPR: /* Just request to look at the subtrees, leaving val_only and lhs untouched. This might actually be for !val_only + lhs, in which @@ -2247,6 +2264,15 @@ remap_vla_decls (tree block, struct nesting_info *root) pointer_map_destroy (id.cb.decl_map); } +/* Fold the MEM_REF *E. */ +static bool +fold_mem_refs (const void *e, void *data ATTRIBUTE_UNUSED) +{ + tree *ref_p = CONST_CAST2(tree *, const tree *, (const tree *)e); + *ref_p = fold (*ref_p); + return true; +} + /* Do "everything else" to clean up or complete state collected by the various walking passes -- lay out the types and decls, generate code to initialize the frame decl, store critical expressions in the @@ -2461,6 +2487,9 @@ finalize_nesting_tree_1 (struct nesting_info *root) root->debug_var_chain); } + /* Fold the rewritten MEM_REF trees. */ + pointer_set_traverse (root->mem_refs, fold_mem_refs, NULL); + /* Dump the translated tree function. */ if (dump_file) { @@ -2514,6 +2543,7 @@ free_nesting_tree (struct nesting_info *root) next = iter_nestinfo_next (node); pointer_map_destroy (node->var_map); pointer_map_destroy (node->field_map); + pointer_set_destroy (node->mem_refs); free (node); node = next; } |