[LLVMdev] ML types in LLVM

Aaron Gray aaronngray.lists at googlemail.com
Sun Jun 14 09:02:40 PDT 2009


Does this help :-

struct TaggedUnionType {
  enum { Byte, Char, Int } Type;
  union {
    uint_8 b;
    char c;
    uint32_t i;
  };
};
int main( int argc, char *argv[])
{
    TaggedUnionType t;
    t.Type = Int;
    t.i = 0xAA55;
    switch( t.Type)
    {
    case Byte:
      {
        printf( "Byte = %0x2\n", t.b);
        break;
      }
    case Char:
      {
        printf( "Char = %c\n", t.c);
        break;
      }
    case Int:
      {
        printf( "Int = %0x8\n", t.i);
        break;
      }
    return 0;
}

Output from LLVM disassembler
; ModuleID = '/tmp/webcompile/_613_0.bc'
target datalayout =
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
target triple = "i386-pc-linux-gnu"
 %struct.TaggedUnionType = type { i32, %"struct.TaggedUnionType::._11" }
 %"struct.TaggedUnionType::._11" = type { i32 }
@.str = internal constant [13 x i8] c"Byte = %0x2\0A\00"  ; <[13 x i8]*>
[#uses=1]
@.str1 = internal constant [11 x i8] c"Char = %c\0A\00"  ; <[11 x i8]*>
[#uses=1]
@.str2 = internal constant [12 x i8] c"Int = %0x8\0A\00"  ; <[12 x i8]*>
[#uses=1]
define i32 @main(i32 %argc, i8** %argv) {
entry:
 %argc_addr = alloca i32  ; <i32*> [#uses=1]
 %argv_addr = alloca i8**  ; <i8***> [#uses=1]
 %retval = alloca i32  ; <i32*> [#uses=2]
 %t = alloca %struct.TaggedUnionType  ; <%struct.TaggedUnionType*> [#uses=6]
 %0 = alloca i32  ; <i32*> [#uses=2]
 %"alloca point" = bitcast i32 0 to i32  ; <i32> [#uses=0]
 store i32 %argc, i32* %argc_addr
 store i8** %argv, i8*** %argv_addr
 %1 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 0  ; <i32*>
[#uses=1]
 store i32 2, i32* %1, align 4
 %2 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1  ;
<%"struct.TaggedUnionType::._11"*> [#uses=1]
 %3 = getelementptr %"struct.TaggedUnionType::._11"* %2, i32 0, i32 0  ;
<i32*> [#uses=1]
 store i32 43605, i32* %3, align 4
 %4 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 0  ; <i32*>
[#uses=1]
 %5 = load i32* %4, align 4  ; <i32> [#uses=1]
 switch i32 %5, label %bb3 [
  i32 0, label %bb
  i32 1, label %bb1
  i32 2, label %bb2
 ]
bb:  ; preds = %entry
 %6 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1  ;
<%"struct.TaggedUnionType::._11"*> [#uses=1]
 %7 = getelementptr %"struct.TaggedUnionType::._11"* %6, i32 0, i32 0  ;
<i32*> [#uses=1]
 %8 = bitcast i32* %7 to i8*  ; <i8*> [#uses=1]
 %9 = load i8* %8, align 4  ; <i8> [#uses=1]
 %10 = zext i8 %9 to i32  ; <i32> [#uses=1]
 %11 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr ([13 x i8]*
@.str, i32 0, i32 0), i32 %10)  ; <i32> [#uses=0]
 br label %bb3
bb1:  ; preds = %entry
 %12 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1  ;
<%"struct.TaggedUnionType::._11"*> [#uses=1]
 %13 = getelementptr %"struct.TaggedUnionType::._11"* %12, i32 0, i32 0  ;
<i32*> [#uses=1]
 %14 = bitcast i32* %13 to i8*  ; <i8*> [#uses=1]
 %15 = load i8* %14, align 4  ; <i8> [#uses=1]
 %16 = sext i8 %15 to i32  ; <i32> [#uses=1]
 %17 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr ([11 x i8]*
@.str1, i32 0, i32 0), i32 %16)  ; <i32> [#uses=0]
 br label %bb3
bb2:  ; preds = %entry
 %18 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1  ;
<%"struct.TaggedUnionType::._11"*> [#uses=1]
 %19 = getelementptr %"struct.TaggedUnionType::._11"* %18, i32 0, i32 0  ;
<i32*> [#uses=1]
 %20 = load i32* %19, align 4  ; <i32> [#uses=1]
 %21 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr ([12 x i8]*
@.str2, i32 0, i32 0), i32 %20)  ; <i32> [#uses=0]
 br label %bb3
bb3:  ; preds = %bb2, %bb1, %bb, %entry
 store i32 0, i32* %0, align 4
 %22 = load i32* %0, align 4  ; <i32> [#uses=1]
 store i32 %22, i32* %retval, align 4
 br label %return
return:  ; preds = %bb3
 %retval4 = load i32* %retval  ; <i32> [#uses=1]
 ret i32 %retval4
}
declare i32 @printf(i8* noalias, ...)

Use :-

    http://llvm.org/demo/index.cgi

To convert the code. Making sure optimization is turned off, its good
optimization !

The other approach is a C++ style inheritance and have a base class with a
tag in and sub types as inheriting classes.

Hope this helps,

Aaron







2009/6/13 Wesley W. Terpstra <wesley at terpstra.ca>

> Good afternoon!
>
> I'm trying to write an LLVM codegen for a Standard ML compiler
> (MLton). So far things seem to match up quite nicely, but I have hit
> two sticking points. I'm hoping LLVM experts might know how to handle
> these two cases better.
>
> 1: In ML we have some types that are actually one of several possible
> types. Expressed in C this might be thought of as a union. The codegen
> only ever accesses these 'union types' via pointer. Before actually
> indexing into the type, it always casts from the 'union pointer type'
> to a specific pointer type.
>
> As a concrete example. I have two types %a and %b. I want to express a
> third type %c that is either %a* or %b*. Later I'll cast the %c to
> either %a* or %b*.
>
> Currently I just represent %c as i8*. I assume that this can have
> consequences in terms of aliasing. I tried opaque*, but llvm-as didn't
> like that. Is there any way to better represent the type %c to LLVM?
>
> 2: In the ML heap we have objects that are garbage collected. Objects
> are preceded by a header that describes the object to the garbage
> collector. However, pointers to the objects point past the header and
> at the actual object. Sometimes, however, the program itself accesses
> the header. For example, to determine the length of an array (the
> length is in the header). For every type I output it like this:
>
> %opt_33 = { i32, %opt_45*, float }
>
> I could also create another type which includes the header something like:
> %opt_33_with_header = {i32, %opt_33 }
>
> 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 ?
>
> Currently when I want to read the header of an %opt_33, I cast it to a
> i32* and then use getelementptr -1. Is there a better way?
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090614/7afc43c6/attachment.html>


More information about the llvm-dev mailing list