The language I am working on connecting to an llvm back-end (Modula-3) allows a fairly extensive set of recursive declarations. It looks like I can translate all its high-level types using four llvm types that refer to another type: function, struct, pointer, and array. It looks like I can alter an llvm struct type in place after it has been created, using StructType::setBody. I don't see a way to do this for the other three. I have to handle cases such as an array type of pointers to itself (OK, not very useful, but legal, and I should handle it) and, quite realistically, a function with a parameter or result that is a pointer to itself. In general, I can get type recursions involving any subset of the four. So what would be the best way to build llvm IR for these cases? If I add my own mutator functions to the llvm type classes, and carefully only use them during initial IR building, before any transformations, will it break anything? It looks like things are too private to do this with added outside code, and I am trying very hard to avoid touching llvm in-tree code. (We've been down that path with the current gcc-derived back-end.) Also, could the assembly language handle these new kinds of cycles in type definitions? Alternatively, is it possible to construct a system whereby the llvm operators are sometimes given a slightly artificial type, perhaps whose component(s) have the same size, alignment, etc. as the real one(s)? This would presumably entail some educated guesses as to how much of the type would actually matter to a given operator, but that might usually be intuitively obvious. Would this also require bitcasts between uses of the same value with the different types? (Note: I am building IR with core.h, etc., not generating .ll assembly.) -- Rodney Bates rodney.m.bates at acm.org
On 30 January 2015 at 12:00, Rodney M. Bates <rodney_bates at lcwb.coop> wrote:> The language I am working on connecting to an llvm back-end (Modula-3) > allows a fairly extensive set of recursive declarations. It looks > like I can translate all its high-level types using four llvm types that > refer to another type: function, struct, pointer, and array. > > It looks like I can alter an llvm struct type in place after it has > been created, using StructType::setBody. I don't see a way to do this > for the other three.The current idea it to go the other way actually: have a single pointer type and remove cycles. See http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20141201/247285.html for some of the discussion. You can just cast one pointer type to another for now. Cheers, Rafael
On 02/05/2015 04:20 PM, Rafael EspĂndola wrote:> On 30 January 2015 at 12:00, Rodney M. Bates <rodney_bates at lcwb.coop> wrote: >> The language I am working on connecting to an llvm back-end (Modula-3) >> allows a fairly extensive set of recursive declarations. It looks >> like I can translate all its high-level types using four llvm types that >> refer to another type: function, struct, pointer, and array. >> >> It looks like I can alter an llvm struct type in place after it has >> been created, using StructType::setBody. I don't see a way to do this >> for the other three. > > The current idea it to go the other way actually: have a single > pointer type and remove cycles. See > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20141201/247285.html > for some of the discussion. > > You can just cast one pointer type to another for now. >Hmm, I have been working on a different scheme, to selectively wrap a pointer in a one-member struct, as needed to break cycles. I'm not sure what the pros/cons of this are, relative to a single pointer type, say i8*. For uses, it would be a GEP vs. a cast. I presume the wrapping would be optimized away. It does leave more type information in the IR, but as an llvm newcomer, I have very little idea what parts of the type info matter.> Cheers, > Rafael >-- Rodney Bates rodney.m.bates at acm.org