Message ID | 20140606083053.GA6876@kam.mff.cuni.cz |
---|---|
State | New |
Headers | show |
On Fri, Jun 6, 2014 at 10:30 AM, Jan Hubicka <hubicka@ucw.cz> wrote: > 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. We have decl_lang_specific for FE specific data. > So any comments? Well, I think it's a good idea to move stuff out of the decls if it isn't required for just declarations but definitions only. Richard. > 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.")
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.")