Hi folks, Assuming that I'm writing a pass and that for bizarre reasons I need to programmatically do the equivalent of a C/C++ sizeof on a Value (or a Type, it doesn't matter which really), yielding a result in bytes, what is the known-safe way to do this? I notice that doing something like struct thingy { ... some stuff ... }; ... printf("Size = %d", sizeof(thingy)); ... turns into a constant at the bitcode disassembly level, which is fair enough but I can't rely on the source passing down information like that -- I have to be able to work purely at the opt pass level. One of the transformations I need to do is turn load and store instructions into model-checker-specific intrinsics so I can track memory modifications efficiently, but just having the address isn't enough, I really need the size too. Or are reads and writes always guaranteed to be simple types, so the bit width (as given by the Type::getPrimitiveSizeInBits() member function) divided by 8 and rounded up if necessary is enough? (The latter works well for me too, I just don't want to mess myself up by making assumptions). As usual, thank you in advance. Sarah
Check out http://nondot.org/sabre/LLVMNotes -Chris http://nondot.org/sabre http://llvm.org On Jul 27, 2007, at 12:00 PM, Sarah Thompson <thompson at email.arc.nasa.gov > wrote:> Hi folks, > > Assuming that I'm writing a pass and that for bizarre reasons I need > to > programmatically do the equivalent of a C/C++ sizeof on a Value (or a > Type, it doesn't matter which really), yielding a result in bytes, > what > is the known-safe way to do this? I notice that doing something like > > struct thingy > { > ... some stuff ... > }; > > ... > printf("Size = %d", sizeof(thingy)); > ... > > turns into a constant at the bitcode disassembly level, which is fair > enough but I can't rely on the source passing down information like > that > -- I have to be able to work purely at the opt pass level. One of the > transformations I need to do is turn load and store instructions into > model-checker-specific intrinsics so I can track memory modifications > efficiently, but just having the address isn't enough, I really need > the > size too. Or are reads and writes always guaranteed to be simple > types, > so the bit width (as given by the Type::getPrimitiveSizeInBits() > member > function) divided by 8 and rounded up if necessary is enough? (The > latter works well for me too, I just don't want to mess myself up by > making assumptions). > > As usual, thank you in advance. > > Sarah > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Sarah Thompson
2007-Jul-27 22:29 UTC
[LLVMdev] Forcing JIT of all functions before execution starts (was: Implementing sizeof)
Chris Lattner wrote:> Check out http://nondot.org/sabre/LLVMNotes > >%Size = getelementptr %T* null, int 1 %SizeI = cast %T* %Size to uint How incredibly cunning. :-) Thanks for that. Next stupid question. I've put together a simple coroutine/fibre style threading system on top of the Linux setcontext/getcontext stuff, which surprisingly enough seems to work *almost* perfectly under the JITted environment, with the exception that the JITter doesn't like running in anything other than the primary fibre. For example, #include <stdio.h> #include "../../mcp/tools/mcp2/mcpapi.h" void thread1(void *udata) { int i; for(i=0; i<10; i++) { printf("--- thread1: Hello (%d)\n", i); } } void thread2(void *udata) { int i; for(i=0; i<10; i++) { printf("--- thread2 Hello (%d)\n", i); } } int main(int argc, char **argv) { printf("--- Running threads serially:\n"); thread1(0); thread2(0); printf("--- Running threads in parallel:\n"); mcp_begin_thread(thread1, 0); mcp_begin_thread(thread2, 0); printf("--- Waiting for child threads to terminate\n"); mcp_wait_for_exit(); printf("--- Bye...\n"); return 0; } works perfectly, because thread1() and thread2() are forced into existence before they are referenced by mcp_begin_thread() (i.e. as a parameter to makecontext). Commenting out the running threads serially section results in a seg fault inside the jitter. Since we have to make so many performance compromises in the name of model checking anyway, it's no big deal for me to just basically force every function in the module to be compiled before execution starts, which should effectively mean that the JITter can never execute at run time (and therefore can never accidentally be run inside a child thread). What is the best/safest way to do this? Is it OK just to enumerate all the functions within the module and resolve them to non-lazy function pointers? I think in V1.8 just taking the address of a function was enough to cause it to be jitted, so something has obviously changed a bit since then. Thanks, Sarah
On 2007-07-27, at 15:00, Sarah Thompson wrote:> Are reads and writes always guaranteed to be simple types, so the > bit width (as given by the Type::getPrimitiveSizeInBits() member > function) divided by 8 and rounded up if necessary is enough? (The > latter works well for me too, I just don't want to mess myself up > by making assumptions).Sarah, Indeed, loads and stores must be of first class type: iN, float, double, pointers, or vectors. http://llvm.org/docs/LangRef.html#i_load http://llvm.org/docs/LangRef.html#t_primitive — Gordon -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20070727/083ea401/attachment.html>
Reasonably Related Threads
- [LLVMdev] Implementing sizeof
- [LLVMdev] Forcing JIT of all functions before execution starts (was: Implementing sizeof)
- About memory index/search in multithread program
- Pfilestat vs. prstat
- [LLVMdev] multithreaded performance disaster with -fprofile-instr-generate (contention on profile counters)