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

Richard Biener richard.guenther@gmail.com
Fri Jun 6 09:06:00 GMT 2014


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



More information about the Gcc-patches mailing list