On Mon, 11 Nov 2013, Richard Biener wrote:

> 
> The following patch removes now dead code from input_gimple_stmt
> (which also could be quite slow).  Type mismatches can only
> occur at the decl level after the new tree merging code went
> in and those are handed by wrapping all decls in MEM_REFs to
> transparently have them view-converted.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu, LTO bootstrap
> in progress.

Applied with making sure to also do the MEM_REF wrapping in addresses.

LTO bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2013-11-13  Richard Biener  <rguent...@suse.de>

        * gimple-streamer-out.c (output_gimple_stmt): Also wrap
        decls in ADDR_EXPR operands inside a MEM_REF and optimize that.
        * gimple-streamer-in.c (input_gimple_stmt): Remove now dead
        code dealing with type mismatches inside component reference
        chains.

Index: gcc/gimple-streamer-out.c
===================================================================
*** gcc/gimple-streamer-out.c   (revision 204664)
--- gcc/gimple-streamer-out.c   (working copy)
*************** output_gimple_stmt (struct output_block
*** 129,134 ****
--- 129,136 ----
          if (op && (i || !is_gimple_debug (stmt)))
            {
              basep = &op;
+             if (TREE_CODE (*basep) == ADDR_EXPR)
+               basep = &TREE_OPERAND (*basep, 0);
              while (handled_component_p (*basep))
                basep = &TREE_OPERAND (*basep, 0);
              if (TREE_CODE (*basep) == VAR_DECL
*************** output_gimple_stmt (struct output_block
*** 136,145 ****
                  && !DECL_REGISTER (*basep))
                {
                  bool volatilep = TREE_THIS_VOLATILE (*basep);
                  *basep = build2 (MEM_REF, TREE_TYPE (*basep),
!                                  build_fold_addr_expr (*basep),
!                                  build_int_cst (build_pointer_type
!                                                 (TREE_TYPE (*basep)), 0));
                  TREE_THIS_VOLATILE (*basep) = volatilep;
                }
              else
--- 138,147 ----
                  && !DECL_REGISTER (*basep))
                {
                  bool volatilep = TREE_THIS_VOLATILE (*basep);
+                 tree ptrtype = build_pointer_type (TREE_TYPE (*basep));
                  *basep = build2 (MEM_REF, TREE_TYPE (*basep),
!                                  build1 (ADDR_EXPR, ptrtype, *basep),
!                                  build_int_cst (ptrtype, 0));
                  TREE_THIS_VOLATILE (*basep) = volatilep;
                }
              else
Index: gcc/gimple-streamer-in.c
===================================================================
*** gcc/gimple-streamer-in.c    (revision 204664)
--- gcc/gimple-streamer-in.c    (working copy)
*************** input_gimple_stmt (struct lto_input_bloc
*** 158,242 ****
          if (TREE_CODE (*opp) == ADDR_EXPR)
            opp = &TREE_OPERAND (*opp, 0);
          while (handled_component_p (*opp))
!           {
!             if (TREE_CODE (*opp) == COMPONENT_REF)
!               {
!                 /* Fixup FIELD_DECLs in COMPONENT_REFs, they are not handled
!                    by decl merging.  */
!                 tree field, type, tem;
!                 tree closest_match = NULL_TREE;
!                 field = TREE_OPERAND (*opp, 1);
!                 type = DECL_CONTEXT (field);
!                 for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
!                   {
!                     if (TREE_CODE (tem) != FIELD_DECL)
!                       continue;
!                     if (tem == field)
!                       break;
!                     if (DECL_NONADDRESSABLE_P (tem)
!                         == DECL_NONADDRESSABLE_P (field)
!                         && gimple_compare_field_offset (tem, field))
!                       {
!                         if (types_compatible_p (TREE_TYPE (tem),
!                                                 TREE_TYPE (field)))
!                           break;
!                         else
!                           closest_match = tem;
!                       }
!                   }
!                 /* In case of type mismatches across units we can fail
!                    to unify some types and thus not find a proper
!                    field-decl here.  */
!                 if (tem == NULL_TREE)
!                   {
!                     /* Thus, emit a ODR violation warning.  */
!                     if (warning_at (gimple_location (stmt), 0,
!                                     "use of type %<%E%> with two mismatching "
!                                     "declarations at field %<%E%>",
!                                     type, TREE_OPERAND (*opp, 1)))
!                       {
!                         if (TYPE_FIELDS (type))
!                           inform (DECL_SOURCE_LOCATION (TYPE_FIELDS (type)),
!                                   "original type declared here");
!                         inform (DECL_SOURCE_LOCATION (TREE_OPERAND (*opp, 1)),
!                                 "field in mismatching type declared here");
!                         if (TYPE_NAME (TREE_TYPE (field))
!                             && (TREE_CODE (TYPE_NAME (TREE_TYPE (field)))
!                                 == TYPE_DECL))
!                           inform (DECL_SOURCE_LOCATION
!                                     (TYPE_NAME (TREE_TYPE (field))),
!                                   "type of field declared here");
!                         if (closest_match
!                             && TYPE_NAME (TREE_TYPE (closest_match))
!                             && (TREE_CODE (TYPE_NAME
!                                  (TREE_TYPE (closest_match))) == TYPE_DECL))
!                           inform (DECL_SOURCE_LOCATION
!                                     (TYPE_NAME (TREE_TYPE (closest_match))),
!                                   "type of mismatching field declared here");
!                       }
!                     /* And finally fixup the types.  */
!                     TREE_OPERAND (*opp, 0)
!                       = build1 (VIEW_CONVERT_EXPR, type,
!                                 TREE_OPERAND (*opp, 0));
!                   }
!                 else
!                   TREE_OPERAND (*opp, 1) = tem;
!               }
!             else if ((TREE_CODE (*opp) == ARRAY_REF
!                       || TREE_CODE (*opp) == ARRAY_RANGE_REF)
!                      && (TREE_CODE (TREE_TYPE (TREE_OPERAND (*opp, 0)))
!                          != ARRAY_TYPE))
!               {
!                 /* And ARRAY_REFs to objects that had mismatched types
!                    during symbol merging to avoid ICEs.  */
!                 TREE_OPERAND (*opp, 0)
!                   = build1 (VIEW_CONVERT_EXPR,
!                             build_array_type (TREE_TYPE (*opp), NULL_TREE),
!                             TREE_OPERAND (*opp, 0));
!               }
! 
!             opp = &TREE_OPERAND (*opp, 0);
!           }
          /* At LTO output time we wrap all global decls in MEM_REFs to
             allow seamless replacement with prevailing decls.  Undo this
             here if the prevailing decl allows for this.
--- 158,164 ----
          if (TREE_CODE (*opp) == ADDR_EXPR)
            opp = &TREE_OPERAND (*opp, 0);
          while (handled_component_p (*opp))
!           opp = &TREE_OPERAND (*opp, 0);
          /* At LTO output time we wrap all global decls in MEM_REFs to
             allow seamless replacement with prevailing decls.  Undo this
             here if the prevailing decl allows for this.

Reply via email to