Bugzilla – Bug 135
JIT should lazily initialize global variables
Last modified: 2003-12-19 21:38:51
You need to log in before you can comment on or make changes to this bug.
LLVM tablegen takes 4.5 seconds to start and stop (without doing any work), 2.7s of this is spent initializing 4.2MB of global variables which it is presumably not using. This is kinda pointless methinks. -Chris
This is particularly bad for C++ programs, because emitting global variables (such as vtables) causes the addrses of a many functions to be needed. This makes start-up time VERY slow for the JIT if there are lots of classes. -Chris
I've looked into this a bit, and it is due to the fact that the only way that the JIT can call into the code generator is through TargetMachine::addPassesToJITCompile, TargetMachine::addPassesToEmitMachineCode, and TargetMachine::replaceMachineCodeForFunction. We _need_ to add a virtual method on ExecutionEngine named 'getPointerToGlobalOrStub', which will return a pointer to the specified global if it has been code generated or return the address of a stub if not. With this, ExecutionEngine::getConstantValue would lazily compile called functions whose addresses are used to initialize global variables (thus improving startup times for C++ programs dramatically without actually needing to lazily emit globals). While we are adding this method, a more structured target information structure should be exposed from TargetMachine (perhaps TargetJITInfo?), to provide the various target-specific things that the JIT can request of the target (getting passes for codegenerating, emitting a stub for a function, "replacing" a function, etc). While I'm thinking about this, JIT/VM.(h|cpp) should be renamed to be JIT/JIT.(h|cpp). Also, recompileAndRelinkFunction should become a virtual method in ExecutionEngine (which does nothing on the interpreter), so that clients don't need to include the JIT header file directly. Misha, Brian, do you guys have any problems with me tackling the above stuff? I know you've been using the JIT with your 497 project, and I don't want to step on your guyz'z toes. -Chris
So I don't lose this, here is the testcase that I'm using to play with the JIT: --- void bar() {} void baz() {} void (*P1)(void) = bar; // P1 is never used, should not codegen bar void (*P2)(void) = baz; void qux() { P2(); } int main(int argc, char**argv) { if (argc > 1) qux(); } --- Use like so: $ llvmgcc test.c -c -Wa,-disable-inlining $ lli -debug-only=jit test.o <optional arg> Currently I get this on the testcase: $ lli -debug-only=jit test.o Global 'P1' -> 0x84e3808 Global 'P2' -> 0x84e3818 Finished CodeGen of [0x4018e000] Function: bar: 7 bytes of text Finished CodeGen of [0x4018e008] Function: baz: 7 bytes of text Finished CodeGen of [0x4018e010] Function: main: 57 bytes of text WARNING: Cannot resolve fn '__main' using a dummy noop function instead! $ lli -debug-only=jit test.o x Global 'P1' -> 0x84e3808 Global 'P2' -> 0x84e3818 Finished CodeGen of [0x4018e000] Function: bar: 7 bytes of text Finished CodeGen of [0x4018e008] Function: baz: 7 bytes of text Finished CodeGen of [0x4018e010] Function: main: 57 bytes of text WARNING: Cannot resolve fn '__main' using a dummy noop function instead! Finished CodeGen of [0x4018e04c] Function: qux: 16 bytes of text ... so we are lazily codegen'ing qux correctly, but that's about it. :(
497 will be over in 4 days, so I think that would be a good time to start. Right now, we have a copy of *most* of the JIT stuff in our own projects/ tree, but it's better to be safe than sorry.
Ok, I'll see if I can try to restrain myself until then. :) -Chris
Also, MachineCodeEmitter::forceCompilationOf should be refactored in a severe way... -Chris
This is just a note: I split the code refactoring portion of this PR out into Bug 176 and the lazy compilation of functions pointed to by globals into Bug 177. This bug still remains open though. -Chris
This feature is finally implemented: http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20031215/010377.html http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20031215/010378.html http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20031215/010379.html http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20031215/010380.html http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20031215/010381.html Running ll-tblgen --help, for example now only compiles 602 global variables consisting of 16183 bytes, instead of 4237379 bytes. This speeds up llvm tablegen from 2.52s to 2.08s. -Chris