Given a structure like this (using C syntax rather than LLVM because I'm still not fluent with LLVM assembly): struct Object { int i1; int i2; int i3; }; Then, if I have an int* pointer which I know is pointing to the i3 element, what's the best way of recovering a pointer to the structure as a whole? My fallback option is to cast the pointer to an int64, use getelementptr to determine the offset of the i3 element, subtract, cast back to a pointer, etc. However this feels very clunky to me and I'd like a cleaner way of doing it. Any suggestions? (The actual use case: I have an object with embedded vtables; given a pointer to one of the vtables, I need to get the pointer to the actual object instance. Does LLVM has any built-in support for doing this sort of thing?) -- ┌─── dg@cowlark.com ───── http://www.cowlark.com ───── │ │ life←{ ↑1 ⍵∨.^3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵ } │ --- Conway's Game Of Life, in one line of APL -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 262 bytes Desc: OpenPGP digital signature URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100823/51ed2d67/attachment.sig>
Hi David, On 23 August 2010 15:02, David Given <dg at cowlark.com> wrote:> Given a structure like this (using C syntax rather than LLVM because I'm > still not fluent with LLVM assembly): > > struct Object > { > int i1; > int i2; > int i3; > }; > > Then, if I have an int* pointer which I know is pointing to the i3 > element, what's the best way of recovering a pointer to the structure as > a whole? > > My fallback option is to cast the pointer to an int64, use getelementptr > to determine the offset of the i3 element, subtract, cast back to a > pointer, etc. However this feels very clunky to me and I'd like a > cleaner way of doing it.Casting the pointer to "i8 *" and then using getelementptr with a single index, to add a (negative) number of bytes to the pointer, is probably a bit cleaner. As for how you calculate the number to subtract, you can either try to implement offsetof() as a complicated ConstantExpr using getelementptr, or you can just know that the value is 8. Most front ends know what the target data layout is, so they can just use a constant. As a general suggestion, try writing the code in C and seeing what llvm-gcc or clang turns it into.> life←{ ↑1 ⍵∨.^3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵ }Ha! Jay.
On 2010-08-24 12:35, Jay Foad wrote: [...]> As a general suggestion, try writing the code in C and seeing what > llvm-gcc or clang turns it into.I hadn't thought of that; a bit of experimentation with the demo website shows that clang is doing raw pointer arithmetic, but with getelementptr to avoid too many casts: %struct.Object = type { i32, double, i32 } define %struct.Object* @getobj(i32* %ptr) nounwind readnone { entry: %0 = getelementptr inbounds i32* %ptr, i64 -4 ; <i32*> %1 = bitcast i32* %0 to %struct.Object* ; <%struct.Object*> ret %struct.Object* %1 } The offset to getelementptr does, therefore, have structure layout information baked into it. Using getelementptr for raw pointer arithmetic is a neat trick and avoids the evil of having to cast pointers to ints, so I think I'll just do that.>> life←{ ↑1 ⍵∨.^3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵ }"There are three things a man must do, Before his life is done. Write two lines of APL And make the buggers run." -- Anonymous -- ┌─── dg@cowlark.com ───── http://www.cowlark.com ───── │ │ life←{ ↑1 ⍵∨.^3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵ } │ --- Conway's Game Of Life, in one line of APL