[llvm-commits] RFC: initial union syntax support

Duncan Sands baldrick at free.fr
Thu May 21 08:08:40 PDT 2009


Hi Nick,

>>>>> Then it would seem I misunderstood the purpose of unions. I thought 
>>>>> the problem was that it was impossible to declare a type which 
>>>>> would be "as large as the largest of any of these" without having 
>>>>> accurate TargetData. The union type was supposed to do that and 
>>>>> nothing more.
>>>>
>>>> I sent an example earlier showing that you can do this already without
>>>> union types.
>>>
>>> Close. Your trick does perform a ptrtoint which requires knowing what
>>> int size is large enough. Fortunately in your case it's indexing off of
>>> null so it's very unlikely that it won't fit in 16 bits or less, but
>>> it's still not as good as a first-class union.
>>
>> if the union is bigger than accessible memory, then you are going to
>> be able to allocate one anyway.  Conclusion: doing GEP of null can be
>> assumed to not result in pointer overflow.  Thus the only problem is
>> ptrtoint.  You can do ptrtoint to i64 on all platforms, which solves
>> the problem since you can't alloca an amount that doesn't fit in i64
>> anyway.  That said, this whole technique is pretty ugly.
> 
> Sure.
> 
>>> I've been thinking about the original suggestion and the reasons I 
>>> objected to it. It seems that the original suggest was to think about 
>>> a union as a structure where the offset into each element is zero 
>>> instead of being contiguous to each other. That makes the original 
>>> proposal make a whole lot more sense to me than it did originally.
>>>
>>> Despite Chris' message to the contrary, I still think u{i32, i32} 
>>> shouldn't be allowed (rather, it should be folded to u{i32} by the 
>>> getter). We could provide an accessor that returns the element number 
>>> for a given Type* and the only drawback is that it means doing an 
>>> extra lookup through a small list. Allowing GEP makes sense, and 
>>> unions should certainly be first class aggregates.
>>
>> another possibility is to not introduce new union types, but instead
>> to enhance the alloca instruction to take a list of types : it would
>> then allocate enough memory for all of the types in the list.  The
>> return type could be that of the first type in the list.
> 
> That's only good for stack variables. It doesn't work for globals.

good point.  How about allowing the "align" parameter for alloca's and
globals to be a ConstantExpr of integer type, rather than a ConstantInt?
(If it doesn't resolve to a ConstantInt at codegen time, when the target
is known, then codegen can abort).  As I pointed out in a previous mail,
you can get the size of a "union type" in a target independent way as a
ConstantExpr, by taking the size of each type (using the GEP trick) and
calculating the maximum using constant expressions.  You can also get
the alignment as a constant expression using a variant of the trick (I
explained how in yet another email).  So the only thing currently
stopping you declaring locals or globals of a "union type" in a target
independent is the fact that "align" is required to be a ConstantInt.
I think this approach would be much easier to implement than a new
"union type:.

Ciao,

Duncan.



More information about the llvm-commits mailing list