On Jun 25, 2011, at 11:59 AM, Jay Foad wrote:> On 25 June 2011 13:00, Duncan Sands <baldrick at free.fr> wrote: >>> 3. Clang/dragonegg need to adapt to the new API (help appreciated!) >> >> what needs to be done exactly? > > Background info: http://www.nondot.org/sabre/LLVMNotes/TypeSystemRewrite.txt > > As I understand it, PATypeHolder, OpaqueType and the Module's > TypeSymbolTable are gone. Instead, StructTypes can optionally be > named, and if they are then: > > - they use name equivalence instead of structural equivalence. > - you can create them without any fields, and then add the fields > later when the struct is complete.Right, exactly. The major impact is that the various AbstractTypeUser-related classes (including OpaqueType) are gone, and the StructType interface is richer: http://llvm.org/viewvc/llvm-project/llvm/branches/type-system-rewrite/include/llvm/DerivedTypes.h?revision=133420&view=markup> I've played with the Clang bits of this. The biggest problem I've > found is that Clang uses LLVM's type resolution not just for > forward-declared structs/classes/unions, which convert > straightforwardly to the new system, but also for forward-declared > enums, which don't.I haven't started looking at this at all yet, but it seems that we could use a similar example for forward declared structs whose bodies are needed. Clang currently codegen's this: struct S; struct S f(void); struct T { struct S (*f)(void); }; struct T t = {f}; into: %0 = type opaque %struct.T = type { %0* } @t = global %struct.T { %0* bitcast (void ()* @f to %0*) }, align 8 for example. Instead of doing that, we can/should just codegen it to: %struct.T = type { void ()* } @t = global %struct.T { void ()* @f }, align 8 directly. Basically, if we "need" a type and don't have it, just lower it directly to void instead of 'opaque'. This will lead to some more bitcasts downstream, but we already have that, they get resolved if f is ever implemented.> Also, varargs forms of StructType::createNamed() and > StructType::setBody() would save a lot of mindless churn in the Clang > source code.Please feel free to add it to the branch! -Chris
On 27 June 2011 18:58, Chris Lattner <clattner at apple.com> wrote:> > On Jun 25, 2011, at 11:59 AM, Jay Foad wrote: > >> I've played with the Clang bits of this. The biggest problem I've >> found is that Clang uses LLVM's type resolution not just for >> forward-declared structs/classes/unions, which convert >> straightforwardly to the new system, but also for forward-declared >> enums, which don't.In case anyone's interested, here's my work-in-progress patch for clang. (Note that it's against a slightly old clang tree, because the llvm type-system-rewrite branch hasn't had a merge from trunk recently; and you also need the attached llvm patchlet to make it all build.) I'm not 100% satisfied with it but it is good enough to build sqlite3 from the test suite.> I haven't started looking at this at all yet, but it seems that we could use a similar example for forward declared structs whose bodies are needed. Clang currently codegen's this: > > struct S; > struct S f(void); > struct T { struct S (*f)(void); }; > struct T t = {f}; > > into: > > %0 = type opaque > %struct.T = type { %0* } > > @t = global %struct.T { %0* bitcast (void ()* @f to %0*) }, align 8 > > for example. Instead of doing that, we can/should just codegen it to: > > %struct.T = type { void ()* } > > @t = global %struct.T { void ()* @f }, align 8 > > directly.I now get: %struct.T = type { i8* } @t = global %struct.T { i8* bitcast (void ()* @f to i8*) }, align 8 declare void @f() (I lowered the incomplete function type all the way to void, instead of to void(), only because that made it simpler for CodeGenModule::GetOrCreateLLVMFunction() to tell the difference between a proper function type and a placeholder type. There's probably a better way of doing this.)> Basically, if we "need" a type and don't have it, just lower it directly to void instead of 'opaque'.I'm doing this for: - incomplete non-fixed enum types - functions types whose argument or return types are incomplete (because in that case the ABI stuff can't work out how parameters are going to be passed/returned, so you can't get a proper LLVM type for the function)> This will lead to some more bitcasts downstream, but we already have that, they get resolved if f is ever implemented.I don't have a good understanding of which bits of Clang's codegen are prepared to insert bitcasts like this; but it seems to work well enough to build sqlite3! Jay. -------------- next part -------------- A non-text attachment was scrubbed... Name: clang-type-system-rewrite.diff Type: text/x-patch Size: 91585 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110630/2b0aa78a/attachment.bin> -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-constantarray-get-arrayref.diff Type: text/x-patch Size: 702 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110630/2b0aa78a/attachment-0001.bin>
On Jun 30, 2011, at 5:38 AM, Jay Foad wrote:> In case anyone's interested, here's my work-in-progress patch for > clang. (Note that it's against a slightly old clang tree, because the > llvm type-system-rewrite branch hasn't had a merge from trunk > recently; and you also need the attached llvm patchlet to make it all > build.) > I'm not 100% satisfied with it but it is good enough to build sqlite3 > from the test suite.Wow, that's great! I'm using my few spare cycles to try to finish up the linker and bitcode reader, I really appreciate you working on this. I landed your Constants.h helper function. I'll update the branch to mainline if I can figure out how to get SVN to do what I want :)>> struct S; >> struct S f(void); >> struct T { struct S (*f)(void); }; >> struct T t = {f}; >> >> into: >> >> %0 = type opaque >> %struct.T = type { %0* } >> >> @t = global %struct.T { %0* bitcast (void ()* @f to %0*) }, align 8 >> >> for example. Instead of doing that, we can/should just codegen it to: >> >> %struct.T = type { void ()* } >> >> @t = global %struct.T { void ()* @f }, align 8 >> >> directly. > > I now get: > > %struct.T = type { i8* } > @t = global %struct.T { i8* bitcast (void ()* @f to i8*) }, align 8 > declare void @f() > > (I lowered the incomplete function type all the way to void, instead > of to void(), only because that made it simpler for > CodeGenModule::GetOrCreateLLVMFunction() to tell the difference > between a proper function type and a placeholder type. There's > probably a better way of doing this.)This makes perfect sense to me.>> Basically, if we "need" a type and don't have it, just lower it directly to void instead of 'opaque'. > > I'm doing this for: > > - incomplete non-fixed enum types > - functions types whose argument or return types are incomplete > (because in that case the ABI stuff can't work out how parameters are > going to be passed/returned, so you can't get a proper LLVM type for > the function)Yep, makes sense.>> This will lead to some more bitcasts downstream, but we already have that, they get resolved if f is ever implemented. > > I don't have a good understanding of which bits of Clang's codegen are > prepared to insert bitcasts like this; but it seems to work well > enough to build sqlite3!My bet is that this is really really close. -Chris