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: Fix ipa-devirt WRT type variants


> 
> Btw - this points to the "obvious" opportunity to make variant types
> a lot smaller (with the caveat to require an indirection to the main
> variant to access shared bits).  That would also automagically
> help LTO streaming ....

Yeah, I was playing with this idea.  Lets get things checked and consistent first
and then we can play with this. Changing memory representation of tree types
would be quite a project...

Honza
> 
> Richard.
> 
> >  /* TYPE is equivalent to VAL by ODR, but its tree representation differs
> >     from VAL->type.  This may happen in LTO where tree merging did not merge
> >     all variants of the same type.  It may or may not mean the ODR violation.
> > @@ -446,16 +457,17 @@ add_type_duplicate (odr_type val, tree t
> >             {
> >               unsigned int i;
> >
> > -             TYPE_BINFO (val->type) = TYPE_BINFO (type);
> > +             set_type_binfo (val->type, TYPE_BINFO (type));
> >               for (i = 0; i < val->types->length (); i++)
> >                 {
> >                   if (TYPE_BINFO ((*val->types)[i])
> >                       == master_binfo)
> > -                   TYPE_BINFO ((*val->types)[i]) = TYPE_BINFO (type);
> > +                   set_type_binfo ((*val->types)[i], TYPE_BINFO (type));
> >                 }
> > +             BINFO_TYPE (TYPE_BINFO (type)) = val->type;
> >             }
> >           else
> > -           TYPE_BINFO (type) = master_binfo;
> > +           set_type_binfo (type, master_binfo);
> >         }
> >      }
> >  }
> > @@ -495,6 +507,7 @@ get_odr_type (tree type, bool insert)
> >
> >        val = ggc_cleared_alloc<odr_type_d> ();
> >        val->type = type;
> > +      gcc_assert (BINFO_TYPE (TYPE_BINFO (val->type)) = type);
> >        val->bases = vNULL;
> >        val->derived_types = vNULL;
> >        val->anonymous_namespace = type_in_anonymous_namespace_p (type);
> > @@ -1102,7 +1115,7 @@ get_class_context (ipa_polymorphic_call_
> >           if (!fld)
> >             goto give_up;
> >
> > -         type = TREE_TYPE (fld);
> > +         type = TYPE_MAIN_VARIANT (TREE_TYPE (fld));
> >           offset -= pos;
> >           /* DECL_ARTIFICIAL represents a basetype.  */
> >           if (!DECL_ARTIFICIAL (fld))
> > @@ -1116,7 +1129,7 @@ get_class_context (ipa_polymorphic_call_
> >         }
> >        else if (TREE_CODE (type) == ARRAY_TYPE)
> >         {
> > -         tree subtype = TREE_TYPE (type);
> > +         tree subtype = TYPE_MAIN_VARIANT (TREE_TYPE (type));
> >
> >           /* Give up if we don't know array size.  */
> >           if (!tree_fits_shwi_p (TYPE_SIZE (subtype))
> > @@ -1159,7 +1172,8 @@ static bool
> >  contains_type_p (tree outer_type, HOST_WIDE_INT offset,
> >                  tree otr_type)
> >  {
> > -  ipa_polymorphic_call_context context = {offset, outer_type,
> > +  ipa_polymorphic_call_context context = {offset,
> > +                                         TYPE_MAIN_VARIANT (outer_type),
> >                                           false, true};
> >    return get_class_context (&context, otr_type);
> >  }
> > @@ -1272,7 +1286,7 @@ get_polymorphic_call_info_for_decl (ipa_
> >  {
> >    gcc_assert (DECL_P (base));
> >
> > -  context->outer_type = TREE_TYPE (base);
> > +  context->outer_type = TYPE_MAIN_VARIANT (TREE_TYPE (base));
> >    context->offset = offset;
> >    /* Make very conservative assumption that all objects
> >       may be in construction.
> > @@ -1329,7 +1343,7 @@ get_polymorphic_call_info (tree fndecl,
> >    *otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (ref));
> >
> >    /* Set up basic info in case we find nothing interesting in the analysis.  */
> > -  context->outer_type = *otr_type;
> > +  context->outer_type = TYPE_MAIN_VARIANT (*otr_type);
> >    context->offset = 0;
> >    base_pointer = OBJ_TYPE_REF_OBJECT (ref);
> >    context->maybe_derived_type = true;
> > @@ -1415,7 +1429,8 @@ get_polymorphic_call_info (tree fndecl,
> >        if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE
> >           && SSA_NAME_VAR (base_pointer) == DECL_ARGUMENTS (fndecl))
> >         {
> > -         context->outer_type = TREE_TYPE (TREE_TYPE (base_pointer));
> > +         context->outer_type
> > +            = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer)));
> >           gcc_assert (TREE_CODE (context->outer_type) == RECORD_TYPE);
> >
> >           /* Dynamic casting has possibly upcasted the type
> > @@ -1450,7 +1465,8 @@ get_polymorphic_call_info (tree fndecl,
> >          object.  */
> >        if (DECL_BY_REFERENCE (SSA_NAME_VAR (base_pointer)))
> >         {
> > -         context->outer_type = TREE_TYPE (TREE_TYPE (base_pointer));
> > +         context->outer_type
> > +            = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer)));
> >           gcc_assert (!POINTER_TYPE_P (context->outer_type));
> >           /* Only type inconsistent programs can have otr_type that is
> >              not part of outer type.  */
> > @@ -1599,6 +1615,8 @@ possible_polymorphic_call_targets (tree
> >    bool can_refer;
> >    bool skipped = false;
> >
> > +  otr_type = TYPE_MAIN_VARIANT (otr_type);
> > +
> >    /* If ODR is not initialized, return empty incomplete list.  */
> >    if (!odr_hash)
> >      {
> > @@ -1625,6 +1643,10 @@ possible_polymorphic_call_targets (tree
> >
> >    type = get_odr_type (otr_type, true);
> >
> > +  /* Recording type variants would wast results cache.  */
> > +  gcc_assert (!context.outer_type
> > +             || TYPE_MAIN_VARIANT (context.outer_type) == context.outer_type);
> > +
> >    /* Lookup the outer class type we want to walk.  */
> >    if (context.outer_type
> >        && !get_class_context (&context, otr_type))
> > @@ -1638,6 +1660,10 @@ possible_polymorphic_call_targets (tree
> >        return nodes;
> >      }
> >
> > +  /* Check that get_class_context kept the main variant.  */
> > +  gcc_assert (!context.outer_type
> > +             || TYPE_MAIN_VARIANT (context.outer_type) == context.outer_type);
> > +
> >    /* We canonicalize our query, so we do not need extra hashtable entries.  */
> >
> >    /* Without outer type, we have no use for offset.  Just do the


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