What I can think of: 1. Anonymous struct, to avoid a copy. 2. Use stdarg.h...dangerous but accomplishes what you're looking for. 3. Split up F: giant switch statements often indicate that your function is doing several different things. (IMHO...) 4. Don't worry about it, it's probably not a bottleneck. (Or rather, profile first...) But no, there's no standard way to do this. Even C++11's variadic templates don't avoid the copy, and initializer lists are pretty much equivalent to an anonymous struct / const struct reference. (Why not? Because calling conventions differ from platform to platform; often the first few arguments of a function are passed in registers, not on the stack.) Jordy On Aug 21, 2011, at 6:23, Carlo Alberto Ferraris wrote:> Nella citazione giovedì 18 agosto 2011 09:11:36, Carlo Alberto Ferraris ha scritto: >> I need some advice on "forwarding" arguments to a callee. Suppose I have a function F that is called at the beginning of all other functions in the module. From F I need to access (read) the arguments passed to its immediate caller. Right now I do something like boxing all arguments in the caller inside a struct and passing a pointer to the struct to F, alongside an identifier telling which caller F is being called from. F has then a giant switch that branches to the appropriate unboxing code. This is obviously suboptimal because I need to allocate the struct on the stack, copy the arguments inside of it and then passing an additional pointer to F. >> I was wondering if there's a better way to do this, e.g. a way to access the stack frame of the caller (knowing, thanks to the identifier, which caller F was called from) or, more in general, arbitrary values d > efined >> in the caller. Any suggestions? > > Are there really no better ways of doing this? > <cafxx.vcf>_______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Il 21/08/2011 19:31, Jordy Rose ha scritto:> What I can think of: > 1. Anonymous struct, to avoid a copy. > 2. Use stdarg.h...dangerous but accomplishes what you're looking for.probably it wasn't clear from my first post: I'm talking about LLVM-IR, not C or C++.> 3. Split up F: giant switch statements often indicate that your function is doing several different things. (IMHO...)The whole point of the work I'm doing is having a single function; there's no way around that.> 4. Don't worry about it, it's probably not a bottleneck. (Or rather, profile first...)It might not be the most important thing right now, but it will quickly become important the further the project moves. By disassembling the genereated executable there's a lot of things that pop out as inefficient.> But no, there's no standard way to do this. Even C++11's variadic templates don't avoid the copy, and initializer lists are pretty much equivalent to an anonymous struct / const struct reference. > > (Why not? Because calling conventions differ from platform to platform; often the first few arguments of a function are passed in registers, not on the stack.)That's why I was hoping that LLVM-IR had a better way of doing such things (I mean, telling the backend that I need to access the stack frame of the caller). BTW, I posted the same question on SO, along with some (pseudo-) code to explain what I'm doing right now: http://stackoverflow.com/questions/7144733/argument-forwarding-in-llvm -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110822/8b21ac8e/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: cafxx.vcf Type: text/x-vcard Size: 230 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110822/8b21ac8e/attachment.vcf>
Hi Carlo, rather than declaring individual stack variables int x; int y; int z; and so on, which requires you to pass each one, or a pointer to each one, to your function, declare one stack variable of struct type that holds them all: struct StackObjects { int x; int y; int z; ... }; ... struct StackObjects stack; then pass the address of stack to your function, enabling it to access all of the objects on the callers stack. This way you only need to copy a single pointer. This is what GCC's nested function implementation does for example to enable child functions to access variables on the parent's stack. Ciao, Duncan.