[LLVMdev] Linking opaque types

Talin viridia at gmail.com
Mon Jul 25 22:58:21 PDT 2011

On Mon, Jul 25, 2011 at 9:36 PM, Chris Lattner <clattner at apple.com> wrote:

> On Jul 25, 2011, at 8:52 AM, Anton Lokhmotov wrote:
> > There is an issue with representing opaque types in LLVM IR modules: if
> two
> > modules are using the same opaque type (which is only going to be
> > specialised at some later stage), it is only identified by its name.  But
> > the current module linker "resolves" this as if there is a name clash,
> and
> > one of that opaque types is renamed.  It contradicts an intuitively
> expected
> > identifier behaviour and makes it literally impossible to use opaque
> types
> > for identifying underspecified types across different modules.
> >
> > Our position is that structure type names should be treated as proper
> > identifiers, as long as types are structurally equivalent, and all the
> > opaque types are structurally equivalent unless they're specialised.
> >
> > Could anyone familiar with the linker comment please?
> Hi Anton,
> In the new-world-order, the identity of a named structure type is based on
> the name, but just like before, types have no linkage.
> This means that when linking:
> %A = type { i32 }
> and
> %A = type opaque
> that these two types are not necessarily unioned.  There are several
> reasons for this, including that it is completely valid IR to link these two
> modules:
> %A = type { i32 }
> @G = external global %A
> ... and ...
> %A = type { float}
> %G = global %A { float 1.0 }
> Even though the two globals *do* have type linkage and the types are
> contradictory.
> To handle the fact that types do not (and can not, at least as long as we
> intend to support obscure languages like "C" :) have linkage, the the linker
> uses a "best effort" approach.  It attempts to merge types and rewrite IR to
> use the merged types where it can, but it doesn't make any guarantees.
> I want to add an additional detail into this mix: That the frontend
generating all of this code is making a best effort to insure that the types
are in fact compatible -- and it isn't working.

One of the painful things about the old type system was that you were forced
to specify every type in excruciating detail - so if I had a type A which
had a data member of type B*, I had to include the complete definition of B
in my module, even if the module never dereferenced that field - because
otherwise my definition of A wouldn't be compatible with another module's
definition of A. And if B contained a C* which in turn contained a D*, all
of those had to be specified as well, even if the module never used types C
or D.

One of the benefits I had hoped to get out of the new system was to be able
to "forward declare" a type without giving a definition for it - so if I
have my definition of A containing a B*, I only need to declare B as an
opaque type instead of giving all the details.

However, it sounds like what you are saying is that if I do this, I can't
depend on the linker being able to merge the definition of forward-declared
B with fully-specified B, nor A from module 1 (containing forward-declared
B*) with A from module 2 (containing fully-specified B*).

If that's true, then it means that we're back to the case where every type
has to be fully defined down to the leaf level.

> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

-- Talin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110725/1f2d8fd2/attachment.html>

More information about the llvm-dev mailing list