[LLVMdev] Suggestion: Support union types in IR

Talin viridia at gmail.com
Mon May 11 22:46:17 PDT 2009


Nick Lewycky wrote:
> Hi Talin, thanks for looking in to this.
>
> I think there's already a lot of code that makes the assumption that the 
> different members of a StructType represent distinct storage. Why is it 
> easier to co-opt StructType than to create a new 'UnionType' under 
> CompositeType? What's the tradeoff?
>
>   
So, I'm not sure what path to take now, or how to proceed on this. 
Anyone have an opinion as to whether unions should be a brand new type, 
or a variation of struct? The union class will share a lot of the same 
internal stuff as struct, such as the methods for serializing and 
managing the memory for the member list.

In the mean time, I've decided to use an evil hack to get around the 
lack of proper union support. What I do is to examine all of the types 
in the union and estimate which one will be the largest. However, since 
my compiler is platform-independent, and doesn't know how big a pointer 
is, my calculation for "largest" is fairly complex - I calculate the 
size of all of the union members based on the assumption that pointers 
are 32-bits, and then filter out all members which are smaller than some 
other member in the set. I then do the same calculation but this time 
assume that pointers are 64 bits. Now I have two "largest" sets, I then 
intersect them to see if they have any entries in common. If they do, I 
pick one, and create a struct containing that type. This struct is 
guaranteed to be large enough to hold any union member on either a 
32-bit or 64-bit platform. If the two sets don't have any entries in 
common, then I just fail and print a message saying wait until proper 
union support is done :)

This hack at least gets me far enough so that in my language I can now 
compile and run code that looks like this:

  def testSimpleUnionType() {
    var x:int or float;
    x = 1;
    Debug.assertTrue(x isa int);
    Debug.assertFalse(x isa float);
    Debug.assertFalse(x isa String);
    x = 1.0;
    Debug.assertTrue(x isa float);
    Debug.assertFalse(x isa int);
    Debug.assertFalse(x isa String);
  }

-- Talin




More information about the llvm-dev mailing list