Hi! I followed the discussion on structure types with the example struct I { int a; char b; }; struct J : I { char c; }; Dave said that this translates to %I = type { i32, i8, i16 } %J = type { %I, i8, i16 } because the frontend has to communicate the ABI to llvm since llvm is language agnostic. What I really wonder is why it isn't %I = type { i32, i8 } %J = type { %I, i16, i8 } because llvm at least knows alignment rules by target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16... Therefore llvm has no other choice than assigning %I a size of 8 since an array may consist of %I elements and size of 5 would violate the aligment of the i32 member. If the ABI requires that member c has an offset of 8 instead of 5 then of course a padding behind %I is necessary in %J. -Jochen
Jochen Wilhelmy <j.wilhelmy at arcor.de> writes:> struct I { > int a; > char b; > }; > > struct J : I { > char c; > }; > > Dave said that this translates to > > %I = type { i32, i8, i16 } > %J = type { %I, i8, i16 }It translates to that in OUR compiler. It's not the only answer.> because the frontend has to communicate the ABI to llvm since llvm is > language agnostic.Correct.> What I really wonder is why it isn't > > %I = type { i32, i8 } > %J = type { %I, i16, i8 } > > because llvm at least knows alignment rules by > > target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16... > > Therefore llvm has no other choice than assigning %I a size of 8 > since an array may consist of %I elements and size of 5 would violate > the aligment of the i32 member.I can't quite parse this. %I doesn't get "assigned" a size by anyone. Do you meant the size of struct I is eight bytes? Yes, that's true.> If the ABI requires that member c has an offset of 8 instead of 5 then > of course a padding behind %I is necessary in %J.Yes, the padding is required. I believe %J = type { %I, i16, i8 } would work just as well as long as %I = type { i32, i8 } as in your example. Our frontend is far from "perfect" in the sense of aesthetics. :) -Dave
>> What I really wonder is why it isn't >> >> %I = type { i32, i8 } >> %J = type { %I, i16, i8 } >> >> because llvm at least knows alignment rules by >> >> target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16... >> >> Therefore llvm has no other choice than assigning %I a size of 8 >> since an array may consist of %I elements and size of 5 would violate >> the aligment of the i32 member. > I can't quite parse this. %I doesn't get "assigned" a size by anyone. > Do you meant the size of struct I is eight bytes? Yes, that's true.Yes I mean that %I = type { i32, i8 } is 8 bytes given the alignment rules (i.e. llvm "assigns" a size of 8 bytes to this struct after parsing it)> Yes, the padding is required. I believe %J = type { %I, i16, i8 } would > work just as well as long as %I = type { i32, i8 } as in your example.Yes but given the ABI requires the last member to be at offset 5, which may happen (i.e. no tail padding if I is derived from), then your solution %I = type { i32, i8, i16 } is problematic or do you switch struct generation dependent on the ABI? The question arises to me since I would use an "always working" solution (with no case distinction) but of course I'm not deep enough in the matter. -Jochen