[LLVMdev] ML types in LLVM
John McCall
rjmccall at apple.com
Sun Jun 14 12:33:59 PDT 2009
On Jun 13, 2009, at 5:14 PM, Wesley W. Terpstra wrote:
> On Sat, Jun 13, 2009 at 9:44 PM, John McCall<rjmccall at apple.com>
> wrote:
>> Logically, what you want is a distinct LLVM type for every ML union
>> type
>> and each of its constructors. Unfortunately, LLVM does structural
>> uniquing of types, so that won't work.
>
> Is there absolutely no way to generate a new type? Not even an
> 'opaque' one?
As mentioned, you can generate new opaque types, but obviously that
won't work for, say, distinguishing between separate constructors that
are
structured identically. If you're not planning to write any LLVM-level
language-specific optimizations, that probably doesn't matter at all.
On the other hand, you were talking about alias analysis, which
generally
involves writing a pass to inject language-specific information.
>> What you can do is abuse address
>> spaces, giving every distinct type its own address space and casting
>> back and forth between address spaces as necessary.
>
> The manual indicates that only addresses in space 0 can have GC
> intrinsics used on them.
More casts! Although I'm curious why this limitation is in effect at
all;
probably a consequence of some other overloaded use of address
spaces.
> Also I get the impression that this would be a pretty unsafe idea. ;)
Not particularly less safe than all the other unsafe casts you're
planning
to use.
>> Is there any way to express that a pointer is actually a pointer to
>> an
>> interior element of a type? Something like %opt_33_in_heap =
>> %opt_33_with_header:1 ?
>>
>> Something like an ungetelementptr? No, sorry. That would be a
>> pretty nice extension, though obviously unsound, of course.
>
> Well, ungetelementptr could be nice, but I was hoping for something
> even better: a way to refer to the whole object type (including the
> header) even though my pointer doesn't point to the start of the
> object. Ie: this is a pointer to 8 bytes past type X.
Okay. You are right, there is no way to express this in the type
system,
and that is very unlikely to change.
>> Personally, I would create a struct type (hereafter "HeaderType")
>> for the
>> entire GC header; when you want to access a header field, just
>> cast the
>> base pointer to i8*, subtract the allocation size of HeaderType,
>> cast the
>> result to HeaderType*, and getelementptr from there.
>
> That's what I'm doing right now; the HeaderType happens to be i32. ;)
> I am assuming that casting in and out of i8* will cost me in terms of
> the optimizations LLVM can apply..?
It would only really affect a type-based alias analysis, and there's no
cookie-cutter version of that; you would need to write your own AA
pass, which could then easily recognize the pattern of accessing the
header.
> Also, I couldn't find a no-op instruction in LLVM. In some places it
> would be convenient to say: '%x = %y'. For the moment I'm doing a
> bitcast from the type back to itself, which is rather awkward.
The bitcast is a decent workaround, but the real question is why you
need
a no-op at all; if you're doing it to provide a hook for optimizer
information, a call is probably a better idea.
John.
More information about the llvm-dev
mailing list