Mercurial > hg > CbC > CbC_gcc
diff gcc/tree-nested.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/tree-nested.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/tree-nested.c Tue Mar 22 17:18:12 2011 +0900 @@ -31,7 +31,7 @@ #include "tree-iterator.h" #include "tree-flow.h" #include "cgraph.h" -#include "expr.h" +#include "expr.h" /* FIXME: For STACK_SAVEAREA_MODE and SAVE_NONLOCAL. */ #include "langhooks.h" #include "pointer-set.h" @@ -84,6 +84,7 @@ struct pointer_map_t *field_map; struct pointer_map_t *var_map; + struct pointer_set_t *mem_refs; bitmap suppress_expansion; tree context; @@ -147,7 +148,7 @@ tmp_var = create_tmp_var_raw (type, prefix); DECL_CONTEXT (tmp_var) = info->context; - TREE_CHAIN (tmp_var) = info->new_local_var_chain; + DECL_CHAIN (tmp_var) = info->new_local_var_chain; DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1; if (TREE_CODE (type) == COMPLEX_TYPE || TREE_CODE (type) == VECTOR_TYPE) @@ -183,7 +184,7 @@ way the properties are for the ADDR_EXPR are computed properly. */ save_context = current_function_decl; current_function_decl = context; - retval = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp); + retval = build_fold_addr_expr (exp); current_function_decl = save_context; return retval; } @@ -197,11 +198,11 @@ DECL_CONTEXT (field) = type; - for (p = &TYPE_FIELDS (type); *p ; p = &TREE_CHAIN (*p)) + for (p = &TYPE_FIELDS (type); *p ; p = &DECL_CHAIN (*p)) if (DECL_ALIGN (field) >= DECL_ALIGN (*p)) break; - TREE_CHAIN (field) = *p; + DECL_CHAIN (field) = *p; *p = field; /* Set correct alignment for frame struct type. */ @@ -697,7 +698,7 @@ for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) { - for (arg = DECL_ARGUMENTS (cgn->decl); arg; arg = TREE_CHAIN (arg)) + for (arg = DECL_ARGUMENTS (cgn->decl); arg; arg = DECL_CHAIN (arg)) if (variably_modified_type_p (TREE_TYPE (arg), orig_fndecl)) return true; @@ -717,6 +718,7 @@ 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 @@ { 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 @@ { 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 @@ 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), @@ -873,7 +875,7 @@ DECL_HAS_VALUE_EXPR_P (new_decl) = 1; *slot = new_decl; - TREE_CHAIN (new_decl) = info->debug_var_chain; + DECL_CHAIN (new_decl) = info->debug_var_chain; info->debug_var_chain = new_decl; if (!optimize @@ -927,7 +929,7 @@ 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); } } @@ -1200,7 +1202,7 @@ { tree var; - for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var)) + for (var = BLOCK_VARS (block); var; var = DECL_CHAIN (var)) if (TREE_CODE (var) == VAR_DECL && variably_modified_type_p (TREE_TYPE (var), NULL) && DECL_HAS_VALUE_EXPR_P (var) @@ -1365,7 +1367,7 @@ DECL_HAS_VALUE_EXPR_P (new_decl) = 1; *slot = new_decl; - TREE_CHAIN (new_decl) = info->debug_var_chain; + DECL_CHAIN (new_decl) = info->debug_var_chain; info->debug_var_chain = new_decl; /* Do not emit debug info twice. */ @@ -1498,6 +1500,21 @@ 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 @@ -2053,9 +2070,8 @@ static void convert_all_function_calls (struct nesting_info *root) { + unsigned int chain_count = 0, old_chain_count, iter_count; struct nesting_info *n; - int iter_count; - bool any_changed; /* First, optimistically clear static_chain for all decls that haven't used the static chain already for variable access. */ @@ -2071,6 +2087,7 @@ } else DECL_STATIC_CHAIN (decl) = 1; + chain_count += DECL_STATIC_CHAIN (decl); } /* Walk the functions and perform transformations. Note that these @@ -2083,7 +2100,8 @@ iter_count = 0; do { - any_changed = false; + old_chain_count = chain_count; + chain_count = 0; iter_count++; if (dump_file && (dump_flags & TDF_DETAILS)) @@ -2092,22 +2110,16 @@ FOR_EACH_NEST_INFO (n, root) { tree decl = n->context; - bool old_static_chain = DECL_STATIC_CHAIN (decl); - walk_function (convert_tramp_reference_stmt, convert_tramp_reference_op, n); walk_function (convert_gimple_call, NULL, n); - - /* If a call to another function created the use of a chain - within this function, we'll have to continue iteration. */ - if (!old_static_chain && DECL_STATIC_CHAIN (decl)) - any_changed = true; + chain_count += DECL_STATIC_CHAIN (decl); } } - while (any_changed); + while (chain_count != old_chain_count); if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "convert_all_function_calls iterations: %d\n\n", + fprintf (dump_file, "convert_all_function_calls iterations: %u\n\n", iter_count); } @@ -2179,19 +2191,22 @@ subblock = BLOCK_CHAIN (subblock)) remap_vla_decls (subblock, root); - for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var)) - { - if (TREE_CODE (var) == VAR_DECL - && variably_modified_type_p (TREE_TYPE (var), NULL) - && DECL_HAS_VALUE_EXPR_P (var)) - { - type = TREE_TYPE (var); - val = DECL_VALUE_EXPR (var); - if (walk_tree (&type, contains_remapped_vars, root, NULL) != NULL - || walk_tree (&val, contains_remapped_vars, root, NULL) != NULL) - break; - } - } + for (var = BLOCK_VARS (block); var; var = DECL_CHAIN (var)) + if (TREE_CODE (var) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (var)) + { + val = DECL_VALUE_EXPR (var); + type = TREE_TYPE (var); + + if (!(TREE_CODE (val) == INDIRECT_REF + && TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL + && variably_modified_type_p (type, NULL))) + continue; + + if (pointer_map_contains (root->var_map, TREE_OPERAND (val, 0)) + || walk_tree (&type, contains_remapped_vars, root, NULL)) + break; + } + if (var == NULL_TREE) return; @@ -2200,18 +2215,23 @@ id.cb.decl_map = pointer_map_create (); id.root = root; - for (; var; var = TREE_CHAIN (var)) - if (TREE_CODE (var) == VAR_DECL - && variably_modified_type_p (TREE_TYPE (var), NULL) - && DECL_HAS_VALUE_EXPR_P (var)) + for (; var; var = DECL_CHAIN (var)) + if (TREE_CODE (var) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (var)) { struct nesting_info *i; - tree newt, t, context; - - t = type = TREE_TYPE (var); + tree newt, context; + void **slot; + val = DECL_VALUE_EXPR (var); - if (walk_tree (&type, contains_remapped_vars, root, NULL) == NULL - && walk_tree (&val, contains_remapped_vars, root, NULL) == NULL) + type = TREE_TYPE (var); + + if (!(TREE_CODE (val) == INDIRECT_REF + && TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL + && variably_modified_type_p (type, NULL))) + continue; + + slot = pointer_map_contains (root->var_map, TREE_OPERAND (val, 0)); + if (!slot && !walk_tree (&type, contains_remapped_vars, root, NULL)) continue; context = decl_function_context (var); @@ -2222,6 +2242,15 @@ if (i == NULL) continue; + /* Fully expand value expressions. This avoids having debug variables + only referenced from them and that can be swept during GC. */ + if (slot) + { + tree t = (tree) *slot; + gcc_assert (DECL_P (t) && DECL_HAS_VALUE_EXPR_P (t)); + val = build1 (INDIRECT_REF, TREE_TYPE (val), DECL_VALUE_EXPR (t)); + } + id.cb.src_fn = i->context; id.cb.dst_fn = i->context; id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context); @@ -2230,13 +2259,13 @@ while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt)) { newt = TREE_TYPE (newt); - t = TREE_TYPE (t); + type = TREE_TYPE (type); } if (TYPE_NAME (newt) && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL && DECL_ORIGINAL_TYPE (TYPE_NAME (newt)) - && newt != t - && TYPE_NAME (newt) == TYPE_NAME (t)) + && newt != type + && TYPE_NAME (newt) == TYPE_NAME (type)) TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb); walk_tree (&val, copy_tree_body_r, &id.cb, NULL); @@ -2247,6 +2276,15 @@ 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 @@ -2282,11 +2320,11 @@ expression get substituted in instantiate_virtual_regs(). */ for (adjust = &root->new_local_var_chain; *adjust != root->frame_decl; - adjust = &TREE_CHAIN (*adjust)) - gcc_assert (TREE_CHAIN (*adjust)); - *adjust = TREE_CHAIN (*adjust); - - TREE_CHAIN (root->frame_decl) = NULL_TREE; + adjust = &DECL_CHAIN (*adjust)) + gcc_assert (DECL_CHAIN (*adjust)); + *adjust = DECL_CHAIN (*adjust); + + DECL_CHAIN (root->frame_decl) = NULL_TREE; declare_vars (root->frame_decl, gimple_seq_first_stmt (gimple_body (context)), true); } @@ -2297,7 +2335,7 @@ if (root->any_parm_remapped) { tree p; - for (p = DECL_ARGUMENTS (context); p ; p = TREE_CHAIN (p)) + for (p = DECL_ARGUMENTS (context); p ; p = DECL_CHAIN (p)) { tree field, x, y; @@ -2402,7 +2440,7 @@ remap_vla_decls (DECL_INITIAL (root->context), root); for (debug_var = root->debug_var_chain; debug_var; - debug_var = TREE_CHAIN (debug_var)) + debug_var = DECL_CHAIN (debug_var)) if (variably_modified_type_p (TREE_TYPE (debug_var), NULL)) break; @@ -2417,7 +2455,7 @@ id.cb.decl_map = pointer_map_create (); id.root = root; - for (; debug_var; debug_var = TREE_CHAIN (debug_var)) + for (; debug_var; debug_var = DECL_CHAIN (debug_var)) if (variably_modified_type_p (TREE_TYPE (debug_var), NULL)) { tree type = TREE_TYPE (debug_var); @@ -2461,6 +2499,9 @@ 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 +2555,7 @@ 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; }