<div>Does this help :-</div>
<div> </div>
<div>struct TaggedUnionType {<br> enum { Byte, Char, Int } Type;<br> union {<br> uint_8 b;<br> char c;<br> uint32_t i;<br> };<br>};</div>
<div>int main( int argc, char *argv[])<br>{<br> TaggedUnionType t;<br> t.Type = Int;<br> t.i = 0xAA55;</div>
<div> switch( t.Type)<br> {<br> case Byte:<br> {<br> printf( "Byte = %0x2\n", t.b);<br> break;<br> }<br> case Char:<br> {<br> printf( "Char = %c\n", t.c);<br>
break;<br> }<br> case Int:<br> {<br> printf( "Int = %0x8\n", t.i);<br> break;<br> }<br> return 0;<br>}</div>
<div> </div>
<div>Output from LLVM disassembler<br></div>
<div>; ModuleID = '/tmp/webcompile/_613_0.bc'<br>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"<br>target triple = "i386-pc-linux-gnu"<br>
%struct.TaggedUnionType = type { i32, %"struct.TaggedUnionType::._11" }<br> %"struct.TaggedUnionType::._11" = type { i32 }<br>@.str = internal constant [13 x i8] c"Byte = %0x2\0A\00" ; <[13 x i8]*> [#uses=1]<br>
@.str1 = internal constant [11 x i8] c"Char = %c\0A\00" ; <[11 x i8]*> [#uses=1]<br>@.str2 = internal constant [12 x i8] c"Int = %0x8\0A\00" ; <[12 x i8]*> [#uses=1]</div>
<div>define i32 @main(i32 %argc, i8** %argv) {<br>entry:<br> %argc_addr = alloca i32 ; <i32*> [#uses=1]<br> %argv_addr = alloca i8** ; <i8***> [#uses=1]<br> %retval = alloca i32 ; <i32*> [#uses=2]<br>
%t = alloca %struct.TaggedUnionType ; <%struct.TaggedUnionType*> [#uses=6]<br> %0 = alloca i32 ; <i32*> [#uses=2]<br> %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]<br> store i32 %argc, i32* %argc_addr<br>
store i8** %argv, i8*** %argv_addr<br> %1 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 0 ; <i32*> [#uses=1]<br> store i32 2, i32* %1, align 4<br> %2 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1 ; <%"struct.TaggedUnionType::._11"*> [#uses=1]<br>
%3 = getelementptr %"struct.TaggedUnionType::._11"* %2, i32 0, i32 0 ; <i32*> [#uses=1]<br> store i32 43605, i32* %3, align 4<br> %4 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 0 ; <i32*> [#uses=1]<br>
%5 = load i32* %4, align 4 ; <i32> [#uses=1]<br> switch i32 %5, label %bb3 [<br> i32 0, label %bb<br> i32 1, label %bb1<br> i32 2, label %bb2<br> ]</div>
<div>bb: ; preds = %entry<br> %6 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1 ; <%"struct.TaggedUnionType::._11"*> [#uses=1]<br> %7 = getelementptr %"struct.TaggedUnionType::._11"* %6, i32 0, i32 0 ; <i32*> [#uses=1]<br>
%8 = bitcast i32* %7 to i8* ; <i8*> [#uses=1]<br> %9 = load i8* %8, align 4 ; <i8> [#uses=1]<br> %10 = zext i8 %9 to i32 ; <i32> [#uses=1]<br> %11 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 %10) ; <i32> [#uses=0]<br>
br label %bb3</div>
<div>bb1: ; preds = %entry<br> %12 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1 ; <%"struct.TaggedUnionType::._11"*> [#uses=1]<br> %13 = getelementptr %"struct.TaggedUnionType::._11"* %12, i32 0, i32 0 ; <i32*> [#uses=1]<br>
%14 = bitcast i32* %13 to i8* ; <i8*> [#uses=1]<br> %15 = load i8* %14, align 4 ; <i8> [#uses=1]<br> %16 = sext i8 %15 to i32 ; <i32> [#uses=1]<br> %17 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr ([11 x i8]* @.str1, i32 0, i32 0), i32 %16) ; <i32> [#uses=0]<br>
br label %bb3</div>
<div>bb2: ; preds = %entry<br> %18 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1 ; <%"struct.TaggedUnionType::._11"*> [#uses=1]<br> %19 = getelementptr %"struct.TaggedUnionType::._11"* %18, i32 0, i32 0 ; <i32*> [#uses=1]<br>
%20 = load i32* %19, align 4 ; <i32> [#uses=1]<br> %21 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr ([12 x i8]* @.str2, i32 0, i32 0), i32 %20) ; <i32> [#uses=0]<br> br label %bb3</div>
<div>bb3: ; preds = %bb2, %bb1, %bb, %entry<br> store i32 0, i32* %0, align 4<br> %22 = load i32* %0, align 4 ; <i32> [#uses=1]<br> store i32 %22, i32* %retval, align 4<br> br label %return</div>
<div>return: ; preds = %bb3<br> %retval4 = load i32* %retval ; <i32> [#uses=1]<br> ret i32 %retval4<br>}</div>
<div>declare i32 @printf(i8* noalias, ...)</div>
<div><br>Use :-</div>
<div> </div>
<div> <a href="http://llvm.org/demo/index.cgi">http://llvm.org/demo/index.cgi</a></div>
<div> </div>
<div>To convert the code. Making sure optimization is turned off, its good optimization !</div>
<div> </div>
<div>The other approach is a C++ style inheritance and have a base class with a tag in and sub types as inheriting classes.</div>
<div> </div>
<div>Hope this helps,</div>
<div> </div>
<div>Aaron</div>
<div> </div>
<div> </div>
<div> </div>
<div> </div>
<div><br><br> </div>
<div class="gmail_quote">2009/6/13 Wesley W. Terpstra <span dir="ltr"><<a href="mailto:wesley@terpstra.ca">wesley@terpstra.ca</a>></span><br>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">Good afternoon!<br><br>I'm trying to write an LLVM codegen for a Standard ML compiler<br>(MLton). So far things seem to match up quite nicely, but I have hit<br>
two sticking points. I'm hoping LLVM experts might know how to handle<br>these two cases better.<br><br>1: In ML we have some types that are actually one of several possible<br>types. Expressed in C this might be thought of as a union. The codegen<br>
only ever accesses these 'union types' via pointer. Before actually<br>indexing into the type, it always casts from the 'union pointer type'<br>to a specific pointer type.<br><br>As a concrete example. I have two types %a and %b. I want to express a<br>
third type %c that is either %a* or %b*. Later I'll cast the %c to<br>either %a* or %b*.<br><br>Currently I just represent %c as i8*. I assume that this can have<br>consequences in terms of aliasing. I tried opaque*, but llvm-as didn't<br>
like that. Is there any way to better represent the type %c to LLVM?<br><br>2: In the ML heap we have objects that are garbage collected. Objects<br>are preceded by a header that describes the object to the garbage<br>collector. However, pointers to the objects point past the header and<br>
at the actual object. Sometimes, however, the program itself accesses<br>the header. For example, to determine the length of an array (the<br>length is in the header). For every type I output it like this:<br><br>%opt_33 = { i32, %opt_45*, float }<br>
<br>I could also create another type which includes the header something like:<br>%opt_33_with_header = {i32, %opt_33 }<br><br>Is there any way to express that a pointer is actually a pointer to an<br>interior element of a type? Something like %opt_33_in_heap =<br>
%opt_33_with_header:1 ?<br><br>Currently when I want to read the header of an %opt_33, I cast it to a<br>i32* and then use getelementptr -1. Is there a better way?<br>_______________________________________________<br>LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu/" target="_blank">http://llvm.cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</blockquote></div><br>