Hi folk, I'm writing a set of small C code to verify whether my pass handle some instruction correctly. One of the instruction I want to test is "va_arg", but compiling my variadic function does not generate any va_arg instruction. Is va_arg deprecated? Will va_arg instruction ever be generated by any front-end? The source code and llvm instructions are appended as follows. the c code #include<stdarg.h> #include<stdio.h> #include<stdlib.h> void printValue(char * fmt, ...) { va_list args; va_start(args, fmt); int i; double d; i = va_arg(args, int); d = va_arg(args, double); va_end(args); } the generated llvm instructions: ; ModuleID = 'i.bc' 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-n8:16:32" target triple = "i386-pc-linux-gnu" define void @printValue(i8* %fmt, ...) nounwind { entry: %fmt_addr = alloca i8* ; <i8**> [#uses=1] %args.2 = alloca i8* ; <i8**> [#uses=3] %args.0 = alloca i8* ; <i8**> [#uses=3] %args = alloca i8* ; <i8**> [#uses=6] %i = alloca i32 ; <i32*> [#uses=1] %d = alloca double, align 8 ; <double*> [#uses=1] %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] store i8* %fmt, i8** %fmt_addr %args1 = bitcast i8** %args to i8* ; <i8*> [#uses=1] call void @llvm.va_start(i8* %args1) %0 = load i8** %args, align 4 ; <i8*> [#uses=1] store i8* %0, i8** %args.0, align 4 %1 = load i8** %args.0, align 4 ; <i8*> [#uses=1] %2 = getelementptr inbounds i8* %1, i64 4 ; <i8*> [#uses=1] store i8* %2, i8** %args, align 4 %3 = load i8** %args.0, align 4 ; <i8*> [#uses=1] %4 = bitcast i8* %3 to i32* ; <i32*> [#uses=1] %5 = load i32* %4, align 4 ; <i32> [#uses=1] store i32 %5, i32* %i, align 4 %6 = load i8** %args, align 4 ; <i8*> [#uses=1] store i8* %6, i8** %args.2, align 4 %7 = load i8** %args.2, align 4 ; <i8*> [#uses=1] %8 = getelementptr inbounds i8* %7, i64 8 ; <i8*> [#uses=1] store i8* %8, i8** %args, align 4 %9 = load i8** %args.2, align 4 ; <i8*> [#uses=1] %10 = bitcast i8* %9 to double* ; <double*> [#uses=1] %11 = load double* %10, align 4 ; <double> [#uses=1] store double %11, double* %d, align 8 %args2 = bitcast i8** %args to i8* ; <i8*> [#uses=1] call void @llvm.va_end(i8* %args2) br label %return return: ; preds = %entry ret void } declare void @llvm.va_start(i8*) nounwind declare void @llvm.va_end(i8*) nounwind -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100719/0feb9865/attachment.html>
Neal, FYI, my group has added a flag to llvm-gcc for emitting the va_arg instruction (instead of lowering in the front-end), and we also have an implementation of the VAARG instruction for X86-64. (which is currently not implemented in the LLVM backend). Both of these things will be sent upstream to LLVM soon, pending some more testing and review. If you are dire need of these features now, I can point you to the (public) repository where we have the beta versions. - David M On Mon, Jul 19, 2010 at 11:57 AM, Neal N. Wang <neal.wang at gmail.com> wrote:> Hi folk, > > I'm writing a set of small C code to verify whether my pass handle some > instruction correctly. One of the instruction I want to test is "va_arg", > but compiling my variadic function does not generate any va_arg instruction. > Is va_arg deprecated? Will va_arg instruction ever be generated by any > front-end? The source code and llvm instructions are appended as follows. > > the c code > #include<stdarg.h> > #include<stdio.h> > #include<stdlib.h> > > void printValue(char * fmt, ...) { > va_list args; > va_start(args, fmt); > int i; > double d; > i = va_arg(args, int); > d = va_arg(args, double); > va_end(args); > } > > the generated llvm instructions: > ; ModuleID = 'i.bc' > 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-n8:16:32" > target triple = "i386-pc-linux-gnu" > > define void @printValue(i8* %fmt, ...) nounwind { > entry: > %fmt_addr = alloca i8* ; <i8**> [#uses=1] > %args.2 = alloca i8* ; <i8**> [#uses=3] > %args.0 = alloca i8* ; <i8**> [#uses=3] > %args = alloca i8* ; <i8**> [#uses=6] > %i = alloca i32 ; <i32*> [#uses=1] > %d = alloca double, align 8 ; <double*> [#uses=1] > %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] > store i8* %fmt, i8** %fmt_addr > %args1 = bitcast i8** %args to i8* ; <i8*> [#uses=1] > call void @llvm.va_start(i8* %args1) > %0 = load i8** %args, align 4 ; <i8*> [#uses=1] > store i8* %0, i8** %args.0, align 4 > %1 = load i8** %args.0, align 4 ; <i8*> [#uses=1] > %2 = getelementptr inbounds i8* %1, i64 4 ; <i8*> [#uses=1] > store i8* %2, i8** %args, align 4 > %3 = load i8** %args.0, align 4 ; <i8*> [#uses=1] > %4 = bitcast i8* %3 to i32* ; <i32*> [#uses=1] > %5 = load i32* %4, align 4 ; <i32> [#uses=1] > store i32 %5, i32* %i, align 4 > %6 = load i8** %args, align 4 ; <i8*> [#uses=1] > store i8* %6, i8** %args.2, align 4 > %7 = load i8** %args.2, align 4 ; <i8*> [#uses=1] > %8 = getelementptr inbounds i8* %7, i64 8 ; <i8*> [#uses=1] > store i8* %8, i8** %args, align 4 > %9 = load i8** %args.2, align 4 ; <i8*> [#uses=1] > %10 = bitcast i8* %9 to double* ; <double*> [#uses=1] > %11 = load double* %10, align 4 ; <double> [#uses=1] > store double %11, double* %d, align 8 > %args2 = bitcast i8** %args to i8* ; <i8*> [#uses=1] > call void @llvm.va_end(i8* %args2) > br label %return > > return: ; preds = %entry > ret void > } > > declare void @llvm.va_start(i8*) nounwind > > declare void @llvm.va_end(i8*) nounwind > > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >
On 19 July 2010 14:57, Neal N. Wang <neal.wang at gmail.com> wrote:> Hi folk, > > I'm writing a set of small C code to verify whether my pass handle some > instruction correctly. One of the instruction I want to test is "va_arg", > but compiling my variadic function does not generate any va_arg instruction. > Is va_arg deprecated? Will va_arg instruction ever be generated by any > front-end? The source code and llvm instructions are appended as follows.Currently both clang and llvm-gcc lower va_arg. As David mentioned, we are experimenting with va_arg. Some bits were pushed upstream, some are in our public svn repo waiting for more testing/cleanup or just time to send it upstream. With those patches it is possible to use va_arg, but they are not as tested and the code is not as good (we load and store the va_list every time for example). It should be possible to improve the code generated by va_arg and some optimizations might also be easier to implement with it, but it is not done yet. So, there is hope that va_arg will be used, but currently it isn't. Cheers, -- Rafael Ávila de Espíndola
Thanks David, I don't want my pass to get any surprise when some front-ends emit va_arg. Can you please point out the link of your beta versions? Thanks, Neal. On Mon, Jul 19, 2010 at 2:18 PM, David Meyer <pdox at google.com> wrote:> Neal, > > FYI, my group has added a flag to llvm-gcc for emitting the va_arg > instruction (instead of lowering in the front-end), > and we also have an implementation of the VAARG instruction for > X86-64. (which is currently not implemented in the LLVM backend). > > Both of these things will be sent upstream to LLVM soon, pending some > more testing and review. > > If you are dire need of these features now, I can point you to the > (public) repository where we have the beta versions. > > - David M > > > On Mon, Jul 19, 2010 at 11:57 AM, Neal N. Wang <neal.wang at gmail.com> > wrote: > > Hi folk, > > > > I'm writing a set of small C code to verify whether my pass handle some > > instruction correctly. One of the instruction I want to test is > "va_arg", > > but compiling my variadic function does not generate any va_arg > instruction. > > Is va_arg deprecated? Will va_arg instruction ever be generated by any > > front-end? The source code and llvm instructions are appended as > follows. > > > > the c code > > #include<stdarg.h> > > #include<stdio.h> > > #include<stdlib.h> > > > > void printValue(char * fmt, ...) { > > va_list args; > > va_start(args, fmt); > > int i; > > double d; > > i = va_arg(args, int); > > d = va_arg(args, double); > > va_end(args); > > } > > > > the generated llvm instructions: > > ; ModuleID = 'i.bc' > > 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-n8:16:32" > > target triple = "i386-pc-linux-gnu" > > > > define void @printValue(i8* %fmt, ...) nounwind { > > entry: > > %fmt_addr = alloca i8* ; <i8**> [#uses=1] > > %args.2 = alloca i8* ; <i8**> [#uses=3] > > %args.0 = alloca i8* ; <i8**> [#uses=3] > > %args = alloca i8* ; <i8**> [#uses=6] > > %i = alloca i32 ; <i32*> [#uses=1] > > %d = alloca double, align 8 ; <double*> [#uses=1] > > %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] > > store i8* %fmt, i8** %fmt_addr > > %args1 = bitcast i8** %args to i8* ; <i8*> [#uses=1] > > call void @llvm.va_start(i8* %args1) > > %0 = load i8** %args, align 4 ; <i8*> [#uses=1] > > store i8* %0, i8** %args.0, align 4 > > %1 = load i8** %args.0, align 4 ; <i8*> [#uses=1] > > %2 = getelementptr inbounds i8* %1, i64 4 ; <i8*> [#uses=1] > > store i8* %2, i8** %args, align 4 > > %3 = load i8** %args.0, align 4 ; <i8*> [#uses=1] > > %4 = bitcast i8* %3 to i32* ; <i32*> [#uses=1] > > %5 = load i32* %4, align 4 ; <i32> [#uses=1] > > store i32 %5, i32* %i, align 4 > > %6 = load i8** %args, align 4 ; <i8*> [#uses=1] > > store i8* %6, i8** %args.2, align 4 > > %7 = load i8** %args.2, align 4 ; <i8*> [#uses=1] > > %8 = getelementptr inbounds i8* %7, i64 8 ; <i8*> [#uses=1] > > store i8* %8, i8** %args, align 4 > > %9 = load i8** %args.2, align 4 ; <i8*> [#uses=1] > > %10 = bitcast i8* %9 to double* ; <double*> [#uses=1] > > %11 = load double* %10, align 4 ; <double> [#uses=1] > > store double %11, double* %d, align 8 > > %args2 = bitcast i8** %args to i8* ; <i8*> [#uses=1] > > call void @llvm.va_end(i8* %args2) > > br label %return > > > > return: ; preds = %entry > > ret void > > } > > > > declare void @llvm.va_start(i8*) nounwind > > > > declare void @llvm.va_end(i8*) nounwind > > > > > > > > _______________________________________________ > > LLVM Developers mailing list > > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > > > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100720/add52580/attachment.html>
Hi David, I'm working on source to source transformations and instrumentation. A flag to disable 'va_arg' lowering in LLVM FEs will be very useful. Have you sent your modifications upstream to LLVM? If not, could you please share link to your public repository. Thanks, Sergey Yakoushkin On Mon, Jul 19, 2010 at 11:18 PM, David Meyer <pdox at google.com> wrote:> Neal, > > FYI, my group has added a flag to llvm-gcc for emitting the va_arg > instruction (instead of lowering in the front-end), > and we also have an implementation of the VAARG instruction for > X86-64. (which is currently not implemented in the LLVM backend). > > Both of these things will be sent upstream to LLVM soon, pending some > more testing and review. > > If you are dire need of these features now, I can point you to the > (public) repository where we have the beta versions. > > - David M