On Tue, 18 Feb 2014, Jan Hubicka wrote:

> > > Non-ODR types born from other frontends will then need to be made to 
> > > alias all the ODR variants that can be done by storing them into the 
> > > current canonical type hash.
> > > (I wonder if we want to support cross language aliasing for non-POD?)
> > 
> > Surely for accessing components of non-POD types, no?  Like
> > 
> > class Foo {
> > Foo();
> > int *get_data ();
> > int *data;
> > } glob_foo;
> > 
> > extern "C" int *get_foo_data() { return glob_foo.get_data(); }
> 
> OK, if we want to support this, then we want to merge.
> What about types with vtbl pointer? :)

I can easily create a C struct variant covering that.  Basically
in _practice_ I can inter-operate with any language from C if I
know its ABI.  Do we really want to make this undefined?  See
the (even standard) Fortran - C interoperability spec.  I'm sure
something exists for Ada interoperating with C (or even C++).

> > ?  But you are talking about the "tree" merging part using ODR info
> > to also merge types which differ in completeness of contained
> > pointer types, right?  (exactly equal cases should be already merged)
> 
> Actually I was speaking of canonical types here. I want to preserve more 
> of TBAA via honoring ODR and local types.

So, are you positive there will be a net gain in optimization when
doing that?  Please factor in the surprises you'll get when code
gets "miscompiled" because of "slight" ODR violations or interoperability
that no longer works.

> I want to change lto to not 
> merge canonical types for pairs of types of same layout (i.e. equivalent 
> in the current canonical type definition) but with different mangled 
> names.

Names are nothing ;)  In C I very often see different _names_ used
in headers vs. implementation (when the implementation uses a different
internal header).  You have struct Foo; in public headers vs.
struct Foo_impl; in the implementation.

> I also want it to never merge when types are local. For 
> inter-language TBAA we will need to ensure aliasing in between non-ODR 
> type of same layout and all unmerged variants of ODR type.
>  Can it be 
> done by attaching chains of ODR types into the canonical type hash and 
> when non-ODR type appears, just make it alias with all of them?

No, how would that work?

> It would make sense to ODR merge in tree merging, too, but I am not sure if
> this fits the current design, since you would need to merge SCC components of
> different shape then that seems hard, right?

Right.  You'd lose the nice incremental SCC merging (where we haven't even
yet implemented the nicest way - avoid re-materializing the SCC until
we know it prevails).

> It may be easier to ODR merge after streaming (during DECL fixup) just to make
> WPA streaming cheaper and to reduce debug info size.  If you use
> -fdump-ipa-devirt, it will dump you ODR types that did not get merged (only
> ones with vtable pointers in them ATM) and there are quite long chains for
> firefox. Surely then hundreds of duplicated ODR types will end up in the 
> ltrans
> partition streams and they eventually hit debug output machinery.
> Eric sent me presentation about doing this in LLVM.
> http://llvm.org/devmtg/2013-11/slides/Christopher-DebugInfo.pdf

Debuginfo is sth completely separate and should be done separately
(early debug), avoiding to stream the types in the first place.

> > 
> > The canonical type computation happens separately (only for prevailing
> > types, of course), and there we already "merge" types which differ
> > in completeness.  Canonical type merging is conservative the other
> > way aroud - if we merge _all_ types to a single canonical type then
> > TBAA is still correct (we get a single alias set).
> 
> Yes, I think I understand that. One equivalence is kind of minimal so we merge
> only if we are sure there is no informationloss, other is maximal so we are
> sure that types that needs to be equivalent by whatever underlying langauge
> TBAA rules are actually equivalent.

The former is just not correct - it would mean that not merging at all
would be valid, which it is not (you'd create wrong-code all over the 
place).

We still don't merge enough (because of latent bugs that I didn't manage
to fix in time) - thus we do not merge all structurally equivalent types
right now.

> > > I also think we want explicit representation of types known to be local 
> > > to compilation unit - anonymous namespaces in C/C++, types defined 
> > > within function bodies in C and god knows what in Ada/Fortran/Java.
> > 
> > But here you get into the idea of improving TBAA, thus having
> > _more_ distinct canonical types?
> 
> Yes.
> > 
> > Just to make sure to not mix those two ;)
> > 
> > And whatever "frontend knowledge" we want to excercise - please
> > make sure we get a reliable way for the middle-end to see
> > that "frontend knowledge" (no langhooks!).  Thus, make it
> > "middle-end knowledge".
> 
> Sure that is what I am proposing - just have DECL_ASSEMBLER_NAME on TYPE_DECL
> and ODR flag. Middle-end when comparing types will test ODR flag and if flag
> is set, then it will compare via DECL_ASEBMLER_NAME (TYPE_DECL (type)).
> No langhooks needed here + if other language has similar inter-unit 
> equivalency
> it can use the same mechanizm. Just turn the equivalency description into
> string identifiers.

Ok.  You have to be aware of the effects on inter-language 
interoperability though (you'll break it).  Thus I'd make this
guarded by -fextra-strict-aliasing and only auto-enable that when
all TUs are produced by the same frontend (easy enough to check I guess).

Richard.

> > Oh - and the easiest way to improve things is to get less types into
> > the merging process in the first place!
> 
> Yep, my experiments with not streaming BINFO are directed in it.  I will 
> collect
> some numbers and send.
> 
> Honza
> > 
> > Richard.

Reply via email to