This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [lto] Make COMPOUND_LITERAL_EXPR part of GENERIC


I like the patch a lot!

A first version of a port to lto is attached. I doesn't work, because
trunk revision 140138 is missing from the branch. That is the revision
that removed c_expand_decl.

Diego, are you doing a merge from trunk? Do you want me to do one so
that we can use this patch?

2008/9/9 Paolo Bonzini <bonzini@gnu.org>:
> Here is the patch with no regressions over current mainline (the problem
> with the previous patch, visible in pr34146-2.c, was that since I call
> optimize_compound_literals_in_ctor later, I had to add one recursive
> call within the function instead of relying on recursive gimplification).
>
> I can port it over to lto on Friday, but I doubt it's more than
> reverting Bill's patch and applying this one.
>
> Paolo
>
> 2008-09-09  Paolo Bonzini  <bonzini@gnu.org>
>
>        * Makefile.in (TREE_H, s-alltree, c-lang.o): Remove c-common.def
>        * c-common.c (c_expand_expr, c_staticp): Remove.
>        * c-common.def: Delete.
>        * c-common.h (emit_local_var, c_staticp, COMPOUND_LITERAL_EXPR_DECL,
>        COMPOUND_LITERAL_EXPR_DECL_EXPR): Remove.
>        * c-gimplify.c (gimplify_compound_literal_expr,
>        optimize_compound_literals_in_ctor): Remove.
>        (c_gimplify_expr): Remove COMPOUND_LITERAL_EXPR handling.
>        * c-objc-common.h (LANG_HOOKS_STATICP): Remove.
>        * c-semantics.c (emit_local_var): Remove.
>
>        * langhooks-def.h (lhd_expand_expr): Remove.
>        * langhooks.c (lhd_expand_expr): Remove.
>        * langhooks.h (LANG_HOOKS_DEF): Remove LANG_HOOKS_EXPAND_EXPR.
>
>        * expr.c (expand_expr_real_1): Move COMPOUND_LITERAL_EXPR
>        handling from c-semantics.c; don't call into langhook.
>        (expand_expr_addr_expr_1): Check that we don't get non-GENERIC trees.
>        * gimplify.c (gimplify_compound_literal_expr,
>        optimize_compound_literals_in_ctor): Move from c-gimplify.c.
>        (gimplify_init_constructor): Call optimize_compound_literals_in_ctor.
>        (gimplify_modify_expr_rhs, gimplify_expr): Handle COMPOUND_LITERAL_EXPR
>        as was done in c-gimplify.c.
>        * tree.c (staticp): Move COMPOUND_LITERAL_EXPR handling from c_staticp.
>        * tree.h (COMPOUND_LITERAL_EXPR_DECL, COMPOUND_LITERAL_EXPR_DECL_EXPR):
>        Move from c-common.h.
>        * tree.def (COMPOUND_LITERAL_EXPR): Move from c-common.def.
>
>        * doc/c-tree.texi (Expression nodes): Refer to DECL_EXPRs
>        instead of DECL_STMTs.
>
> 2008-09-09  Paolo Bonzini  <bonzini@gnu.org>
>
>        * Make-lang.in (CXX_TREE_H): Remove c-common.def.
>
> Index: doc/c-tree.texi
> ===================================================================
> --- doc/c-tree.texi     (revision 140137)
> +++ doc/c-tree.texi     (working copy)
> @@ -2636,10 +2636,10 @@ declaration order.  You should not assum
>  represented.  Unrepresented fields will be set to zero.
>
>  @item COMPOUND_LITERAL_EXPR
> -@findex COMPOUND_LITERAL_EXPR_DECL_STMT
> +@findex COMPOUND_LITERAL_EXPR_DECL_EXPR
>  @findex COMPOUND_LITERAL_EXPR_DECL
>  These nodes represent ISO C99 compound literals.  The
> -@code{COMPOUND_LITERAL_EXPR_DECL_STMT} is a @code{DECL_STMT}
> +@code{COMPOUND_LITERAL_EXPR_DECL_EXPR} is a @code{DECL_EXPR}
>  containing an anonymous @code{VAR_DECL} for
>  the unnamed object represented by the compound literal; the
>  @code{DECL_INITIAL} of that @code{VAR_DECL} is a @code{CONSTRUCTOR}
> Index: tree.c
> ===================================================================
> --- tree.c      (revision 140137)
> +++ tree.c      (working copy)
> @@ -2120,7 +2119,10 @@ staticp (tree arg)
>          && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST)
>        return staticp (TREE_OPERAND (arg, 0));
>       else
> -       return false;
> +       return NULL;
> +
> +    case COMPOUND_LITERAL_EXPR:
> +      return TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (arg)) ? arg : NULL;
>
>     default:
>       if ((unsigned int) TREE_CODE (arg)
> Index: tree.h
> ===================================================================
> --- tree.h      (revision 140138)
> +++ tree.h      (working copy)
> @@ -1591,6 +1591,12 @@ extern void protected_set_expr_location
>
>  #define EXIT_EXPR_COND(NODE)        TREE_OPERAND (EXIT_EXPR_CHECK (NODE), 0)
>
> +/* COMPOUND_LITERAL_EXPR accessors.  */
> +#define COMPOUND_LITERAL_EXPR_DECL_EXPR(NODE)          \
> +  TREE_OPERAND (COMPOUND_LITERAL_EXPR_CHECK (NODE), 0)
> +#define COMPOUND_LITERAL_EXPR_DECL(NODE)                       \
> +  DECL_EXPR_DECL (COMPOUND_LITERAL_EXPR_DECL_EXPR (NODE))
> +
>  /* SWITCH_EXPR accessors. These give access to the condition, body and
>    original condition type (before any compiler conversions)
>    of the switch statement, respectively.  */
> Index: cp/Make-lang.in
> ===================================================================
> --- cp/Make-lang.in     (revision 140137)
> +++ cp/Make-lang.in     (working copy)
> @@ -222,7 +222,7 @@ c++.stagefeedback: stagefeedback-start
>  #
>  # .o: .h dependencies.
>  CXX_TREE_H = $(TREE_H) cp/name-lookup.h cp/cp-tree.h $(C_COMMON_H) \
> -       c-common.def $(FUNCTION_H) $(VARRAY_H) \
> +       $(FUNCTION_H) $(VARRAY_H) \
>        $(SYSTEM_H) coretypes.h $(CONFIG_H) $(TARGET_H) $(GGC_H) \
>        $(srcdir)/../include/hashtab.h $(srcdir)/../include/splay-tree.h
>
> Index: c-semantics.c
> ===================================================================
> --- c-semantics.c       (revision 140137)
> +++ c-semantics.c       (working copy)
> @@ -1,6 +1,4 @@
> -/* This file contains the definitions and documentation for the common
> -   tree codes used in the GNU C and C++ compilers (see c-common.def
> -   for the standard codes).
> +/* This file contains subroutine used by the C front-end to construct GENERIC.
>    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007
>    Free Software Foundation, Inc.
>    Written by Benjamin Chelf (chelf@codesourcery.com).
> @@ -145,23 +143,6 @@ build_stmt (enum tree_code code, ...)
>   return ret;
>  }
>
> -/* Let the back-end know about DECL.  */
> -
> -void
> -emit_local_var (tree decl)
> -{
> -  /* Create RTL for this variable.  */
> -  if (!DECL_RTL_SET_P (decl))
> -    {
> -      if (DECL_HARD_REGISTER (decl))
> -       /* The user specified an assembler name for this variable.
> -          Set that up now.  */
> -       rest_of_decl_compilation (decl, 0, 0);
> -      else
> -       expand_decl (decl);
> -    }
> -}
> -
>  /* Create a CASE_LABEL_EXPR tree node and return it.  */
>
>  tree
> Index: expr.c
> ===================================================================
> --- expr.c      (revision 140137)
> +++ expr.c      (working copy)
> @@ -6807,9 +6807,10 @@ expand_expr_addr_expr_1 (tree exp, rtx t
>         CONSTRUCTORs too, which should yield a memory reference for the
>         constructor's contents.  Assume language specific tree nodes can
>         be expanded in some interesting way.  */
> +      gcc_assert (TREE_CODE (exp) < LAST_AND_UNUSED_TREE_CODE);
>       if (DECL_P (exp)
>          || TREE_CODE (exp) == CONSTRUCTOR
> -         || TREE_CODE (exp) >= LAST_AND_UNUSED_TREE_CODE)
> +         || TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
>        {
>          result = expand_expr (exp, target, tmode,
>                                modifier == EXPAND_INITIALIZER
> @@ -8043,11 +8043,8 @@ expand_expr_real_1 (tree exp, rtx target
>        /* Check for a built-in function.  */
>        if (fndecl && DECL_BUILT_IN (fndecl))
>          {
> -           if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_FRONTEND)
> -             return lang_hooks.expand_expr (exp, original_target,
> -                                            tmode, modifier, alt_rtl);
> -           else
> -             return expand_builtin (exp, target, subtarget, tmode, ignore);
> +           gcc_assert (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_FRONTEND);
> +           return expand_builtin (exp, target, subtarget, tmode, ignore);
>          }
>       }
>       return expand_call (exp, target, ignore);
> @@ -9426,9 +9423,29 @@ expand_expr_real_1 (tree exp, rtx target
>       mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
>       goto binop;
>
> +    case COMPOUND_LITERAL_EXPR:
> +      {
> +       /* Initialize the anonymous variable declared in the compound
> +          literal, then return the variable.  */
> +       tree decl = COMPOUND_LITERAL_EXPR_DECL (exp);
> +
> +       /* Create RTL for this variable.  */
> +       if (!DECL_RTL_SET_P (decl))
> +         {
> +           if (DECL_HARD_REGISTER (decl))
> +             /* The user specified an assembler name for this variable.
> +                Set that up now.  */
> +             rest_of_decl_compilation (decl, 0, 0);
> +           else
> +             expand_decl (decl);
> +         }
> +
> +       return expand_expr_real (decl, original_target, tmode,
> +                                modifier, alt_rtl);
> +      }
> +
>     default:
> -      return lang_hooks.expand_expr (exp, original_target, tmode,
> -                                    modifier, alt_rtl);
> +      gcc_unreachable ();
>     }
>
>   /* Here to do an ordinary binary operator.  */
> Index: langhooks.c
> ===================================================================
> --- langhooks.c (revision 140138)
> +++ langhooks.c (working copy)
> @@ -216,17 +216,6 @@ lhd_get_alias_set (tree ARG_UNUSED (t))
>   return -1;
>  }
>
> -/* This is the default expand_expr function.  */
> -
> -rtx
> -lhd_expand_expr (tree ARG_UNUSED (t), rtx ARG_UNUSED (r),
> -                enum machine_mode ARG_UNUSED (mm),
> -                int ARG_UNUSED (em),
> -                rtx * ARG_UNUSED (a))
> -{
> -  gcc_unreachable ();
> -}
> -
>  /* This is the default decl_printable_name function.  */
>
>  const char *
> Index: langhooks.h
> ===================================================================
> --- langhooks.h (revision 140138)
> +++ langhooks.h (working copy)
> @@ -290,10 +290,6 @@ struct lang_hooks
>      Returns -1 if the language does nothing special for it.  */
>   alias_set_type (*get_alias_set) (tree);
>
> -  /* Called by expand_expr for language-specific tree codes.
> -     Fourth argument is actually an enum expand_modifier.  */
> -  rtx (*expand_expr) (tree, rtx, enum machine_mode, int, rtx *);
> -
>   /* Function to finish handling an incomplete decl at the end of
>      compilation.  Default hook is does nothing.  */
>   void (*finish_incomplete_decl) (tree);
> Index: gimplify.c
> ===================================================================
> --- gimplify.c  (revision 140137)
> +++ gimplify.c  (working copy)
> @@ -3483,6 +3483,83 @@ rhs_predicate_for (tree lhs)
>     return is_gimple_mem_or_call_rhs;
>  }
>
> +/* Gimplify a C99 compound literal expression.  This just means adding
> +   the DECL_EXPR before the current statement and using its anonymous
> +   decl instead.  */
> +
> +static enum gimplify_status
> +gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p)
> +{
> +  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
> +  tree decl = DECL_EXPR_DECL (decl_s);
> +  /* Mark the decl as addressable if the compound literal
> +     expression is addressable now, otherwise it is marked too late
> +     after we gimplify the initialization expression.  */
> +  if (TREE_ADDRESSABLE (*expr_p))
> +    TREE_ADDRESSABLE (decl) = 1;
> +
> +  /* Preliminarily mark non-addressed complex variables as eligible
> +     for promotion to gimple registers.  We'll transform their uses
> +     as we find them.  */
> +  if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
> +       || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
> +      && !TREE_THIS_VOLATILE (decl)
> +      && !needs_to_live_in_memory (decl))
> +    DECL_GIMPLE_REG_P (decl) = 1;
> +
> +  /* This decl isn't mentioned in the enclosing block, so add it to the
> +     list of temps.  FIXME it seems a bit of a kludge to say that
> +     anonymous artificial vars aren't pushed, but everything else is.  */
> +  if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
> +    gimple_add_tmp_var (decl);
> +
> +  gimplify_and_add (decl_s, pre_p);
> +  *expr_p = decl;
> +  return GS_OK;
> +}
> +
> +/* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
> +   return a new CONSTRUCTOR if something changed.  */
> +
> +static tree
> +optimize_compound_literals_in_ctor (tree orig_ctor)
> +{
> +  tree ctor = orig_ctor;
> +  VEC(constructor_elt,gc) *elts = CONSTRUCTOR_ELTS (ctor);
> +  unsigned int idx, num = VEC_length (constructor_elt, elts);
> +
> +  for (idx = 0; idx < num; idx++)
> +    {
> +      tree value = VEC_index (constructor_elt, elts, idx)->value;
> +      tree newval = value;
> +      if (TREE_CODE (value) == CONSTRUCTOR)
> +       newval = optimize_compound_literals_in_ctor (value);
> +      else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
> +       {
> +         tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
> +         tree decl = DECL_EXPR_DECL (decl_s);
> +         tree init = DECL_INITIAL (decl);
> +
> +         if (!TREE_ADDRESSABLE (value)
> +             && !TREE_ADDRESSABLE (decl)
> +             && init)
> +           newval = optimize_compound_literals_in_ctor (init);
> +       }
> +      if (newval == value)
> +       continue;
> +
> +      if (ctor == orig_ctor)
> +       {
> +         ctor = copy_node (orig_ctor);
> +         CONSTRUCTOR_ELTS (ctor) = VEC_copy (constructor_elt, gc, elts);
> +         elts = CONSTRUCTOR_ELTS (ctor);
> +       }
> +      VEC_index (constructor_elt, elts, idx)->value = newval;
> +    }
> +  return ctor;
> +}
> +
> +
>
>  /* A subroutine of gimplify_modify_expr.  Break out elements of a
>    CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
> @@ -3507,7 +3584,7 @@ static enum gimplify_status
>  gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
>                           bool want_value, bool notify_temp_creation)
>  {
> -  tree object;
> +  tree object, new_ctor;
>   tree ctor = TREE_OPERAND (*expr_p, 1);
>   tree type = TREE_TYPE (ctor);
>   enum gimplify_status ret;
> @@ -3519,6 +3596,7 @@ gimplify_init_constructor (tree *expr_p,
>     }
>
>   object = TREE_OPERAND (*expr_p, 0);
> -  elts = CONSTRUCTOR_ELTS (ctor);
> +  new_ctor = optimize_compound_literals_in_ctor (ctor);
> +  elts = CONSTRUCTOR_ELTS (new_ctor);
>   ret = GS_ALL_DONE;
>
> @@ -4118,6 +4196,26 @@ gimplify_modify_expr_rhs (tree *expr_p,
>          return GS_OK;
>        }
>
> +      case COMPOUND_LITERAL_EXPR:
> +       {
> +         tree complit = TREE_OPERAND (*expr_p, 1);
> +         tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
> +         tree decl = DECL_EXPR_DECL (decl_s);
> +         tree init = DECL_INITIAL (decl);
> +
> +         /* struct T x = (struct T) { 0, 1, 2 } can be optimized
> +            into struct T x = { 0, 1, 2 } if the address of the
> +            compound literal has never been taken.  */
> +         if (!TREE_ADDRESSABLE (complit)
> +             && !TREE_ADDRESSABLE (decl)
> +             && init)
> +           {
> +             *expr_p = copy_node (*expr_p);
> +             TREE_OPERAND (*expr_p, 1) = init;
> +             return GS_OK;
> +           }
> +       }
> +
>       default:
>        ret = GS_UNHANDLED;
>        break;
> @@ -6340,6 +6438,10 @@ gimplify_expr (tree *expr_p, gimple_seq
>          ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
>          break;
>
> +       case COMPOUND_LITERAL_EXPR:
> +         ret = gimplify_compound_literal_expr (expr_p, pre_p);
> +         break;
> +
>        case MODIFY_EXPR:
>        case INIT_EXPR:
>          ret = gimplify_modify_expr (expr_p, pre_p, post_p,
> Index: tree.def
> ===================================================================
> --- tree.def    (revision 140137)
> +++ tree.def    (working copy)
> @@ -768,6 +768,13 @@ DEFTREECODE (NON_LVALUE_EXPR, "non_lvalu
>    generating insns.  */
>  DEFTREECODE (VIEW_CONVERT_EXPR, "view_convert_expr", tcc_reference, 1)
>
> +/* A COMPOUND_LITERAL_EXPR represents a literal that is placed in a DECL.  The
> +   COMPOUND_LITERAL_EXPR_DECL_EXPR is the a DECL_EXPR containing the decl
> +   for the anonymous object represented by the COMPOUND_LITERAL;
> +   the DECL_INITIAL of that decl is the CONSTRUCTOR that initializes
> +   the compound literal.  */
> +DEFTREECODE (COMPOUND_LITERAL_EXPR, "compound_literal_expr", tcc_expression, 1)
> +
>  /* Represents something we computed once and will use multiple times.
>    First operand is that expression.  After it is evaluated once, it
>    will be replaced by the temporary variable that holds the value.  */
> Index: c-gimplify.c
> ===================================================================
> --- c-gimplify.c        (revision 140137)
> +++ c-gimplify.c        (working copy)
> @@ -174,145 +142,25 @@ c_build_bind_expr (tree block, tree body
>
>  /* Gimplification of expression trees.  */
>
> -/* Gimplify a C99 compound literal expression.  This just means adding
> -   the DECL_EXPR before the current statement and using its anonymous
> -   decl instead.  */
> -
> -static enum gimplify_status
> -gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p)
> -{
> -  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
> -  tree decl = DECL_EXPR_DECL (decl_s);
> -  /* Mark the decl as addressable if the compound literal
> -     expression is addressable now, otherwise it is marked too late
> -     after we gimplify the initialization expression.  */
> -  if (TREE_ADDRESSABLE (*expr_p))
> -    TREE_ADDRESSABLE (decl) = 1;
> -
> -  /* Preliminarily mark non-addressed complex variables as eligible
> -     for promotion to gimple registers.  We'll transform their uses
> -     as we find them.  */
> -  if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
> -       || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
> -      && !TREE_THIS_VOLATILE (decl)
> -      && !needs_to_live_in_memory (decl))
> -    DECL_GIMPLE_REG_P (decl) = 1;
> -
> -  /* This decl isn't mentioned in the enclosing block, so add it to the
> -     list of temps.  FIXME it seems a bit of a kludge to say that
> -     anonymous artificial vars aren't pushed, but everything else is.  */
> -  if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
> -    gimple_add_tmp_var (decl);
> -
> -  gimplify_and_add (decl_s, pre_p);
> -  *expr_p = decl;
> -  return GS_OK;
> -}
> -
> -/* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
> -   return a new CONSTRUCTOR if something changed.  */
> -
> -static tree
> -optimize_compound_literals_in_ctor (tree orig_ctor)
> -{
> -  tree ctor = orig_ctor;
> -  VEC(constructor_elt,gc) *elts = CONSTRUCTOR_ELTS (ctor);
> -  unsigned int idx, num = VEC_length (constructor_elt, elts);
> -
> -  for (idx = 0; idx < num; idx++)
> -    {
> -      tree value = VEC_index (constructor_elt, elts, idx)->value;
> -      tree newval = value;
> -      if (TREE_CODE (value) == CONSTRUCTOR)
> -       newval = optimize_compound_literals_in_ctor (value);
> -      else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
> -       {
> -         tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (value);
> -         tree decl = DECL_EXPR_DECL (decl_s);
> -         tree init = DECL_INITIAL (decl);
> -
> -         if (!TREE_ADDRESSABLE (value)
> -             && !TREE_ADDRESSABLE (decl)
> -             && init)
> -           newval = init;
> -       }
> -      if (newval == value)
> -       continue;
> -
> -      if (ctor == orig_ctor)
> -       {
> -         ctor = copy_node (orig_ctor);
> -         CONSTRUCTOR_ELTS (ctor) = VEC_copy (constructor_elt, gc, elts);
> -         elts = CONSTRUCTOR_ELTS (ctor);
> -       }
> -      VEC_index (constructor_elt, elts, idx)->value = newval;
> -    }
> -  return ctor;
> -}
> -
>  /* Do C-specific gimplification on *EXPR_P.  PRE_P and POST_P are as in
>    gimplify_expr.  */
>
>  int
> -c_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
> +c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
>                 gimple_seq *post_p ATTRIBUTE_UNUSED)
>  {
>   enum tree_code code = TREE_CODE (*expr_p);
>
> -  switch (code)
> -    {
> -    case DECL_EXPR:
> -      /* This is handled mostly by gimplify.c, but we have to deal with
> -        not warning about int x = x; as it is a GCC extension to turn off
> -        this warning but only if warn_init_self is zero.  */
> -      if (TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
> -         && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
> -         && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
> -         && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p))
> -             == DECL_EXPR_DECL (*expr_p))
> -         && !warn_init_self)
> -       TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
> -      return GS_UNHANDLED;
> -
> -    case COMPOUND_LITERAL_EXPR:
> -      return gimplify_compound_literal_expr (expr_p, pre_p);
> -
> -    case INIT_EXPR:
> -    case MODIFY_EXPR:
> -      if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == COMPOUND_LITERAL_EXPR)
> -       {
> -         tree complit = TREE_OPERAND (*expr_p, 1);
> -         tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (complit);
> -         tree decl = DECL_EXPR_DECL (decl_s);
> -         tree init = DECL_INITIAL (decl);
> -
> -         /* struct T x = (struct T) { 0, 1, 2 } can be optimized
> -            into struct T x = { 0, 1, 2 } if the address of the
> -            compound literal has never been taken.  */
> -         if (!TREE_ADDRESSABLE (complit)
> -             && !TREE_ADDRESSABLE (decl)
> -             && init)
> -           {
> -             *expr_p = copy_node (*expr_p);
> -             TREE_OPERAND (*expr_p, 1) = init;
> -             return GS_OK;
> -           }
> -       }
> -      else if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR)
> -       {
> -         tree ctor
> -           = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
> -
> -         if (ctor != TREE_OPERAND (*expr_p, 1))
> -           {
> -             *expr_p = copy_node (*expr_p);
> -             TREE_OPERAND (*expr_p, 1) = ctor;
> -             return GS_OK;
> -           }
> -       }
> -      return GS_UNHANDLED;
> +  /* This is handled mostly by gimplify.c, but we have to deal with
> +     not warning about int x = x; as it is a GCC extension to turn off
> +     this warning but only if warn_init_self is zero.  */
> +  if (code == DECL_EXPR
> +      && TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
> +      && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
> +      && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
> +      && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p))
> +      && !warn_init_self)
> +    TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
>
> -    default:
> -      return GS_UNHANDLED;
> -    }
> +  return GS_UNHANDLED;
>  }
> Index: c-common.c
> ===================================================================
> --- c-common.c  (revision 140138)
> +++ c-common.c  (working copy)
> @@ -5010,43 +5010,6 @@ finish_label_address_expr (tree label, l
>
>   return result;
>  }
> -
> -/* Hook used by expand_expr to expand language-specific tree codes.  */
> -/* The only things that should go here are bits needed to expand
> -   constant initializers.  Everything else should be handled by the
> -   gimplification routines.  */
> -
> -rtx
> -c_expand_expr (tree exp, rtx target, enum machine_mode tmode,
> -              int modifiera /* Actually enum expand_modifier.  */,
> -              rtx *alt_rtl)
> -{
> -  enum expand_modifier modifier = (enum expand_modifier) modifiera;
> -  switch (TREE_CODE (exp))
> -    {
> -    case COMPOUND_LITERAL_EXPR:
> -      {
> -       /* Initialize the anonymous variable declared in the compound
> -          literal, then return the variable.  */
> -       tree decl = COMPOUND_LITERAL_EXPR_DECL (exp);
> -       emit_local_var (decl);
> -       return expand_expr_real (decl, target, tmode, modifier, alt_rtl);
> -      }
> -
> -    default:
> -      gcc_unreachable ();
> -    }
> -}
> -
> -/* Hook used by staticp to handle language-specific tree codes.  */
> -
> -tree
> -c_staticp (tree exp)
> -{
> -  return (TREE_CODE (exp) == COMPOUND_LITERAL_EXPR
> -         && TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (exp))
> -         ? exp : NULL);
> -}
>
>
>  /* Given a boolean expression ARG, return a tree representing an increment
> Index: c-common.h
> ===================================================================
> --- c-common.h  (revision 140138)
> +++ c-common.h  (working copy)
> @@ -794,12 +794,6 @@ extern void finish_file    (void);
>  #define STATEMENT_LIST_HAS_LABEL(NODE) \
>   TREE_LANG_FLAG_3 (STATEMENT_LIST_CHECK (NODE))
>
> -/* COMPOUND_LITERAL_EXPR accessors.  */
> -#define COMPOUND_LITERAL_EXPR_DECL_STMT(NODE)          \
> -  TREE_OPERAND (COMPOUND_LITERAL_EXPR_CHECK (NODE), 0)
> -#define COMPOUND_LITERAL_EXPR_DECL(NODE)                       \
> -  DECL_EXPR_DECL (COMPOUND_LITERAL_EXPR_DECL_STMT (NODE))
> -
>  /* In a FIELD_DECL, nonzero if the decl was originally a bitfield.  */
>  #define DECL_C_BIT_FIELD(NODE) \
>   (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) == 1)
> @@ -808,7 +802,6 @@ extern void finish_file     (void);
>  #define CLEAR_DECL_C_BIT_FIELD(NODE) \
>   (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 0)
>
> -extern void emit_local_var (tree);
>  extern tree do_case (tree, tree);
>  extern tree build_stmt (enum tree_code, ...);
>  extern tree build_case_label (tree, tree, tree);
> @@ -857,8 +850,6 @@ extern bool vector_types_convertible_p (
>
>  extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
>
> -extern tree c_staticp (tree);
> -
>  extern void init_c_lex (void);
>
>  extern void c_cpp_builtins (cpp_reader *);
> Index: Makefile.in
> ===================================================================
> --- Makefile.in (revision 140137)
> +++ Makefile.in (working copy)
> @@ -791,7 +791,7 @@ FIXED_VALUE_H = fixed-value.h $(MACHMODE
>  RTL_H = $(RTL_BASE_H) genrtl.h
>  PARAMS_H = params.h params.def
>  BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def
> -TREE_H = tree.h all-tree.def tree.def c-common.def $(lang_tree_files) \
> +TREE_H = tree.h all-tree.def tree.def $(lang_tree_files) \
>           $(MACHMODE_H) tree-check.h $(BUILTINS_DEF) \
>           $(INPUT_H) statistics.h vec.h treestruct.def $(HASHTAB_H) \
>           double-int.h alias.h $(SYMTAB_H) options.h
> @@ -1430,7 +1430,6 @@ s-alltree: Makefile
>        rm -f tmp-all-tree.def
>        echo '#include "tree.def"' > tmp-all-tree.def
>        echo 'END_OF_BASE_TREE_CODES' >> tmp-all-tree.def
> -       echo '#include "c-common.def"' >> tmp-all-tree.def
>        ltf="$(lang_tree_files)"; for f in $$ltf; do \
>          echo "#include \"$$f\""; \
>        done | sed 's|$(srcdir)/||' >> tmp-all-tree.def
> @@ -1825,7 +1824,7 @@ c-typeck.o : c-typeck.c $(CONFIG_H) $(SY
>  c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
>     $(C_TREE_H) $(DIAGNOSTIC_H) \
>     $(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-c.h \
> -    c-objc-common.h $(C_PRAGMA_H) c-common.def $(TREE_INLINE_H)
> +    c-objc-common.h $(C_PRAGMA_H) $(TREE_INLINE_H)
>  stub-objc.o : stub-objc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
>     $(C_COMMON_H)
>  c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
> Index: c-objc-common.h
> ===================================================================
> --- c-objc-common.h     (revision 140138)
> +++ c-objc-common.h     (working copy)
> @@ -51,8 +51,6 @@ extern void c_initialize_diagnostics (di
>  #define LANG_HOOKS_PARSE_FILE c_common_parse_file
>  #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
>  #define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl
> -#undef LANG_HOOKS_STATICP
> -#define LANG_HOOKS_STATICP c_staticp
>  #undef LANG_HOOKS_NO_BODY_BLOCKS
>  #define LANG_HOOKS_NO_BODY_BLOCKS true
>  #undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
> Index: c-common.def
> ===================================================================
> --- c-common.def        (revision 140137)
> +++ c-common.def        (working copy)
> @@ -1,38 +0,0 @@
> -/* This file contains the definitions and documentation for the
> -   additional tree codes used in the GNU C compiler (see tree.def
> -   for the standard codes).
> -   Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998,
> -   1999, 2000, 2001, 2004, 2005, 2007 Free Software Foundation, Inc.
> -   Written by Benjamin Chelf <chelf@codesourcery.com>
> -
> -This file is part of GCC.
> -
> -GCC is free software; you can redistribute it and/or modify it under
> -the terms of the GNU General Public License as published by the Free
> -Software Foundation; either version 3, or (at your option) any later
> -version.
> -
> -GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> -WARRANTY; without even the implied warranty of MERCHANTABILITY or
> -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> -for more details.
> -
> -You should have received a copy of the GNU General Public License
> -along with GCC; see the file COPYING3.  If not see
> -<http://www.gnu.org/licenses/>.  */
> -
> -/* Tree nodes used in the C frontend.  These are also shared with the
> -   C++ and Objective C frontends.  */
> -
> -/* A COMPOUND_LITERAL_EXPR represents a C99 compound literal.  The
> -   COMPOUND_LITERAL_EXPR_DECL_STMT is the a DECL_STMT containing the decl
> -   for the anonymous object represented by the COMPOUND_LITERAL;
> -   the DECL_INITIAL of that decl is the CONSTRUCTOR that initializes
> -   the compound literal.  */
> -DEFTREECODE (COMPOUND_LITERAL_EXPR, "compound_literal_expr", tcc_expression, 1)
> -
> -/*
> -Local variables:
> -mode:c
> -End:
> -*/
> Index: langhooks-def.h
> ===================================================================
> --- langhooks-def.h     (revision 140138)
> +++ langhooks-def.h     (working copy)
> @@ -50,7 +50,6 @@ extern void lhd_print_tree_nothing (FILE
>  extern const char *lhd_decl_printable_name (tree, int);
>  extern const char *lhd_dwarf_name (tree, int);
>  extern int lhd_types_compatible_p (tree, tree);
> -extern rtx lhd_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
>  extern void lhd_print_error_function (struct diagnostic_context *,
>                                      const char *, struct diagnostic_info *);
>  extern void lhd_set_decl_assembler_name (tree);
> @@ -91,7 +90,6 @@ extern void lhd_omp_firstprivatize_type_
>  #define LANG_HOOKS_POST_OPTIONS                lhd_post_options
>  #define LANG_HOOKS_MISSING_NORETURN_OK_P hook_bool_tree_true
>  #define LANG_HOOKS_GET_ALIAS_SET       lhd_get_alias_set
> -#define LANG_HOOKS_EXPAND_EXPR         lhd_expand_expr
>  #define LANG_HOOKS_FINISH_INCOMPLETE_DECL lhd_do_nothing_t
>  #define LANG_HOOKS_STATICP             lhd_staticp
>  #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL lhd_do_nothing_t
> @@ -240,7 +238,6 @@ extern tree lhd_make_node (enum tree_cod
>   LANG_HOOKS_PARSE_FILE, \
>   LANG_HOOKS_MISSING_NORETURN_OK_P, \
>   LANG_HOOKS_GET_ALIAS_SET, \
> -  LANG_HOOKS_EXPAND_EXPR, \
>   LANG_HOOKS_FINISH_INCOMPLETE_DECL, \
>   LANG_HOOKS_MARK_ADDRESSABLE, \
>   LANG_HOOKS_STATICP, \
>
>



-- 
Rafael Avila de Espindola

Google | Gordon House | Barrow Street | Dublin 4 | Ireland
Registered in Dublin, Ireland | Registration Number: 368047
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 553d770..0b50bd3 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -781,7 +781,7 @@ FIXED_VALUE_H = fixed-value.h $(MACHMODE_H) double-int.h
 RTL_H = $(RTL_BASE_H) genrtl.h
 PARAMS_H = params.h params.def
 BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def
-TREE_H = tree.h all-tree.def tree.def c-common.def $(lang_tree_files) \
+TREE_H = tree.h all-tree.def tree.def $(lang_tree_files) \
           $(MACHMODE_H) tree-check.h $(BUILTINS_DEF) \
           $(INPUT_H) statistics.h vec.h treestruct.def $(HASHTAB_H) \
           double-int.h alias.h $(SYMTAB_H) options.h
@@ -1413,7 +1413,6 @@ s-alltree: Makefile
 	rm -f tmp-all-tree.def
 	echo '#include "tree.def"' > tmp-all-tree.def
 	echo 'END_OF_BASE_TREE_CODES' >> tmp-all-tree.def
-	echo '#include "c-common.def"' >> tmp-all-tree.def
 	ltf="$(lang_tree_files)"; for f in $$ltf; do \
 	  echo "#include \"$$f\""; \
 	done | sed 's|$(srcdir)/||' >> tmp-all-tree.def
@@ -1808,7 +1807,7 @@ c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
 c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     $(C_TREE_H) $(DIAGNOSTIC_H) \
     $(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-c.h \
-    c-objc-common.h $(C_PRAGMA_H) c-common.def $(TREE_INLINE_H)
+    c-objc-common.h $(C_PRAGMA_H) $(TREE_INLINE_H)
 stub-objc.o : stub-objc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
     $(C_COMMON_H)
 c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 7c7dc02..8d74e43 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -98,8 +98,6 @@ static const char *gnat_dwarf_name	(tree, int);
 static tree gnat_return_tree		(tree);
 static int gnat_eh_type_covers		(tree, tree);
 static void gnat_parse_file		(int);
-static rtx gnat_expand_expr		(tree, rtx, enum machine_mode, int,
-					 rtx *);
 static void internal_error_function	(const char *, va_list *);
 static tree gnat_type_max_size		(const_tree);
 
@@ -131,8 +129,6 @@ static tree gnat_type_max_size		(const_tree);
 #define LANG_HOOKS_FINISH_INCOMPLETE_DECL gnat_finish_incomplete_decl
 #undef  LANG_HOOKS_GET_ALIAS_SET
 #define LANG_HOOKS_GET_ALIAS_SET	gnat_get_alias_set
-#undef  LANG_HOOKS_EXPAND_EXPR
-#define LANG_HOOKS_EXPAND_EXPR		gnat_expand_expr
 #undef  LANG_HOOKS_MARK_ADDRESSABLE
 #define LANG_HOOKS_MARK_ADDRESSABLE	gnat_mark_addressable
 #undef  LANG_HOOKS_PRINT_DECL
@@ -609,45 +605,6 @@ gnat_printable_name (tree decl, int verbosity)
   return (const char *) ada_name;
 }
 
-/* Expands GNAT-specific GCC tree nodes.  The only ones we support
-   here are  and NULL_EXPR.  */
-
-static rtx
-gnat_expand_expr (tree exp, rtx target, enum machine_mode tmode,
-		  int modifier, rtx *alt_rtl)
-{
-  tree type = TREE_TYPE (exp);
-  tree new;
-
-  /* Update EXP to be the new expression to expand.  */
-  switch (TREE_CODE (exp))
-    {
-#if 0
-    case ALLOCATE_EXPR:
-      return
-	allocate_dynamic_stack_space
-	  (expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, TYPE_MODE (sizetype),
-			EXPAND_NORMAL),
-	   NULL_RTX, tree_low_cst (TREE_OPERAND (exp, 1), 1));
-#endif
-
-    case UNCONSTRAINED_ARRAY_REF:
-      /* If we are evaluating just for side-effects, just evaluate our
-	 operand.  Otherwise, abort since this code should never appear
-	 in a tree to be evaluated (objects aren't unconstrained).  */
-      if (target == const0_rtx || TREE_CODE (type) == VOID_TYPE)
-	return expand_expr (TREE_OPERAND (exp, 0), const0_rtx,
-			    VOIDmode, modifier);
-
-      /* ... fall through ... */
-
-    default:
-      gcc_unreachable ();
-    }
-
-  return expand_expr_real (new, target, tmode, modifier, alt_rtl);
-}
-
 /* Do nothing (return the tree node passed).  */
 
 static tree
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 7e3eacc..1b3bd44 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -4972,43 +4972,6 @@ finish_label_address_expr (tree label)
 
   return result;
 }
-
-/* Hook used by expand_expr to expand language-specific tree codes.  */
-/* The only things that should go here are bits needed to expand
-   constant initializers.  Everything else should be handled by the
-   gimplification routines.  */
-
-rtx
-c_expand_expr (tree exp, rtx target, enum machine_mode tmode,
-	       int modifiera /* Actually enum expand_modifier.  */,
-	       rtx *alt_rtl)
-{
-  enum expand_modifier modifier = (enum expand_modifier) modifiera;
-  switch (TREE_CODE (exp))
-    {
-    case COMPOUND_LITERAL_EXPR:
-      {
-	/* Initialize the anonymous variable declared in the compound
-	   literal, then return the variable.  */
-	tree decl = COMPOUND_LITERAL_EXPR_DECL (exp);
-	emit_local_var (decl);
-	return expand_expr_real (decl, target, tmode, modifier, alt_rtl);
-      }
-
-    default:
-      gcc_unreachable ();
-    }
-}
-
-/* Hook used by staticp to handle language-specific tree codes.  */
-
-tree
-c_staticp (tree exp)
-{
-  return (TREE_CODE (exp) == COMPOUND_LITERAL_EXPR
-	  && TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (exp))
-	  ? exp : NULL);
-}
 
 
 /* Given a boolean expression ARG, return a tree representing an increment
diff --git a/gcc/c-common.def b/gcc/c-common.def
index 54ebfc4..e69de29 100644
--- a/gcc/c-common.def
+++ b/gcc/c-common.def
@@ -1,38 +0,0 @@
-/* This file contains the definitions and documentation for the
-   additional tree codes used in the GNU C compiler (see tree.def
-   for the standard codes).
-   Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998,
-   1999, 2000, 2001, 2004, 2005, 2007 Free Software Foundation, Inc.
-   Written by Benjamin Chelf <chelf@codesourcery.com>
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-/* Tree nodes used in the C frontend.  These are also shared with the
-   C++ and Objective C frontends.  */
-
-/* A COMPOUND_LITERAL_EXPR represents a C99 compound literal.  The
-   COMPOUND_LITERAL_EXPR_DECL_STMT is the a DECL_STMT containing the decl
-   for the anonymous object represented by the COMPOUND_LITERAL;
-   the DECL_INITIAL of that decl is the CONSTRUCTOR that initializes
-   the compound literal.  */
-DEFTREECODE (COMPOUND_LITERAL_EXPR, "compound_literal_expr", tcc_expression, 1)
-
-/*
-Local variables:
-mode:c
-End:
-*/
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 1094dab..5936dd1 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -793,12 +793,6 @@ extern void finish_file	(void);
 #define STATEMENT_LIST_HAS_LABEL(NODE) \
   TREE_LANG_FLAG_3 (STATEMENT_LIST_CHECK (NODE))
 
-/* COMPOUND_LITERAL_EXPR accessors.  */
-#define COMPOUND_LITERAL_EXPR_DECL_STMT(NODE)		\
-  TREE_OPERAND (COMPOUND_LITERAL_EXPR_CHECK (NODE), 0)
-#define COMPOUND_LITERAL_EXPR_DECL(NODE)			\
-  DECL_EXPR_DECL (COMPOUND_LITERAL_EXPR_DECL_STMT (NODE))
-
 extern int anon_aggr_type_p (const_tree);
 
 /* For a VAR_DECL that is an anonymous union, these are the various
@@ -813,7 +807,6 @@ extern int anon_aggr_type_p (const_tree);
 #define CLEAR_DECL_C_BIT_FIELD(NODE) \
   (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 0)
 
-extern void emit_local_var (tree);
 extern tree do_case (tree, tree);
 extern tree build_stmt (enum tree_code, ...);
 extern tree build_case_label (tree, tree, tree);
@@ -860,10 +853,6 @@ extern tree lookup_name (tree);
 extern bool vector_targets_convertible_p (const_tree t1, const_tree t2);
 extern bool vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note);
 
-extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
-
-extern tree c_staticp (tree);
-
 extern void init_c_lex (void);
 
 extern void c_cpp_builtins (cpp_reader *);
diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c
index 342848a..70351ad 100644
--- a/gcc/c-gimplify.c
+++ b/gcc/c-gimplify.c
@@ -174,145 +174,25 @@ c_build_bind_expr (tree block, tree body)
 
 /* Gimplification of expression trees.  */
 
-/* Gimplify a C99 compound literal expression.  This just means adding
-   the DECL_EXPR before the current statement and using its anonymous
-   decl instead.  */
-
-static enum gimplify_status
-gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p)
-{
-  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
-  tree decl = DECL_EXPR_DECL (decl_s);
-  /* Mark the decl as addressable if the compound literal
-     expression is addressable now, otherwise it is marked too late
-     after we gimplify the initialization expression.  */
-  if (TREE_ADDRESSABLE (*expr_p))
-    TREE_ADDRESSABLE (decl) = 1;
-
-  /* Preliminarily mark non-addressed complex variables as eligible
-     for promotion to gimple registers.  We'll transform their uses
-     as we find them.  */
-  if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
-       || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
-      && !TREE_THIS_VOLATILE (decl)
-      && !needs_to_live_in_memory (decl))
-    DECL_GIMPLE_REG_P (decl) = 1;
-
-  /* This decl isn't mentioned in the enclosing block, so add it to the
-     list of temps.  FIXME it seems a bit of a kludge to say that
-     anonymous artificial vars aren't pushed, but everything else is.  */
-  if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
-    gimple_add_tmp_var (decl);
-
-  gimplify_and_add (decl_s, pre_p);
-  *expr_p = decl;
-  return GS_OK;
-}
-
-/* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
-   return a new CONSTRUCTOR if something changed.  */
-
-static tree
-optimize_compound_literals_in_ctor (tree orig_ctor)
-{
-  tree ctor = orig_ctor;
-  VEC(constructor_elt,gc) *elts = CONSTRUCTOR_ELTS (ctor);
-  unsigned int idx, num = VEC_length (constructor_elt, elts);
-
-  for (idx = 0; idx < num; idx++)
-    {
-      tree value = VEC_index (constructor_elt, elts, idx)->value;
-      tree newval = value;
-      if (TREE_CODE (value) == CONSTRUCTOR)
-	newval = optimize_compound_literals_in_ctor (value);
-      else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
-	{
-	  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (value);
-	  tree decl = DECL_EXPR_DECL (decl_s);
-	  tree init = DECL_INITIAL (decl);
-
-	  if (!TREE_ADDRESSABLE (value)
-	      && !TREE_ADDRESSABLE (decl)
-	      && init)
-	    newval = init;
-	}
-      if (newval == value)
-	continue;
-
-      if (ctor == orig_ctor)
-	{
-	  ctor = copy_node (orig_ctor);
-	  CONSTRUCTOR_ELTS (ctor) = VEC_copy (constructor_elt, gc, elts);
-	  elts = CONSTRUCTOR_ELTS (ctor);
-	}
-      VEC_index (constructor_elt, elts, idx)->value = newval;
-    }
-  return ctor;
-}
-
 /* Do C-specific gimplification on *EXPR_P.  PRE_P and POST_P are as in
    gimplify_expr.  */
 
 int
-c_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
+c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
 		 gimple_seq *post_p ATTRIBUTE_UNUSED)
 {
   enum tree_code code = TREE_CODE (*expr_p);
 
-  switch (code)
-    {
-    case DECL_EXPR:
-      /* This is handled mostly by gimplify.c, but we have to deal with
-	 not warning about int x = x; as it is a GCC extension to turn off
-	 this warning but only if warn_init_self is zero.  */
-      if (TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
-	  && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
-	  && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
-	  && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p))
-	      == DECL_EXPR_DECL (*expr_p))
-	  && !warn_init_self)
-	TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
-      return GS_UNHANDLED;
-
-    case COMPOUND_LITERAL_EXPR:
-      return gimplify_compound_literal_expr (expr_p, pre_p);
-
-    case INIT_EXPR:
-    case MODIFY_EXPR:
-      if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == COMPOUND_LITERAL_EXPR)
-	{
-	  tree complit = TREE_OPERAND (*expr_p, 1);
-	  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (complit);
-	  tree decl = DECL_EXPR_DECL (decl_s);
-	  tree init = DECL_INITIAL (decl);
-
-	  /* struct T x = (struct T) { 0, 1, 2 } can be optimized
-	     into struct T x = { 0, 1, 2 } if the address of the
-	     compound literal has never been taken.  */
-	  if (!TREE_ADDRESSABLE (complit)
-	      && !TREE_ADDRESSABLE (decl)
-	      && init)
-	    {
-	      *expr_p = copy_node (*expr_p);
-	      TREE_OPERAND (*expr_p, 1) = init;
-	      return GS_OK;
-	    }
-	}
-      else if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR)
-	{
-	  tree ctor
-	    = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
-
-	  if (ctor != TREE_OPERAND (*expr_p, 1))
-	    {
-	      *expr_p = copy_node (*expr_p);
-	      TREE_OPERAND (*expr_p, 1) = ctor;
-	      return GS_OK;
-	    }
-	}
-      return GS_UNHANDLED;
-
-    default:
-      return GS_UNHANDLED;
-    }
+  /* This is handled mostly by gimplify.c, but we have to deal with
+     not warning about int x = x; as it is a GCC extension to turn off
+     this warning but only if warn_init_self is zero.  */
+  if (code == DECL_EXPR
+      && TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
+      && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
+      && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
+      && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p))
+      && !warn_init_self)
+    TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
+
+  return GS_UNHANDLED;
 }
diff --git a/gcc/c-objc-common.h b/gcc/c-objc-common.h
index c48838c..14a714e 100644
--- a/gcc/c-objc-common.h
+++ b/gcc/c-objc-common.h
@@ -43,8 +43,6 @@ extern void c_initialize_diagnostics (diagnostic_context *);
 #define LANG_HOOKS_POST_OPTIONS c_common_post_options
 #undef LANG_HOOKS_GET_ALIAS_SET
 #define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set
-#undef LANG_HOOKS_EXPAND_EXPR
-#define LANG_HOOKS_EXPAND_EXPR c_expand_expr
 #undef LANG_HOOKS_EXPAND_DECL
 #define LANG_HOOKS_EXPAND_DECL c_expand_decl
 #undef LANG_HOOKS_MARK_ADDRESSABLE
@@ -53,8 +51,6 @@ extern void c_initialize_diagnostics (diagnostic_context *);
 #define LANG_HOOKS_PARSE_FILE c_common_parse_file
 #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
 #define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl
-#undef LANG_HOOKS_STATICP
-#define LANG_HOOKS_STATICP c_staticp
 #undef LANG_HOOKS_NO_BODY_BLOCKS
 #define LANG_HOOKS_NO_BODY_BLOCKS true
 #undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c
index 62faee5..c457eeb 100644
--- a/gcc/c-semantics.c
+++ b/gcc/c-semantics.c
@@ -1,6 +1,4 @@
-/* This file contains the definitions and documentation for the common
-   tree codes used in the GNU C and C++ compilers (see c-common.def
-   for the standard codes).
+/* This file contains subroutine used by the C front-end to construct GENERIC.
    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007
    Free Software Foundation, Inc.
    Written by Benjamin Chelf (chelf@codesourcery.com).
@@ -145,23 +143,6 @@ build_stmt (enum tree_code code, ...)
   return ret;
 }
 
-/* Let the back-end know about DECL.  */
-
-void
-emit_local_var (tree decl)
-{
-  /* Create RTL for this variable.  */
-  if (!DECL_RTL_SET_P (decl))
-    {
-      if (DECL_HARD_REGISTER (decl))
-	/* The user specified an assembler name for this variable.
-	   Set that up now.  */
-	rest_of_decl_compilation (decl, 0, 0);
-      else
-	expand_decl (decl);
-    }
-}
-
 /* Create a CASE_LABEL_EXPR tree node and return it.  */
 
 tree
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 0396344..fd64e3d 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -222,7 +222,7 @@ c++.stagefeedback: stagefeedback-start
 #
 # .o: .h dependencies.
 CXX_TREE_H = $(TREE_H) cp/name-lookup.h cp/cp-tree.h $(C_COMMON_H) \
-	c-common.def $(FUNCTION_H) $(VARRAY_H) \
+	$(FUNCTION_H) $(VARRAY_H) \
 	$(SYSTEM_H) coretypes.h $(CONFIG_H) $(TARGET_H) $(GGC_H) \
 	$(srcdir)/../include/hashtab.h $(srcdir)/../include/splay-tree.h
 
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index 46e045e..9443047 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -52,8 +52,6 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
 #define LANG_HOOKS_POST_OPTIONS c_common_post_options
 #undef LANG_HOOKS_GET_ALIAS_SET
 #define LANG_HOOKS_GET_ALIAS_SET cxx_get_alias_set
-#undef LANG_HOOKS_EXPAND_EXPR
-#define LANG_HOOKS_EXPAND_EXPR c_expand_expr
 #undef LANG_HOOKS_EXPAND_DECL
 #define LANG_HOOKS_EXPAND_DECL c_expand_decl
 #undef LANG_HOOKS_PARSE_FILE
diff --git a/gcc/doc/c-tree.texi b/gcc/doc/c-tree.texi
index 6eef7d1..3f1047f 100644
--- a/gcc/doc/c-tree.texi
+++ b/gcc/doc/c-tree.texi
@@ -2636,10 +2636,10 @@ declaration order.  You should not assume that all fields will be
 represented.  Unrepresented fields will be set to zero.
 
 @item COMPOUND_LITERAL_EXPR
-@findex COMPOUND_LITERAL_EXPR_DECL_STMT
+@findex COMPOUND_LITERAL_EXPR_DECL_EXPR
 @findex COMPOUND_LITERAL_EXPR_DECL
 These nodes represent ISO C99 compound literals.  The
-@code{COMPOUND_LITERAL_EXPR_DECL_STMT} is a @code{DECL_STMT}
+@code{COMPOUND_LITERAL_EXPR_DECL_EXPR} is a @code{DECL_EXPR}
 containing an anonymous @code{VAR_DECL} for
 the unnamed object represented by the compound literal; the
 @code{DECL_INITIAL} of that @code{VAR_DECL} is a @code{CONSTRUCTOR}
diff --git a/gcc/expr.c b/gcc/expr.c
index 1d994c5..b514f2e 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6806,9 +6806,10 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
 	 CONSTRUCTORs too, which should yield a memory reference for the
 	 constructor's contents.  Assume language specific tree nodes can
 	 be expanded in some interesting way.  */
+      gcc_assert (TREE_CODE (exp) < LAST_AND_UNUSED_TREE_CODE);
       if (DECL_P (exp)
 	  || TREE_CODE (exp) == CONSTRUCTOR
-	  || TREE_CODE (exp) >= LAST_AND_UNUSED_TREE_CODE)
+	  || TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
 	{
 	  result = expand_expr (exp, target, tmode,
 				modifier == EXPAND_INITIALIZER
@@ -8042,11 +8043,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
 	/* Check for a built-in function.  */
 	if (fndecl && DECL_BUILT_IN (fndecl))
 	  {
-	    if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_FRONTEND)
-	      return lang_hooks.expand_expr (exp, original_target,
-					     tmode, modifier, alt_rtl);
-	    else
-	      return expand_builtin (exp, target, subtarget, tmode, ignore);
+	    gcc_assert (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_FRONTEND);
+	    return expand_builtin (exp, target, subtarget, tmode, ignore);
 	  }
       }
       return expand_call (exp, target, ignore);
@@ -9425,9 +9423,29 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
       mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
       goto binop;
 
+    case COMPOUND_LITERAL_EXPR:
+      {
+	/* Initialize the anonymous variable declared in the compound
+	   literal, then return the variable.  */
+	tree decl = COMPOUND_LITERAL_EXPR_DECL (exp);
+
+	/* Create RTL for this variable.  */
+	if (!DECL_RTL_SET_P (decl))
+	  {
+	    if (DECL_HARD_REGISTER (decl))
+	      /* The user specified an assembler name for this variable.
+	         Set that up now.  */
+	      rest_of_decl_compilation (decl, 0, 0);
+	    else
+	      expand_decl (decl);
+	  }
+
+	return expand_expr_real (decl, original_target, tmode,
+				 modifier, alt_rtl);
+      }
+
     default:
-      return lang_hooks.expand_expr (exp, original_target, tmode,
-				     modifier, alt_rtl);
+      gcc_unreachable ();
     }
 
   /* Here to do an ordinary binary operator.  */
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index a139495..1edf933 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -3482,6 +3482,83 @@ rhs_predicate_for (tree lhs)
     return is_gimple_mem_or_call_rhs;
 }
 
+/* Gimplify a C99 compound literal expression.  This just means adding
+   the DECL_EXPR before the current statement and using its anonymous
+   decl instead.  */
+
+static enum gimplify_status
+gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p)
+{
+  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
+  tree decl = DECL_EXPR_DECL (decl_s);
+  /* Mark the decl as addressable if the compound literal
+     expression is addressable now, otherwise it is marked too late
+     after we gimplify the initialization expression.  */
+  if (TREE_ADDRESSABLE (*expr_p))
+    TREE_ADDRESSABLE (decl) = 1;
+
+  /* Preliminarily mark non-addressed complex variables as eligible
+     for promotion to gimple registers.  We'll transform their uses
+     as we find them.  */
+  if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
+       || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
+      && !TREE_THIS_VOLATILE (decl)
+      && !needs_to_live_in_memory (decl))
+    DECL_GIMPLE_REG_P (decl) = 1;
+
+  /* This decl isn't mentioned in the enclosing block, so add it to the
+     list of temps.  FIXME it seems a bit of a kludge to say that
+     anonymous artificial vars aren't pushed, but everything else is.  */
+  if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
+    gimple_add_tmp_var (decl);
+
+  gimplify_and_add (decl_s, pre_p);
+  *expr_p = decl;
+  return GS_OK;
+}
+
+/* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
+   return a new CONSTRUCTOR if something changed.  */
+
+static tree
+optimize_compound_literals_in_ctor (tree orig_ctor)
+{
+  tree ctor = orig_ctor;
+  VEC(constructor_elt,gc) *elts = CONSTRUCTOR_ELTS (ctor);
+  unsigned int idx, num = VEC_length (constructor_elt, elts);
+
+  for (idx = 0; idx < num; idx++)
+    {
+      tree value = VEC_index (constructor_elt, elts, idx)->value;
+      tree newval = value;
+      if (TREE_CODE (value) == CONSTRUCTOR)
+	newval = optimize_compound_literals_in_ctor (value);
+      else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
+	{
+	  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
+	  tree decl = DECL_EXPR_DECL (decl_s);
+	  tree init = DECL_INITIAL (decl);
+
+	  if (!TREE_ADDRESSABLE (value)
+	      && !TREE_ADDRESSABLE (decl)
+	      && init)
+	    newval = optimize_compound_literals_in_ctor (init);
+	}
+      if (newval == value)
+	continue;
+
+      if (ctor == orig_ctor)
+	{
+	  ctor = copy_node (orig_ctor);
+	  CONSTRUCTOR_ELTS (ctor) = VEC_copy (constructor_elt, gc, elts);
+	  elts = CONSTRUCTOR_ELTS (ctor);
+	}
+      VEC_index (constructor_elt, elts, idx)->value = newval;
+    }
+  return ctor;
+}
+
+
 
 /* A subroutine of gimplify_modify_expr.  Break out elements of a
    CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
@@ -3500,7 +3577,7 @@ static enum gimplify_status
 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 			   bool want_value, bool notify_temp_creation)
 {
-  tree object;
+  tree object, new_ctor;
   tree ctor = TREE_OPERAND (*expr_p, 1);
   tree type = TREE_TYPE (ctor);
   enum gimplify_status ret;
@@ -3518,7 +3595,8 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
     }
 
   object = TREE_OPERAND (*expr_p, 0);
-  elts = CONSTRUCTOR_ELTS (ctor);
+  new_ctor = optimize_compound_literals_in_ctor (ctor);
+  elts = CONSTRUCTOR_ELTS (new_ctor);
   ret = GS_ALL_DONE;
 
   switch (TREE_CODE (type))
@@ -4116,6 +4194,26 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
 	  return GS_OK;
 	}
 	
+      case COMPOUND_LITERAL_EXPR:
+	{
+	  tree complit = TREE_OPERAND (*expr_p, 1);
+	  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
+	  tree decl = DECL_EXPR_DECL (decl_s);
+	  tree init = DECL_INITIAL (decl);
+
+	  /* struct T x = (struct T) { 0, 1, 2 } can be optimized
+	     into struct T x = { 0, 1, 2 } if the address of the
+	     compound literal has never been taken.  */
+	  if (!TREE_ADDRESSABLE (complit)
+	      && !TREE_ADDRESSABLE (decl)
+	      && init)
+	    {
+	      *expr_p = copy_node (*expr_p);
+	      TREE_OPERAND (*expr_p, 1) = init;
+	      return GS_OK;
+	    }
+	}
+
       default:
 	ret = GS_UNHANDLED;
 	break;
@@ -6336,6 +6434,10 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	  ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
 	  break;
 
+	case COMPOUND_LITERAL_EXPR:
+	  ret = gimplify_compound_literal_expr (expr_p, pre_p);
+	  break;
+
 	case MODIFY_EXPR:
 	case INIT_EXPR:
 	  ret = gimplify_modify_expr (expr_p, pre_p, post_p,
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 860881f..b9f28be 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -50,7 +50,6 @@ extern void lhd_print_tree_nothing (FILE *, tree, int);
 extern const char *lhd_decl_printable_name (tree, int);
 extern const char *lhd_dwarf_name (tree, int);
 extern int lhd_types_compatible_p (tree, tree);
-extern rtx lhd_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
 extern int lhd_expand_decl (tree);
 extern void lhd_print_error_function (struct diagnostic_context *,
 				      const char *, struct diagnostic_info *);
@@ -92,7 +91,6 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
 #define LANG_HOOKS_POST_OPTIONS		lhd_post_options
 #define LANG_HOOKS_MISSING_NORETURN_OK_P hook_bool_tree_true
 #define LANG_HOOKS_GET_ALIAS_SET	lhd_get_alias_set
-#define LANG_HOOKS_EXPAND_EXPR		lhd_expand_expr
 #define LANG_HOOKS_EXPAND_DECL		lhd_expand_decl
 #define LANG_HOOKS_FINISH_INCOMPLETE_DECL lhd_do_nothing_t
 #define LANG_HOOKS_STATICP		lhd_staticp
@@ -258,7 +256,6 @@ extern void lhd_end_section (void);
   LANG_HOOKS_PARSE_FILE, \
   LANG_HOOKS_MISSING_NORETURN_OK_P, \
   LANG_HOOKS_GET_ALIAS_SET, \
-  LANG_HOOKS_EXPAND_EXPR, \
   LANG_HOOKS_EXPAND_DECL, \
   LANG_HOOKS_FINISH_INCOMPLETE_DECL, \
   LANG_HOOKS_MARK_ADDRESSABLE, \
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 575d05c..f46a450 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -217,17 +217,6 @@ lhd_get_alias_set (tree ARG_UNUSED (t))
   return -1;
 }
 
-/* This is the default expand_expr function.  */
-
-rtx
-lhd_expand_expr (tree ARG_UNUSED (t), rtx ARG_UNUSED (r),
-		 enum machine_mode ARG_UNUSED (mm),
-		 int ARG_UNUSED (em),
-		 rtx * ARG_UNUSED (a))
-{
-  gcc_unreachable ();
-}
-
 /* The default language-specific function for expanding a decl.  After
    the language-independent cases are handled, this function will be
    called.  If this function is not defined, it is assumed that
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 4342645..adfb64e 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -310,10 +310,6 @@ struct lang_hooks
      Returns -1 if the language does nothing special for it.  */
   alias_set_type (*get_alias_set) (tree);
 
-  /* Called by expand_expr for language-specific tree codes.
-     Fourth argument is actually an enum expand_modifier.  */
-  rtx (*expand_expr) (tree, rtx, enum machine_mode, int, rtx *);
-
   /* Called by expand_expr to generate the definition of a decl.  Returns
      1 if handled, 0 otherwise.  */
   int (*expand_decl) (tree);
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index 3ca408b..d60cbf1 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -25,7 +25,6 @@ Boston, MA 02110-1301, USA.  */
 #include "flags.h"
 #include "tm.h"
 #include "tree.h"
-#include "expr.h"
 #include "target.h"
 #include "langhooks.h"
 #include "langhooks-def.h"
@@ -893,69 +892,6 @@ lto_register_builtin_type (tree type, const char *name)
   registered_builtin_types = tree_cons (0, type, registered_builtin_types);
 }
 
-/* FIXME lto: COMPOUND_LITERAL_EXPR is specific to the C-family front ends
-   but is not removed by the gimplifier when it appears in an initializer.
-   It is likely that we will simply want to add it to the language-independent
-   IR, but a less intrusive solution is to simply implement the same langhooks
-   in lto1 that cc1 and cc1plus use.  */
-
-/* COMPOUND_LITERAL_EXPR accessors.  Cribbed from c-common.h.  */
-#define COMPOUND_LITERAL_EXPR_DECL_STMT(NODE)		\
-  TREE_OPERAND (COMPOUND_LITERAL_EXPR_CHECK (NODE), 0)
-#define COMPOUND_LITERAL_EXPR_DECL(NODE)			\
-  DECL_EXPR_DECL (COMPOUND_LITERAL_EXPR_DECL_STMT (NODE))
-
-/* Let the back-end know about DECL.  Cribbed from the c-semantics.c.  */
-static void
-emit_local_var (tree decl)
-{
-  /* Create RTL for this variable.  */
-  if (!DECL_RTL_SET_P (decl))
-    {
-      if (DECL_HARD_REGISTER (decl))
-	/* The user specified an assembler name for this variable.
-	   Set that up now.  */
-	rest_of_decl_compilation (decl, 0, 0);
-      else
-	expand_decl (decl);
-    }
-}
-
-/* Hook used by expand_expr to expand language-specific tree codes.
-   The only things that should go here are bits needed to expand
-   constant initializers.  Cribbed from c-common.c.  */
-static rtx
-lto_expand_expr (tree exp, rtx target, enum machine_mode tmode,
-	       int modifiera /* Actually enum expand_modifier.  */,
-	       rtx *alt_rtl)
-{
-  enum expand_modifier modifier = (enum expand_modifier) modifiera;
-  switch (TREE_CODE (exp))
-    {
-    case COMPOUND_LITERAL_EXPR:
-      {
-	/* Initialize the anonymous variable declared in the compound
-	   literal, then return the variable.  */
-	tree decl = COMPOUND_LITERAL_EXPR_DECL (exp);
-	emit_local_var (decl);
-	return expand_expr_real (decl, target, tmode, modifier, alt_rtl);
-      }
-
-    default:
-      gcc_unreachable ();
-    }
-}
-
-/* Hook used by staticp to handle language-specific tree codes.
-   Cribbed from c-common.c.  */
-static tree
-lto_staticp (tree exp)
-{
-  return (TREE_CODE (exp) == COMPOUND_LITERAL_EXPR
-	  && TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (exp))
-	  ? exp : NULL);
-}
-
 /* Build nodes that would have be created by the C front-end; necessary
    for including builtin-types.def and ultimately builtins.def.  */
 
@@ -1102,11 +1038,6 @@ static void lto_init_ts (void)
 #undef LANG_HOOKS_INIT_TS
 #define LANG_HOOKS_INIT_TS lto_init_ts
 
-#undef LANG_HOOKS_EXPAND_EXPR
-#define LANG_HOOKS_EXPAND_EXPR lto_expand_expr
-#undef LANG_HOOKS_STATICP
-#define LANG_HOOKS_STATICP lto_staticp
-
 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
 /* Language hooks that are not part of lang_hooks.  */
diff --git a/gcc/tree.c b/gcc/tree.c
index cdec95e..72c7891 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -2174,7 +2174,10 @@ staticp (tree arg)
 	  && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST)
 	return staticp (TREE_OPERAND (arg, 0));
       else
-	return false;
+	return NULL;
+
+    case COMPOUND_LITERAL_EXPR:
+      return TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (arg)) ? arg : NULL;
 
     default:
       if ((unsigned int) TREE_CODE (arg)
diff --git a/gcc/tree.def b/gcc/tree.def
index e9c8917..e43c286 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -768,6 +768,13 @@ DEFTREECODE (NON_LVALUE_EXPR, "non_lvalue_expr", tcc_unary, 1)
    generating insns.  */
 DEFTREECODE (VIEW_CONVERT_EXPR, "view_convert_expr", tcc_reference, 1)
 
+/* A COMPOUND_LITERAL_EXPR represents a literal that is placed in a DECL.  The
+   COMPOUND_LITERAL_EXPR_DECL_EXPR is the a DECL_EXPR containing the decl
+   for the anonymous object represented by the COMPOUND_LITERAL;
+   the DECL_INITIAL of that decl is the CONSTRUCTOR that initializes
+   the compound literal.  */
+DEFTREECODE (COMPOUND_LITERAL_EXPR, "compound_literal_expr", tcc_expression, 1)
+
 /* Represents something we computed once and will use multiple times.
    First operand is that expression.  After it is evaluated once, it
    will be replaced by the temporary variable that holds the value.  */
diff --git a/gcc/tree.h b/gcc/tree.h
index f81ba73..4bca3d4 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1605,6 +1605,12 @@ struct tree_constructor GTY(())
 
 #define EXIT_EXPR_COND(NODE)	     TREE_OPERAND (EXIT_EXPR_CHECK (NODE), 0)
 
+/* COMPOUND_LITERAL_EXPR accessors.  */
+#define COMPOUND_LITERAL_EXPR_DECL_EXPR(NODE)		\
+  TREE_OPERAND (COMPOUND_LITERAL_EXPR_CHECK (NODE), 0)
+#define COMPOUND_LITERAL_EXPR_DECL(NODE)			\
+  DECL_EXPR_DECL (COMPOUND_LITERAL_EXPR_DECL_EXPR (NODE))
+
 /* SWITCH_EXPR accessors. These give access to the condition, body and
    original condition type (before any compiler conversions)
    of the switch statement, respectively.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]