X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-nested.c;h=1b26eca5a2a2cfb08978c4ec5859031489ebafd1;hb=dab866f9b5afc58f05be6ea553163865b7c5cabc;hp=db704b7905578f6b922e48c1a9c7b0abbdf33aa2;hpb=182cf5a9a415f31df0f9a10e46faed1221484a35;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index db704b79055..1b26eca5a2a 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -148,7 +148,7 @@ create_tmp_var_for (struct nesting_info *info, tree type, const char *prefix) 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) @@ -184,7 +184,7 @@ build_addr (tree exp, tree context) 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; } @@ -198,11 +198,11 @@ insert_field_into_struct (tree type, tree field) 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. */ @@ -486,7 +486,7 @@ get_trampoline_type (struct nesting_info *info) align = STACK_BOUNDARY; } - t = build_index_type (build_int_cst (NULL_TREE, size - 1)); + t = build_index_type (size_int (size - 1)); t = build_array_type (char_type_node, t); t = build_decl (DECL_SOURCE_LOCATION (info->context), FIELD_DECL, get_identifier ("__data"), t); @@ -561,7 +561,7 @@ get_nl_goto_field (struct nesting_info *info) size = size + 1; type = build_array_type - (type, build_index_type (build_int_cst (NULL_TREE, size))); + (type, build_index_type (size_int (size))); field = make_node (FIELD_DECL); DECL_NAME (field) = get_identifier ("__nl_goto_buf"); @@ -693,12 +693,12 @@ walk_all_functions (walk_stmt_fn callback_stmt, walk_tree_fn callback_op, static bool check_for_nested_with_variably_modified (tree fndecl, tree orig_fndecl) { - struct cgraph_node *cgn = cgraph_node (fndecl); + struct cgraph_node *cgn = cgraph_get_node (fndecl); tree arg; 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; @@ -875,7 +875,7 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl) 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 @@ -1202,7 +1202,7 @@ note_nonlocal_block_vlas (struct nesting_info *info, tree block) { 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) @@ -1367,7 +1367,7 @@ get_local_debug_decl (struct nesting_info *info, tree decl, tree field) 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. */ @@ -2070,9 +2070,8 @@ convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p, 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. */ @@ -2088,6 +2087,7 @@ convert_all_function_calls (struct nesting_info *root) } else DECL_STATIC_CHAIN (decl) = 1; + chain_count += DECL_STATIC_CHAIN (decl); } /* Walk the functions and perform transformations. Note that these @@ -2100,7 +2100,8 @@ convert_all_function_calls (struct nesting_info *root) iter_count = 0; do { - any_changed = false; + old_chain_count = chain_count; + chain_count = 0; iter_count++; if (dump_file && (dump_flags & TDF_DETAILS)) @@ -2109,22 +2110,16 @@ convert_all_function_calls (struct nesting_info *root) 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); } @@ -2196,19 +2191,22 @@ remap_vla_decls (tree block, struct nesting_info *root) 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; @@ -2217,18 +2215,23 @@ remap_vla_decls (tree block, struct nesting_info *root) 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; + tree newt, context; + void **slot; - t = 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) + 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); @@ -2239,6 +2242,15 @@ remap_vla_decls (tree block, struct nesting_info *root) 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); @@ -2247,13 +2259,13 @@ remap_vla_decls (tree block, struct nesting_info *root) 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); @@ -2308,11 +2320,11 @@ finalize_nesting_tree_1 (struct nesting_info *root) 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); + adjust = &DECL_CHAIN (*adjust)) + gcc_assert (DECL_CHAIN (*adjust)); + *adjust = DECL_CHAIN (*adjust); - TREE_CHAIN (root->frame_decl) = NULL_TREE; + DECL_CHAIN (root->frame_decl) = NULL_TREE; declare_vars (root->frame_decl, gimple_seq_first_stmt (gimple_body (context)), true); } @@ -2323,7 +2335,7 @@ finalize_nesting_tree_1 (struct nesting_info *root) 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; @@ -2428,7 +2440,7 @@ finalize_nesting_tree_1 (struct nesting_info *root) 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; @@ -2443,7 +2455,7 @@ finalize_nesting_tree_1 (struct nesting_info *root) 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); @@ -2511,13 +2523,13 @@ finalize_nesting_tree (struct nesting_info *root) static void unnest_nesting_tree_1 (struct nesting_info *root) { - struct cgraph_node *node = cgraph_node (root->context); + struct cgraph_node *node = cgraph_get_node (root->context); /* For nested functions update the cgraph to reflect unnesting. We also delay finalizing of these functions up to this point. */ if (node->origin) { - cgraph_unnest_node (cgraph_node (root->context)); + cgraph_unnest_node (node); cgraph_finalize_function (root->context, true); } } @@ -2571,7 +2583,7 @@ lower_nested_functions (tree fndecl) struct nesting_info *root; /* If there are no nested functions, there's nothing to do. */ - cgn = cgraph_node (fndecl); + cgn = cgraph_get_node (fndecl); if (!cgn->nested) return;