diff mbox

[RFC] Moving DECL_RESULT, DECL_ARGUMENTS, and DECL_SAVED_TREE into struct function

Message ID 20140606083053.GA6876@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka June 6, 2014, 8:30 a.m. UTC
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

Comments

Richard Biener June 6, 2014, 9:06 a.m. UTC | #1
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.")
diff mbox

Patch

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.")