Say I have the following code: main.c: void foo(char *, ...); void bar(int, ...); int main(void) { foo("foo", 1); bar(1, 2, 3, "bar"); return 0; } foobar.c: int printf(const char *, ...); void foo(const char *str, int i) { printf("%s: %d\n", str, i); } void bar(int i, int j, int k, const char *str) { printf("%s sum: %d\n", str, i+j+k); } When I compile these separately and run llvm-ld -disable-opt I get this unfortunate sequence: define i32 @main() nounwind { entry: %retval = alloca i32 ; <i32*> [#uses=2] %0 = alloca i32 ; <i32*> [#uses=2] %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] call void (i8*, ...)* bitcast (void (i8*, i32)* @foo to void (i8*, ...)*) (i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32 1) nounwind call void (i32, ...)* bitcast (void (i32, i32, i32, i8*)* @bar to void (i32, ...)*)(i32 1, i32 2, i32 3, i8* getelementptr inbounds ([4 x i8]* @.str1, i64 0, i64 0)) nounwind It's unfortunate because the bitcast gets in the way. For example, looking at the ValueMap in the linker one would expect a Function to map to a Function. That's not true here. A Function maps to a bitcast. It also means the generated code will be suboptimal on targets like x86-64 that require extra processing for vararg calls. This happens because RecursiveResolveTypes in LinkModules.cpp doesn't understand that a "more fully specified" function argument list is compatible with a "less fully specified" one and that it should be perfectly fine to resolve the type to the more specified one. Would it break things horribly if I went in and taught RecursiveResolveTypes how to handle this or would that violate some deep-level assumption? -Dave
On Oct 5, 2009, at 3:14 PM, David Greene wrote:> When I compile these separately and run llvm-ld -disable-opt I get > this > unfortunate sequence: > > define i32 @main() nounwind { > entry: > %retval = alloca i32 ; <i32*> [#uses=2] > %0 = alloca i32 ; <i32*> [#uses=2] > %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] > call void (i8*, ...)* bitcast (void (i8*, i32)* @foo to void > (i8*, ...)*) > (i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32 1) > nounwind > call void (i32, ...)* bitcast (void (i32, i32, i32, i8*)* @bar to > void > (i32, ...)*)(i32 1, i32 2, i32 3, i8* getelementptr inbounds ([4 x > i8]* > @.str1, i64 0, i64 0)) nounwind > > It's unfortunate because the bitcast gets in the way. For example, > looking > at the ValueMap in the linker one would expect a Function to map to a > Function. That's not true here. A Function maps to a bitcast. It > also > means the generated code will be suboptimal on targets like x86-64 > that > require extra processing for vararg calls.Yep, it's pretty ugly.> This happens because RecursiveResolveTypes in LinkModules.cpp doesn't > understand that a "more fully specified" function argument list is > compatible > with a "less fully specified" one and that it should be perfectly > fine to > resolve the type to the more specified one. > > Would it break things horribly if I went in and taught > RecursiveResolveTypes > how to handle this or would that violate some deep-level assumption?This is intentional, but instcombine should clean it up. Are you not seeing this? If not, instcombine should be improved. -Chris
On Monday 05 October 2009 17:21, Chris Lattner wrote:> > Would it break things horribly if I went in and taught > > RecursiveResolveTypes > > how to handle this or would that violate some deep-level assumption? > > This is intentional, but instcombine should clean it up. Are you not > seeing this? If not, instcombine should be improved.The problem is I need to examine this before instcombine and do various nefarious things like spitting out IR and/or generating code without any modifications to improve debuggability of our compiler. Why is this intentional? I've coded up the necessary linker changes but the build is waiting on NFS and a tape drive. Grr... -Dave