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. -Chris
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 frontendgenerating 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. -Chris> _______________________________________________ > 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>
On Jul 25, 2011, at 10:58 PM, Talin wrote:> 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.I'm not sure what you mean. LLVM is perfectly fine with opaque structs so long as you don't "deference" them, GEP into them, need their size, etc. -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110725/8ce4d4ae/attachment.html>