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)
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;
}
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. */
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);
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");
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;
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
{
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)
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. */
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. */
}
else
DECL_STATIC_CHAIN (decl) = 1;
+ chain_count += DECL_STATIC_CHAIN (decl);
}
/* Walk the functions and perform transformations. Note that these
iter_count = 0;
do
{
- any_changed = false;
+ old_chain_count = chain_count;
+ chain_count = 0;
iter_count++;
if (dump_file && (dump_flags & TDF_DETAILS))
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);
}
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;
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);
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);
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);
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);
}
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;
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;
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);
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);
}
}
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;