Hi, an attached patch is an experiment on how much work it would take to move DECL_RESULT and DECL_ARGUMENTS, DECL_SAVED_TREE into struct function. The motivation is that middle-end threads them this way already - they are technically part local declarations and part of the body. Moving those pointer to struct function should save some memory and make things a bit cleaner.
The patch does only DECL_RESULT and bootstraps but won't pass fortran testsuite and I did not even look into Ada, yet. Main problem is that frontends tends to build the return values (and arguments) separately from body, since that is how code was structured. I wonder if there are any reason why this change won't work or if it seems undesirable for some reason? Other problem is (ab)use of these fileds by frontends for various reasons. C++ use result for namespace, obj-C for interfaces. I think we could/should replace those by FE specific data, but I am not quite certain how to do that. So any comments? Honza Index: c-family/c-ada-spec.c =================================================================== --- c-family/c-ada-spec.c (revision 211106) +++ c-family/c-ada-spec.c (working copy) @@ -1720,16 +1720,8 @@ dump_ada_template (pretty_printer *buffe { /* DECL_VINDEX is DECL_TEMPLATE_INSTANTIATIONS in this context. */ tree inst = DECL_VINDEX (t); - /* DECL_RESULT_FLD is DECL_TEMPLATE_RESULT in this context. */ - tree result = DECL_RESULT_FLD (t); int num_inst = 0; - /* Don't look at template declarations declaring something coming from - another file. This can occur for template friend declarations. */ - if (LOCATION_FILE (decl_sloc (result, false)) - != LOCATION_FILE (decl_sloc (t, false))) - return 0; - while (inst && inst != error_mark_node) { tree types = TREE_PURPOSE (inst); Index: c-family/cilk.c =================================================================== --- c-family/cilk.c (revision 211106) +++ c-family/cilk.c (working copy) @@ -322,12 +322,6 @@ create_cilk_helper_decl (struct wrapper_ the parent stack frame is stolen. */ DECL_UNINLINABLE (fndecl) = 1; - tree result_decl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, - void_type_node); - DECL_ARTIFICIAL (result_decl) = 0; - DECL_IGNORED_P (result_decl) = 1; - DECL_CONTEXT (result_decl) = fndecl; - DECL_RESULT (fndecl) = result_decl; return fndecl; } @@ -544,7 +538,14 @@ create_cilk_wrapper_body (tree stmt, str (modified) to the wrapped function. Return the wrapper and modified ARGS to the caller to generate a function call. */ fndecl = create_cilk_helper_decl (wd); - push_struct_function (fndecl); + + tree result_decl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, + void_type_node); + DECL_ARTIFICIAL (result_decl) = 0; + DECL_IGNORED_P (result_decl) = 1; + DECL_CONTEXT (result_decl) = fndecl; + + push_struct_function (fndecl, result_decl); if (wd->nested && (wd->type == CILK_BLOCK_FOR)) { gcc_assert (TREE_VALUE (wd->arglist) == NULL_TREE); Index: java/decl.c =================================================================== --- java/decl.c (revision 211106) +++ java/decl.c (working copy) @@ -1743,16 +1743,14 @@ tree build_result_decl (tree fndecl) { tree restype = TREE_TYPE (TREE_TYPE (fndecl)); - tree result = DECL_RESULT (fndecl); - if (! result) - { - result = build_decl (DECL_SOURCE_LOCATION (fndecl), - RESULT_DECL, NULL_TREE, restype); - DECL_ARTIFICIAL (result) = 1; - DECL_IGNORED_P (result) = 1; - DECL_CONTEXT (result) = fndecl; - DECL_RESULT (fndecl) = result; - } + tree result; + + result = build_decl (DECL_SOURCE_LOCATION (fndecl), + RESULT_DECL, NULL_TREE, restype); + DECL_ARTIFICIAL (result) = 1; + DECL_IGNORED_P (result) = 1; + DECL_CONTEXT (result) = fndecl; + return result; } @@ -1886,7 +1884,7 @@ finish_method (tree fndecl) if (DECL_STRUCT_FUNCTION (fndecl)) set_cfun (DECL_STRUCT_FUNCTION (fndecl)); else - allocate_struct_function (fndecl, false); + allocate_struct_function (fndecl, false, build_result_decl (fndecl)); cfun->function_end_locus = DECL_FUNCTION_LAST_LINE (fndecl); /* Defer inlining and expansion to the cgraph optimizers. */ Index: java/jcf-parse.c =================================================================== --- java/jcf-parse.c (revision 211106) +++ java/jcf-parse.c (working copy) @@ -1711,9 +1711,8 @@ java_emit_static_constructor (void) tree resdecl = build_decl (input_location, RESULT_DECL, NULL_TREE, void_type_node); DECL_ARTIFICIAL (resdecl) = 1; - DECL_RESULT (decl) = resdecl; current_function_decl = decl; - allocate_struct_function (decl, false); + allocate_struct_function (decl, false, resdecl); TREE_STATIC (decl) = 1; TREE_USED (decl) = 1; Index: java/expr.c =================================================================== --- java/expr.c (revision 211106) +++ java/expr.c (working copy) @@ -47,6 +47,7 @@ The Free Software Foundation is independ #include "tree-iterator.h" #include "target.h" #include "wide-int.h" +#include "function.h" static void flush_quick_stack (void); static void push_value (tree); @@ -2630,6 +2631,8 @@ build_jni_stub (tree method) tree klass = DECL_CONTEXT (method); klass = build_class_ref (klass); + allocate_struct_function (method, false, build_result_decl (method)); + gcc_assert (METHOD_NATIVE (method) && flag_jni); DECL_ARTIFICIAL (method) = 1; @@ -3138,6 +3141,7 @@ expand_byte_code (JCF *jcf, tree method) stack_pointer = 0; JCF_SEEK (jcf, DECL_CODE_OFFSET (method)); byte_ops = jcf->read_ptr; + allocate_struct_function (method, false, build_result_decl (method)); /* We make an initial pass of the line number table, to note which instructions have associated line number entries. */ Index: c/c-parser.c =================================================================== --- c/c-parser.c (revision 211106) +++ c/c-parser.c (working copy) @@ -13245,7 +13245,7 @@ c_parser_omp_declare_reduction (c_parser tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, reduc_id, default_function_type); current_function_decl = fndecl; - allocate_struct_function (fndecl, true); + allocate_struct_function (fndecl, true, NULL); push_scope (); tree stmt = push_stmt_list (); /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't Index: c/c-decl.c =================================================================== --- c/c-decl.c (revision 211106) +++ c/c-decl.c (working copy) @@ -1231,7 +1231,6 @@ pop_scope (void) DECL_CONTEXT (extp) = current_function_decl; if (TREE_CODE (p) == FUNCTION_DECL) { - DECL_RESULT (extp) = NULL_TREE; DECL_SAVED_TREE (extp) = NULL_TREE; DECL_STRUCT_FUNCTION (extp) = NULL; } @@ -2463,7 +2462,6 @@ merge_decls (tree newdecl, tree olddecl, if (!new_is_definition) { tree t; - DECL_RESULT (newdecl) = DECL_RESULT (olddecl); DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl); DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl); @@ -7871,7 +7869,6 @@ start_function (struct c_declspecs *decl tree attributes) { tree decl1, old_decl; - tree restype, resdecl; location_t loc; current_function_returns_value = 0; /* Assume, until we see it does. */ @@ -8075,12 +8072,6 @@ start_function (struct c_declspecs *decl push_scope (); declare_parm_level (); - restype = TREE_TYPE (TREE_TYPE (current_function_decl)); - resdecl = build_decl (loc, RESULT_DECL, NULL_TREE, restype); - DECL_ARTIFICIAL (resdecl) = 1; - DECL_IGNORED_P (resdecl) = 1; - DECL_RESULT (current_function_decl) = resdecl; - start_fname_decls (); return 1; @@ -8459,6 +8450,7 @@ store_parm_decls (void) { tree fndecl = current_function_decl; bool proto; + tree restype, resdecl; /* The argument information block for FNDECL. */ struct c_arg_info *arg_info = current_function_arg_info; @@ -8486,7 +8478,12 @@ store_parm_decls (void) gen_aux_info_record (fndecl, 1, 0, proto); /* Initialize the RTL code for the function. */ - allocate_struct_function (fndecl, false); + restype = TREE_TYPE (TREE_TYPE (current_function_decl)); + resdecl = build_decl (DECL_SOURCE_LOCATION (fndecl), RESULT_DECL, NULL_TREE, restype); + DECL_ARTIFICIAL (resdecl) = 1; + DECL_IGNORED_P (resdecl) = 1; + allocate_struct_function (fndecl, false, resdecl); + if (warn_unused_local_typedefs) cfun->language = ggc_cleared_alloc<language_function> (); Index: cgraph.c =================================================================== --- cgraph.c (revision 211106) +++ cgraph.c (working copy) @@ -1722,10 +1722,7 @@ cgraph_release_function_body (struct cgr { node->ipa_transforms_to_apply.release (); if (!node->used_as_abstract_origin && cgraph_state != CGRAPH_STATE_PARSING) - { - DECL_RESULT (node->decl) = NULL; - DECL_ARGUMENTS (node->decl) = NULL; - } + DECL_ARGUMENTS (node->decl) = NULL; /* If the node is abstract and needed, then do not clear DECL_INITIAL of its associated function function declaration because it's needed to emit debug info later. */ @@ -3048,7 +3045,8 @@ cgraph_get_body (struct cgraph_node *nod size_t len; tree decl = node->decl; - if (DECL_RESULT (decl)) + /* Do nothing if body is here. */ + if (DECL_STRUCT_FUNCTION (decl)) return false; gcc_assert (in_lto_p); @@ -3164,7 +3162,8 @@ gimple_check_call_matching_types (gimple { tree lhs; - if ((DECL_RESULT (callee) + if ((DECL_STRUCT_FUNCTION (callee) + && DECL_RESULT (callee) && !DECL_BY_REFERENCE (DECL_RESULT (callee)) && (lhs = gimple_call_lhs (call_stmt)) != NULL_TREE && !useless_type_conversion_p (TREE_TYPE (DECL_RESULT (callee)), Index: cgraph.h =================================================================== --- cgraph.h (revision 211106) +++ cgraph.h (working copy) @@ -909,7 +909,7 @@ void cgraph_process_same_body_aliases (v void fixup_same_cpp_alias_visibility (symtab_node *, symtab_node *target, tree); /* Initialize datastructures so DECL is a function in lowered gimple form. IN_SSA is true if the gimple is in SSA. */ -basic_block init_lowered_empty_function (tree, bool); +basic_block init_lowered_empty_function (tree, bool, tree); void cgraph_reset_node (struct cgraph_node *); bool expand_thunk (struct cgraph_node *, bool); Index: tree.c =================================================================== --- tree.c (revision 211106) +++ tree.c (working copy) @@ -5056,7 +5056,6 @@ free_lang_data_in_decl (tree decl) { release_function_body (decl); DECL_ARGUMENTS (decl) = NULL; - DECL_RESULT (decl) = NULL; DECL_INITIAL (decl) = error_mark_node; } } @@ -5246,10 +5245,7 @@ find_decls_types_r (tree *tp, int *ws, v fld_worklist_push (DECL_ABSTRACT_ORIGIN (t), fld); if (TREE_CODE (t) == FUNCTION_DECL) - { - fld_worklist_push (DECL_ARGUMENTS (t), fld); - fld_worklist_push (DECL_RESULT (t), fld); - } + fld_worklist_push (DECL_ARGUMENTS (t), fld); else if (TREE_CODE (t) == TYPE_DECL) { fld_worklist_push (DECL_ARGUMENT_FLD (t), fld); Index: tree.h =================================================================== --- tree.h (revision 211106) +++ tree.h (working copy) @@ -2460,11 +2460,6 @@ extern void decl_fini_priority_insert (t #define DECL_NONALIASED(NODE) \ (VAR_DECL_CHECK (NODE)->base.nothrow_flag) -/* This field is used to reference anything in decl.result and is meant only - for use by the garbage collector. */ -#define DECL_RESULT_FLD(NODE) \ - (DECL_NON_COMMON_CHECK (NODE)->decl_non_common.result) - /* The DECL_VINDEX is used for FUNCTION_DECLS in two different ways. Before the struct containing the FUNCTION_DECL is laid out, DECL_VINDEX may point to a FUNCTION_DECL in a base class which @@ -2477,7 +2472,7 @@ extern void decl_fini_priority_insert (t (DECL_NON_COMMON_CHECK (NODE)->decl_non_common.vindex) /* In FUNCTION_DECL, holds the decl for the return value. */ -#define DECL_RESULT(NODE) (FUNCTION_DECL_CHECK (NODE)->decl_non_common.result) +#define DECL_RESULT(NODE) (DECL_STRUCT_FUNCTION (NODE)->result) /* In a FUNCTION_DECL, nonzero if the function cannot be inlined. */ #define DECL_UNINLINABLE(NODE) \ @@ -2667,7 +2662,7 @@ extern vec<tree, va_gc> **decl_debug_arg /* For a TYPE_DECL, holds the "original" type. (TREE_TYPE has the copy.) */ #define DECL_ORIGINAL_TYPE(NODE) \ - (TYPE_DECL_CHECK (NODE)->decl_non_common.result) + (TYPE_DECL_CHECK (NODE)->type_decl.original_type) /* In a TYPE_DECL nonzero means the detail info about this type is not dumped into stabs. Instead it will generate cross reference ('x') of names. Index: omp-low.c =================================================================== --- omp-low.c (revision 211106) +++ omp-low.c (working copy) @@ -1839,7 +1839,7 @@ create_omp_child_function_name (bool tas static void create_omp_child_function (omp_context *ctx, bool task_copy) { - tree decl, type, name, t; + tree decl, type, name, t, resdecl; name = create_omp_child_function_name (task_copy); if (task_copy) @@ -1887,12 +1887,11 @@ create_omp_child_function (omp_context * = tree_cons (get_identifier ("omp declare target"), NULL_TREE, DECL_ATTRIBUTES (decl)); - t = build_decl (DECL_SOURCE_LOCATION (decl), - RESULT_DECL, NULL_TREE, void_type_node); - DECL_ARTIFICIAL (t) = 1; - DECL_IGNORED_P (t) = 1; - DECL_CONTEXT (t) = decl; - DECL_RESULT (decl) = t; + resdecl = build_decl (DECL_SOURCE_LOCATION (decl), + RESULT_DECL, NULL_TREE, void_type_node); + DECL_ARTIFICIAL (resdecl) = 1; + DECL_IGNORED_P (resdecl) = 1; + DECL_CONTEXT (resdecl) = decl; t = build_decl (DECL_SOURCE_LOCATION (decl), PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node); @@ -1922,7 +1921,7 @@ create_omp_child_function (omp_context * /* Allocate memory for the function structure. The call to allocate_struct_function clobbers CFUN, so we need to restore it afterward. */ - push_struct_function (decl); + push_struct_function (decl, resdecl); cfun->function_end_locus = gimple_location (ctx->stmt); pop_cfun (); } Index: objc/objc-act.c =================================================================== --- objc/objc-act.c (revision 211106) +++ objc/objc-act.c (working copy) @@ -8617,12 +8617,6 @@ objc_start_function (tree name, tree typ current_function_decl = pushdecl (fndecl); push_scope (); declare_parm_level (); - DECL_RESULT (current_function_decl) - = build_decl (input_location, - RESULT_DECL, NULL_TREE, - TREE_TYPE (TREE_TYPE (current_function_decl))); - DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1; - DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1; start_fname_decls (); store_parm_decls_from (params); #endif Index: objc/objc-act.h =================================================================== --- objc/objc-act.h (revision 211106) +++ objc/objc-act.h (working copy) @@ -44,7 +44,7 @@ void objc_common_init_ts (void); /* INSTANCE_METHOD_DECL, CLASS_METHOD_DECL */ #define METHOD_SEL_NAME(DECL) ((DECL)->decl_minimal.name) #define METHOD_SEL_ARGS(DECL) ((DECL)->decl_non_common.arguments) -#define METHOD_ADD_ARGS(DECL) ((DECL)->decl_non_common.result) +#define METHOD_ADD_ARGS(DECL) ((DECL)->decl_non_common.saved_tree) #define METHOD_ADD_ARGS_ELLIPSIS_P(DECL) ((DECL)->decl_common.lang_flag_0) #define METHOD_DEFINITION(DECL) ((DECL)->decl_common.initial) #define METHOD_ENCODING(DECL) ((DECL)->decl_minimal.context) @@ -71,7 +71,7 @@ void objc_common_init_ts (void); #define PROPERTY_GETTER_NAME(DECL) ((DECL)->decl_non_common.arguments) /* PROPERTY_SETTER_NAME is the identifier of the setter method. */ -#define PROPERTY_SETTER_NAME(DECL) ((DECL)->decl_non_common.result) +#define PROPERTY_SETTER_NAME(DECL) ((DECL)->decl_non_common.saved_tree) /* PROPERTY_READONLY can be 0 or 1. */ #define PROPERTY_READONLY(DECL) DECL_LANG_FLAG_0 (DECL) Index: cgraphunit.c =================================================================== --- cgraphunit.c (revision 211106) +++ cgraphunit.c (working copy) @@ -1325,12 +1325,12 @@ mark_functions_to_output (void) return basic block in the function body. */ basic_block -init_lowered_empty_function (tree decl, bool in_ssa) +init_lowered_empty_function (tree decl, bool in_ssa, tree result) { basic_block bb; current_function_decl = decl; - allocate_struct_function (decl, false); + allocate_struct_function (decl, false, result); gimple_register_cfg_hooks (); init_empty_tree_cfg (); @@ -1488,6 +1488,7 @@ expand_thunk (struct cgraph_node *node, const char *fnname; tree fn_block; tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl)); + tree resdecl; if (!output_asm_thunks) return false; @@ -1501,10 +1502,10 @@ expand_thunk (struct cgraph_node *node, /* Ensure thunks are emitted in their correct sections. */ resolve_unique_section (thunk_fndecl, 0, flag_function_sections); - DECL_RESULT (thunk_fndecl) + resdecl = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl), RESULT_DECL, 0, restype); - DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl; + DECL_CONTEXT (resdecl) = thunk_fndecl; fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl)); /* The back end expects DECL_INITIAL to contain a BLOCK, so we @@ -1512,7 +1513,7 @@ expand_thunk (struct cgraph_node *node, fn_block = make_node (BLOCK); BLOCK_VARS (fn_block) = a; DECL_INITIAL (thunk_fndecl) = fn_block; - init_function_start (thunk_fndecl); + init_function_start (thunk_fndecl, resdecl); cfun->is_thunk = 1; insn_locations_init (); set_curr_insn_location (DECL_SOURCE_LOCATION (thunk_fndecl)); @@ -1562,18 +1563,13 @@ expand_thunk (struct cgraph_node *node, /* Build the return declaration for the function. */ restype = TREE_TYPE (TREE_TYPE (thunk_fndecl)); - if (DECL_RESULT (thunk_fndecl) == NULL_TREE) - { - resdecl = build_decl (input_location, RESULT_DECL, 0, restype); - DECL_ARTIFICIAL (resdecl) = 1; - DECL_IGNORED_P (resdecl) = 1; - DECL_RESULT (thunk_fndecl) = resdecl; - DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl; - } - else - resdecl = DECL_RESULT (thunk_fndecl); + resdecl = build_decl (input_location, RESULT_DECL, 0, restype); + DECL_ARTIFICIAL (resdecl) = 1; + DECL_IGNORED_P (resdecl) = 1; + DECL_RESULT (thunk_fndecl) = resdecl; + DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl; - bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl, true); + bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl, true, resdecl); bsi = gsi_start_bb (bb); @@ -1769,7 +1765,7 @@ expand_function (struct cgraph_node *nod current_function_decl = decl; saved_loc = input_location; input_location = DECL_SOURCE_LOCATION (decl); - init_function_start (decl); + init_function_start (decl, NULL); gimple_register_cfg_hooks (); Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 211106) +++ cp/cp-tree.h (working copy) @@ -3754,7 +3754,8 @@ more_aggr_init_expr_args_p (const aggr_i TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (NODE)) /* For function, method, class-data templates. */ #define DECL_TEMPLATE_RESULT(NODE) \ - DECL_RESULT_FLD (TEMPLATE_DECL_CHECK (NODE)) + TEMPLATE_DECL_CHECK (NODE)->decl_non_common.saved_tree + /* For a function template at namespace scope, DECL_TEMPLATE_INSTANTIATIONS lists all instantiations and specializations of the function so that tsubst_friend_function can reassign them to another template if we find Index: cp/method.c =================================================================== --- cp/method.c (revision 211106) +++ cp/method.c (working copy) @@ -294,7 +294,8 @@ use_thunk (tree thunk_fndecl, bool emit_ return; function = THUNK_TARGET (thunk_fndecl); - if (DECL_RESULT (thunk_fndecl)) + if ((thunk_node = cgraph_get_node (thunk_fndecl)) != NULL + && thunk_node->thunk.thunk_p) /* We already turned this thunk into an ordinary function. There's no need to process this thunk again. */ return; Index: cp/pt.c =================================================================== --- cp/pt.c (revision 211106) +++ cp/pt.c (working copy) @@ -10631,7 +10631,6 @@ tsubst_decl (tree t, tree args, tsubst_f DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args, complain, t); - DECL_RESULT (r) = NULL_TREE; TREE_STATIC (r) = 0; TREE_PUBLIC (r) = TREE_PUBLIC (t); Index: cp/decl.c =================================================================== --- cp/decl.c (revision 211106) +++ cp/decl.c (working copy) @@ -2258,7 +2258,6 @@ duplicate_decls (tree newdecl, tree oldd Note that if the types do match, we'll preserve inline info and other bits, but if not, we won't. */ DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl); - DECL_RESULT (olddecl) = DECL_RESULT (newdecl); } /* If redeclaring a builtin function, it stays built in if newdecl is a gnu_inline definition, or if newdecl is just @@ -2294,7 +2293,6 @@ duplicate_decls (tree newdecl, tree oldd SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl)); else if (types_match) { - DECL_RESULT (newdecl) = DECL_RESULT (olddecl); /* Don't clear out the arguments if we're just redeclaring a function. */ if (DECL_ARGUMENTS (olddecl)) @@ -13250,17 +13248,10 @@ start_preparsed_function (tree decl1, tr /* Build the return declaration for the function. */ restype = TREE_TYPE (fntype); - if (DECL_RESULT (decl1) == NULL_TREE) - { - tree resdecl; - - resdecl = build_decl (input_location, RESULT_DECL, 0, restype); - DECL_ARTIFICIAL (resdecl) = 1; - DECL_IGNORED_P (resdecl) = 1; - DECL_RESULT (decl1) = resdecl; - - cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl); - } + tree resdecl = build_decl (input_location, RESULT_DECL, 0, restype); + DECL_ARTIFICIAL (resdecl) = 1; + DECL_IGNORED_P (resdecl) = 1; + cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl); /* Let the user know we're compiling this function. */ announce_function (decl1); @@ -13346,12 +13337,12 @@ start_preparsed_function (tree decl1, tr return true; /* Initialize RTL machinery. We cannot do this until - CURRENT_FUNCTION_DECL and DECL_RESULT are set up. We do this + CURRENT_FUNCTION_DECL and RESDECL are set up. We do this even when processing a template; this is how we get CFUN set up, and our per-function variables initialized. FIXME factor out the non-RTL stuff. */ bl = current_binding_level; - allocate_struct_function (decl1, processing_template_decl); + allocate_struct_function (decl1, processing_template_decl, resdecl); /* Initialize the language data structures. Whenever we start a new function, we destroy temporaries in the usual way. */ Index: cgraphclones.c =================================================================== --- cgraphclones.c (revision 211106) +++ cgraphclones.c (working copy) @@ -335,7 +335,6 @@ duplicate_thunk_for_node (cgraph_node *t } gcc_checking_assert (!DECL_STRUCT_FUNCTION (new_decl)); gcc_checking_assert (!DECL_INITIAL (new_decl)); - gcc_checking_assert (!DECL_RESULT (new_decl)); gcc_checking_assert (!DECL_RTL_SET_P (new_decl)); DECL_NAME (new_decl) = clone_function_name (thunk->decl, "artificial_thunk"); @@ -535,9 +534,6 @@ cgraph_create_virtual_clone (struct cgra DECL_STRUCT_FUNCTION (new_decl) = NULL; DECL_ARGUMENTS (new_decl) = NULL; DECL_INITIAL (new_decl) = NULL; - DECL_RESULT (new_decl) = NULL; - /* We can not do DECL_RESULT (new_decl) = NULL; here because of LTO partitioning - sometimes storing only clone decl instead of original. */ /* Generate a new name for the new version. */ len = IDENTIFIER_LENGTH (DECL_NAME (old_decl)); Index: dwarf2out.c =================================================================== --- dwarf2out.c (revision 211106) +++ dwarf2out.c (working copy) @@ -18594,7 +18594,7 @@ gen_subprogram_die (tree decl, dw_die_re int tail_call_site_note_count = 0; /* Emit a DW_TAG_variable DIE for a named return value. */ - if (DECL_NAME (DECL_RESULT (decl))) + if (DECL_STRUCT_FUNCTION (decl) && DECL_NAME (DECL_RESULT (decl))) gen_decl_die (DECL_RESULT (decl), NULL, subr_die); current_function_has_inlines = 0; Index: tree-browser.c =================================================================== --- tree-browser.c (revision 211106) +++ tree-browser.c (working copy) @@ -359,9 +359,9 @@ browse_tree (tree begin) TB_WF; break; - case TB_RESULT: - if (head && DECL_P (head)) - TB_SET_HEAD (DECL_RESULT_FLD (head)); + case TB_ORIGINAL_TYPE: + if (head && TREE_CODE (head) == TYPE_DECL) + TB_SET_HEAD (DECL_ORIGINAL_TYPE (head)); else TB_WF; break; Index: tree-parloops.c =================================================================== --- tree-parloops.c (revision 211106) +++ tree-parloops.c (working copy) @@ -1445,6 +1445,7 @@ create_loop_fn (location_t loc) tree decl, type, name, t; struct function *act_cfun = cfun; static unsigned loopfn_num; + tree resdecl; loc = LOCATION_LOCUS (loc); snprintf (buf, 100, "%s.$loopfn", current_function_name ()); @@ -1468,10 +1469,9 @@ create_loop_fn (location_t loc) DECL_CONTEXT (decl) = NULL_TREE; DECL_INITIAL (decl) = make_node (BLOCK); - t = build_decl (loc, RESULT_DECL, NULL_TREE, void_type_node); - DECL_ARTIFICIAL (t) = 1; - DECL_IGNORED_P (t) = 1; - DECL_RESULT (decl) = t; + resdecl = build_decl (loc, RESULT_DECL, NULL_TREE, void_type_node); + DECL_ARTIFICIAL (resdecl) = 1; + DECL_IGNORED_P (resdecl) = 1; t = build_decl (loc, PARM_DECL, get_identifier (".paral_data_param"), ptr_type_node); @@ -1481,7 +1481,7 @@ create_loop_fn (location_t loc) TREE_USED (t) = 1; DECL_ARGUMENTS (decl) = t; - allocate_struct_function (decl, false); + allocate_struct_function (decl, false, resdecl); /* The call to allocate_struct_function clobbers CFUN, so we need to restore it. */ Index: lto-streamer-in.c =================================================================== --- lto-streamer-in.c (revision 211106) +++ lto-streamer-in.c (working copy) @@ -916,12 +916,13 @@ input_function (tree fn_decl, struct dat gimple *stmts; basic_block bb; struct cgraph_node *node; + tree resdecl; tag = streamer_read_record_start (ib); lto_tag_check (tag, LTO_function); /* Read decls for parameters and args. */ - DECL_RESULT (fn_decl) = stream_read_tree (ib, data_in); + resdecl = stream_read_tree (ib, data_in); DECL_ARGUMENTS (fn_decl) = streamer_read_chain (ib, data_in); /* Read the tree of lexical scopes for the function. */ @@ -930,7 +931,7 @@ input_function (tree fn_decl, struct dat if (!streamer_read_uhwi (ib)) return; - push_struct_function (fn_decl); + push_struct_function (fn_decl, resdecl); fn = DECL_STRUCT_FUNCTION (fn_decl); init_tree_ssa (fn); /* We input IL in SSA form. */ Index: fortran/trans-decl.c =================================================================== --- fortran/trans-decl.c (revision 211106) +++ fortran/trans-decl.c (working copy) @@ -1676,11 +1676,9 @@ gfc_get_extern_function_decl (gfc_symbol locus old_loc; gfc_save_backend_locus (&old_loc); - push_cfun (NULL); gfc_create_function_decl (gsym->ns, true); - pop_cfun (); gfc_restore_backend_locus (&old_loc); } @@ -1955,7 +1953,6 @@ build_function_decl (gfc_symbol * sym, b DECL_ARTIFICIAL (result_decl) = 1; DECL_IGNORED_P (result_decl) = 1; DECL_CONTEXT (result_decl) = fndecl; - DECL_RESULT (fndecl) = result_decl; /* Don't call layout_decl for a RESULT_DECL. layout_decl (result_decl, 0); */ @@ -1990,6 +1987,7 @@ build_function_decl (gfc_symbol * sym, b gfc_set_decl_assembler_name (fndecl, gfc_sym_mangled_function_id (sym)); sym->backend_decl = fndecl; + allocate_struct_function (fndecl, false, result_decl); } @@ -2350,8 +2348,6 @@ trans_function_start (gfc_symbol * sym) /* Create RTL for function definition. */ make_decl_rtl (fndecl); - allocate_struct_function (fndecl, false); - /* function.c requires a push at the start of the function. */ pushlevel (); } @@ -4661,7 +4657,6 @@ generate_coarray_init (gfc_namespace * n DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 1; DECL_CONTEXT (decl) = fndecl; - DECL_RESULT (fndecl) = decl; pushdecl (fndecl); current_function_decl = fndecl; @@ -4669,7 +4664,7 @@ generate_coarray_init (gfc_namespace * n rest_of_decl_compilation (fndecl, 0, 0); make_decl_rtl (fndecl); - allocate_struct_function (fndecl, false); + allocate_struct_function (fndecl, false, decl); pushlevel (); gfc_init_block (&caf_init_block); @@ -5185,7 +5180,6 @@ create_main_function (tree fndecl) DECL_ARTIFICIAL (result_decl) = 1; DECL_IGNORED_P (result_decl) = 1; DECL_CONTEXT (result_decl) = ftn_main; - DECL_RESULT (ftn_main) = result_decl; pushdecl (ftn_main); @@ -5218,7 +5212,7 @@ create_main_function (tree fndecl) rest_of_decl_compilation (ftn_main, 1, 0); make_decl_rtl (ftn_main); - allocate_struct_function (ftn_main, false); + allocate_struct_function (ftn_main, false, result_decl); pushlevel (); gfc_init_block (&body); Index: function.c =================================================================== --- function.c (revision 211106) +++ function.c (working copy) @@ -140,7 +140,7 @@ void push_function_context (void) { if (cfun == 0) - allocate_struct_function (NULL, false); + allocate_struct_function (NULL, false, NULL); function_context_stack.safe_push (cfun); set_cfun (NULL); @@ -4495,13 +4495,14 @@ get_last_funcdef_no (void) placed in object files. */ void -allocate_struct_function (tree fndecl, bool abstract_p) +allocate_struct_function (tree fndecl, bool abstract_p, tree result) { tree fntype = fndecl ? TREE_TYPE (fndecl) : NULL_TREE; cfun = ggc_cleared_alloc<function> (); init_eh_for_function (); + cfun->result= result; if (init_machine_status) cfun->machine = (*init_machine_status) (); @@ -4521,8 +4522,7 @@ allocate_struct_function (tree fndecl, b if (fndecl != NULL_TREE) { - tree result = DECL_RESULT (fndecl); - if (!abstract_p && aggregate_value_p (result, fndecl)) + if (!abstract_p && aggregate_value_p (cfun->result, fndecl)) { #ifdef PCC_STATIC_STRUCT_RETURN cfun->returns_pcc_struct = 1; @@ -4546,7 +4546,7 @@ allocate_struct_function (tree fndecl, b instead of just setting it. */ void -push_struct_function (tree fndecl) +push_struct_function (tree fndecl, tree result) { /* When in_dummy_function we might be in the middle of a pop_cfun and current_function_decl and cfun may not match. */ @@ -4555,7 +4555,7 @@ push_struct_function (tree fndecl) || (cfun && current_function_decl == cfun->decl)); cfun_stack.safe_push (cfun); current_function_decl = fndecl; - allocate_struct_function (fndecl, false); + allocate_struct_function (fndecl, false, result); } /* Reset crtl and other non-struct-function variables to defaults as @@ -4605,7 +4605,7 @@ init_dummy_function_start (void) { gcc_assert (!in_dummy_function); in_dummy_function = true; - push_struct_function (NULL_TREE); + push_struct_function (NULL_TREE, NULL_TREE); prepare_function_start (); } @@ -4614,12 +4614,12 @@ init_dummy_function_start (void) of the function. */ void -init_function_start (tree subr) +init_function_start (tree subr, tree result) { if (subr && DECL_STRUCT_FUNCTION (subr)) set_cfun (DECL_STRUCT_FUNCTION (subr)); else - allocate_struct_function (subr, false); + allocate_struct_function (subr, false, result); prepare_function_start (); decide_function_section (subr); Index: function.h =================================================================== --- function.h (revision 211106) +++ function.h (working copy) @@ -540,6 +540,9 @@ struct GTY(()) function { /* Points to the FUNCTION_DECL of this function. */ tree decl; + /* Return value of function. */ + tree result; + /* A PARM_DECL that should contain the static chain for this function. It will be initialized at the beginning of the function. */ tree static_chain_decl; @@ -827,9 +830,9 @@ extern void expand_function_start (tree) extern void stack_protect_epilogue (void); extern void init_dummy_function_start (void); extern void expand_dummy_function_end (void); -extern void allocate_struct_function (tree, bool); -extern void push_struct_function (tree fndecl); -extern void init_function_start (tree); +extern void allocate_struct_function (tree, bool, tree); +extern void push_struct_function (tree, tree); +extern void init_function_start (tree, tree); extern bool use_register_for_decl (const_tree); extern void generate_setjmp_warnings (void); extern void init_temp_slots (void); Index: stor-layout.c =================================================================== --- stor-layout.c (revision 211106) +++ stor-layout.c (working copy) @@ -170,6 +170,7 @@ self_referential_size (tree size) unsigned int i; char buf[128]; vec<tree, va_gc> *args = NULL; + tree resdecl; /* Do not factor out simple operations. */ t = skip_simple_constant_arithmetic (size); @@ -247,9 +248,8 @@ self_referential_size (tree size) for (t = param_decl_list; t; t = DECL_CHAIN (t)) DECL_CONTEXT (t) = fndecl; DECL_ARGUMENTS (fndecl) = param_decl_list; - DECL_RESULT (fndecl) - = build_decl (input_location, RESULT_DECL, 0, return_type); - DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl; + resdecl = build_decl (input_location, RESULT_DECL, 0, return_type); + DECL_CONTEXT (resdecl) = fndecl; /* The function has been created by the compiler and we don't want to emit debug info for it. */ @@ -270,6 +270,7 @@ self_referential_size (tree size) t = build2 (MODIFY_EXPR, return_type, DECL_RESULT (fndecl), size); DECL_SAVED_TREE (fndecl) = build1 (RETURN_EXPR, void_type_node, t); TREE_STATIC (fndecl) = 1; + allocate_struct_function (fndecl, false, resdecl); /* Put it onto the list of size functions. */ vec_safe_push (size_functions, fndecl); @@ -293,7 +294,6 @@ finalize_size_functions (void) for (i = 0; size_functions && size_functions->iterate (i, &fndecl); i++) { - allocate_struct_function (fndecl, false); set_cfun (NULL); dump_function (TDI_original, fndecl); gimplify_function_tree (fndecl); Index: ipa.c =================================================================== --- ipa.c (revision 211106) +++ ipa.c (working copy) @@ -806,10 +806,9 @@ cgraph_build_static_cdtor_1 (char which, resdecl = build_decl (input_location, RESULT_DECL, NULL_TREE, void_type_node); DECL_ARTIFICIAL (resdecl) = 1; - DECL_RESULT (decl) = resdecl; DECL_CONTEXT (resdecl) = decl; - allocate_struct_function (decl, false); + allocate_struct_function (decl, false, resdecl); TREE_STATIC (decl) = 1; TREE_USED (decl) = 1; Index: gimplify.c =================================================================== --- gimplify.c (revision 211106) +++ gimplify.c (working copy) @@ -8784,7 +8784,7 @@ gimplify_function_tree (tree fndecl) if (DECL_STRUCT_FUNCTION (fndecl)) push_cfun (DECL_STRUCT_FUNCTION (fndecl)); else - push_struct_function (fndecl); + push_struct_function (fndecl, NULL); for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm)) { Index: lto/lto.c =================================================================== --- lto/lto.c (revision 211106) +++ lto/lto.c (working copy) @@ -779,7 +779,6 @@ mentions_vars_p_decl_non_common (tree t) if (mentions_vars_p_decl_with_vis (t)) return true; CHECK_NO_VAR (DECL_ARGUMENT_FLD (t)); - CHECK_NO_VAR (DECL_RESULT_FLD (t)); CHECK_NO_VAR (DECL_VINDEX (t)); return false; } @@ -937,6 +936,7 @@ mentions_vars_p (tree t) return mentions_vars_p_decl_with_vis (t); case TYPE_DECL: + CHECK_NO_VAR (DECL_ORIGINAL_TYPE (t)); return mentions_vars_p_decl_non_common (t); case FUNCTION_DECL: @@ -1516,7 +1516,6 @@ compare_tree_sccs_1 (tree t1, tree t2, t a1 || a2; a1 = TREE_CHAIN (a1), a2 = TREE_CHAIN (a2)) compare_tree_edges (a1, a2); - compare_tree_edges (DECL_RESULT (t1), DECL_RESULT (t2)); } else if (code == TYPE_DECL) compare_tree_edges (DECL_ORIGINAL_TYPE (t1), DECL_ORIGINAL_TYPE (t2)); @@ -2723,7 +2722,6 @@ lto_fixup_prevailing_decls (tree t) if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON)) { LTO_NO_PREVAIL (DECL_ARGUMENT_FLD (t)); - LTO_NO_PREVAIL (DECL_RESULT_FLD (t)); LTO_NO_PREVAIL (DECL_VINDEX (t)); } if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL)) @@ -2736,6 +2734,8 @@ lto_fixup_prevailing_decls (tree t) LTO_NO_PREVAIL (DECL_FIELD_BIT_OFFSET (t)); LTO_NO_PREVAIL (DECL_FCONTEXT (t)); } + if (TREE_CODE (t) == TYPE_DECL) + LTO_NO_PREVAIL (DECL_ORIGINAL_TYPE (t)); } else if (TYPE_P (t)) { Index: print-tree.c =================================================================== --- print-tree.c (revision 211106) +++ print-tree.c (working copy) @@ -531,8 +531,9 @@ print_node (FILE *file, const char *pref if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON)) { print_node (file, "arguments", DECL_ARGUMENT_FLD (node), indent + 4); - print_node (file, "result", DECL_RESULT_FLD (node), indent + 4); } + if (TREE_CODE (node) == TYPE_DECL) + print_node (file, "original_type", DECL_ORIGINAL_TYPE (node), indent + 4); lang_hooks.print_decl (file, node, indent); Index: tree-inline.c =================================================================== --- tree-inline.c (revision 211106) +++ tree-inline.c (working copy) @@ -2180,15 +2180,13 @@ remap_decl_1 (tree decl, void *data) the cfun to the function of new_fndecl (and current_function_decl too). */ static void -initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count) +initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count, tree resdecl) { struct function *src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl); gcov_type count_scale; if (!DECL_ARGUMENTS (new_fndecl)) DECL_ARGUMENTS (new_fndecl) = DECL_ARGUMENTS (callee_fndecl); - if (!DECL_RESULT (new_fndecl)) - DECL_RESULT (new_fndecl) = DECL_RESULT (callee_fndecl); if (ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count) count_scale @@ -2201,7 +2199,7 @@ initialize_cfun (tree new_fndecl, tree c gimple_register_cfg_hooks (); /* Get clean struct function. */ - push_struct_function (new_fndecl); + push_struct_function (new_fndecl, resdecl); /* We will rebuild these, so just sanity check that they are empty. */ gcc_assert (VALUE_HISTOGRAMS (cfun) == NULL); @@ -5340,10 +5338,9 @@ tree_function_versioning (tree old_decl, old_entry_block = ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (old_decl)); - DECL_RESULT (new_decl) = DECL_RESULT (old_decl); DECL_ARGUMENTS (new_decl) = DECL_ARGUMENTS (old_decl); initialize_cfun (new_decl, old_decl, - old_entry_block->count); + old_entry_block->count, DECL_RESULT (old_decl)); DECL_STRUCT_FUNCTION (new_decl)->gimple_df->ipa_pta = id.src_cfun->gimple_df->ipa_pta; Index: tree-core.h =================================================================== --- tree-core.h (revision 211106) +++ tree-core.h (working copy) @@ -1486,8 +1486,6 @@ struct GTY(()) tree_decl_non_common { tree saved_tree; /* C++ uses this in templates. */ tree arguments; - /* Almost all FE's use this. */ - tree result; /* C++ uses this in namespaces and function_decls. */ tree vindex; }; @@ -1550,7 +1548,7 @@ struct GTY(()) tree_translation_unit_dec struct GTY(()) tree_type_decl { struct tree_decl_non_common common; - + tree original_type; }; struct GTY ((chain_next ("%h.next"), chain_prev ("%h.prev"))) tree_statement_list_node Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 211106) +++ config/i386/i386.c (working copy) @@ -9152,6 +9152,7 @@ ix86_code_end (void) { char name[32]; tree decl; + tree resdecl; if (!(pic_labels_used & (1 << regno))) continue; @@ -9161,8 +9162,7 @@ ix86_code_end (void) decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, get_identifier (name), build_function_type_list (void_type_node, NULL_TREE)); - DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL, - NULL_TREE, void_type_node); + resdecl = build_decl (BUILTINS_LOCATION, RESULT_DECL, NULL_TREE, void_type_node); TREE_PUBLIC (decl) = 1; TREE_STATIC (decl) = 1; DECL_IGNORED_P (decl) = 1; @@ -9202,7 +9202,7 @@ ix86_code_end (void) DECL_INITIAL (decl) = make_node (BLOCK); current_function_decl = decl; - init_function_start (decl); + init_function_start (decl, resdecl); first_function_block_is_cold = false; /* Make sure unwind info is emitted for the thunk if needed. */ final_start_function (emit_barrier (), asm_out_file, 1); @@ -32192,11 +32192,10 @@ make_resolver_func (const tree default_d t = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, ptr_type_node); DECL_ARTIFICIAL (t) = 1; DECL_IGNORED_P (t) = 1; - DECL_RESULT (decl) = t; + /*push_struct_function (DECL_STRUCT_FUNCTION (decl), t); - gimplify_function_tree (decl); - push_cfun (DECL_STRUCT_FUNCTION (decl)); - *empty_bb = init_lowered_empty_function (decl, false); + gimplify_function_tree (decl);*/ + *empty_bb = init_lowered_empty_function (decl, false, t); cgraph_add_new_function (decl, true); cgraph_call_function_insertion_hooks (cgraph_get_create_node (decl)); @@ -32209,7 +32208,6 @@ make_resolver_func (const tree default_d = make_attribute ("ifunc", resolver_name, DECL_ATTRIBUTES (dispatch_decl)); /* Create the alias for dispatch to resolver here. */ - /*cgraph_create_function_alias (dispatch_decl, decl);*/ cgraph_same_body_alias (NULL, dispatch_decl, decl); XDELETEVEC (resolver_name); return decl; Index: tree-browser.def =================================================================== --- tree-browser.def (revision 211106) +++ tree-browser.def (working copy) @@ -55,7 +55,7 @@ DEFTBCODE (TB_CONTEXT, "context DEFTBCODE (TB_ATTRIBUTES, "attributes", "Field accessor.") DEFTBCODE (TB_ABSTRACT_ORIGIN, "abstract_origin", "Field accessor.") DEFTBCODE (TB_ARGUMENTS, "arguments", "Field accessor.") -DEFTBCODE (TB_RESULT, "result", "Field accessor.") +DEFTBCODE (TB_ORIGINAL_TYPE, "original_type", "Field accessor.") DEFTBCODE (TB_INITIAL, "initial", "Field accessor.") DEFTBCODE (TB_ARG_TYPE, "arg-type", "Field accessor.") DEFTBCODE (TB_ARG_TYPE_AS_WRITTEN, "arg-type-as-written", "Field accessor.")