[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