Bram Adams
2006-Oct-05 12:46 UTC
[LLVMdev] Extracting all BasicBlocks of a Function into new Function
Hi, Chris Lattner wrote:> All the non-vastart calls can be anywhere. va_end in particular codegens > to a noop on all targets llvm currently supports, fwiw. >Things go well, except for the following (pathological?) C program: int va_double_sum(int count,...){ int i,sum=0; va_list ap; va_start(ap,count); for(i=0;i<count;i++){ sum+=va_arg(ap,int); } va_end(ap); va_start(ap,count);/* same vararg opened twice!!! */ for(i=0;i<count;i++){ sum+=va_arg(ap,int); } va_end(ap); return sum; } The problematic issue here is that the va_list is opened and used twice, which should work according to GCC. If I convert the program's LLVM bytecode to the following pseudo-bytecode: int va_double_sum(int count,...){ /*declare va_list*/ /*llvm.va_start va_list*/ /*call extracted_sum(count,va_list)*/ /*llvm.va_end va_list*/ } int extracted_sum(int count,/*vararg-argument*/){ /*see original va_double_sum WITHOUT the llvm.va_start's and llvm.va_end's and WITH all uses of the original va_list replaced with the extra vararg-argument*/ } Apparently, the problem is how to "rewind" the vararg-argument back to its first element when the second loop is reached, as it seems that the code just continues at position count and beyond, resulting in overflow. I'm not sure whether this code snippet is valid ANSI C, and if it is, one probably shouldn't use this approach, but I'm just curious to know how (and if) this problem could be solved. Kind regards, Bram Adams GH-SEL, INTEC, Ghent University (Belgium)
Ryan Brown
2006-Oct-05 14:05 UTC
[LLVMdev] Extracting all BasicBlocks of a Function into new Function
I don't know if that's valid but what about something like this: int va_double_sum(int count,...){ /*declare va_list for each original va_start*/ /*llvm.va_start for each va_list*/ /*call extracted_sum(count,va_list1, va_list2, ...)*/ } int extracted_sum(int count,/*va_list1, va_list2, ...*/){ /*see original va_double_sum WITHOUT the llvm.va_start's and WITH all uses of the original va_list replaced with the correspinding va_list argument the extra vararg-argument*/ } On 10/5/06, Bram Adams <bram.adams at ugent.be> wrote:> Hi, > > Chris Lattner wrote: > > All the non-vastart calls can be anywhere. va_end in particular codegens > > to a noop on all targets llvm currently supports, fwiw. > > > Things go well, except for the following (pathological?) C program: > > int va_double_sum(int count,...){ > int i,sum=0; > va_list ap; > > va_start(ap,count); > for(i=0;i<count;i++){ > sum+=va_arg(ap,int); > } > va_end(ap); > > va_start(ap,count);/* same vararg opened twice!!! */ > for(i=0;i<count;i++){ > sum+=va_arg(ap,int); > } > va_end(ap); > > return sum; > } > > The problematic issue here is that the va_list is opened and used twice, > which should work according to GCC. If I convert the program's LLVM > bytecode to the following pseudo-bytecode: > > int va_double_sum(int count,...){ > /*declare va_list*/ > /*llvm.va_start va_list*/ > /*call extracted_sum(count,va_list)*/ > /*llvm.va_end va_list*/ > } > > int extracted_sum(int count,/*vararg-argument*/){ > /*see original va_double_sum WITHOUT the llvm.va_start's and > llvm.va_end's and WITH all uses of the original va_list replaced with > the extra vararg-argument*/ > } > > Apparently, the problem is how to "rewind" the vararg-argument back to > its first element when the second loop is reached, as it seems that the > code just continues at position count and beyond, resulting in overflow. > > I'm not sure whether this code snippet is valid ANSI C, and if it is, > one probably shouldn't use this approach, but I'm just curious to know > how (and if) this problem could be solved. > > Kind regards, > > Bram Adams > GH-SEL, INTEC, Ghent University (Belgium) > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Chris Lattner
2006-Oct-05 18:51 UTC
[LLVMdev] Extracting all BasicBlocks of a Function into new Function
On Thu, 5 Oct 2006, Bram Adams wrote:> Apparently, the problem is how to "rewind" the vararg-argument back to > its first element when the second loop is reached, as it seems that the > code just continues at position count and beyond, resulting in overflow. > > I'm not sure whether this code snippet is valid ANSI C, and if it is, > one probably shouldn't use this approach, but I'm just curious to know > how (and if) this problem could be solved.Why not va_copy the input valist? -Chris -- http://nondot.org/sabre/ http://llvm.org/
Bram Adams
2006-Oct-05 20:54 UTC
[LLVMdev] Extracting all BasicBlocks of a Function into new Function
Hi, Op 5-okt-06, om 16:05 heeft Ryan Brown het volgende geschreven:> I don't know if that's valid but what about something like this: > int va_double_sum(int count,...){ > /*declare va_list for each original va_start*/ > /*llvm.va_start for each va_list*/ > /*call extracted_sum(count,va_list1, va_list2, ...)*/ > }That should work, I think, ... Op 5-okt-06, om 20:51 heeft Chris Lattner het volgende geschreven:> Why not va_copy the input valist?... and so would this. The only problem left is that both require an easy way to replace each use of the original va_list situated AFTER a (to be removed) va_end with the second va_list. This seems a task for a control flow graph based function checking the (possibly partial) order between two Instructions, i.e. to check whether a Use is situated after a CallInst to va_end. Does such a method already exist in one of the transform or analysis passes? Or does a replaceAllUsesAfterThisInstruction() method exist? A related question: What's the easiest way to replace all uses of a Value, but only within, say, a Function? Kind regards, Bram Adams GH-SEL, INTEC, Ghent University (Belgium)
Possibly Parallel Threads
- [LLVMdev] Extracting all BasicBlocks of a Function into new Function
- [LLVMdev] Extracting all BasicBlocks of a Function into new Function
- [LLVMdev] Extracting all BasicBlocks of a Function into new Function
- [LLVMdev] Extracting all BasicBlocks of a Function into new Function
- [LLVMdev] Extracting all BasicBlocks of a Function into new Function