First Last Prev Next    No search results available
Details
: JIT should lazily initialize global variables
Bug#: 135
: libraries
: Generic Execution Engine Support
Status: RESOLVED
Resolution: FIXED
: All
: All
: 1.0
: P2
: normal
: 1.2

:
: quality-of-implementation
: 176
:
  Show dependency tree - Show dependency graph
People
Reporter: Chris Lattner <sabre@nondot.org>
Assigned To: Chris Lattner <sabre@nondot.org>
:

Attachments


Note

You need to log in before you can comment on or make changes to this bug.

Related actions


Description:   Opened: 2003-11-19 15:03
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
------- Comment #1 From Chris Lattner 2003-12-05 20:41:23 -------
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
------- Comment #2 From Chris Lattner 2003-12-08 01:58:19 -------
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
------- Comment #3 From Chris Lattner 2003-12-08 02:01:39 -------
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.  :(
------- Comment #4 From Brian R. Gaeke 2003-12-08 06:11:06 -------
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.
------- Comment #5 From Chris Lattner 2003-12-08 12:02:56 -------
 Ok, I'll see if I can try to restrain myself until then.  :)

-Chris
------- Comment #6 From Chris Lattner 2003-12-12 00:24:05 -------
Also, MachineCodeEmitter::forceCompilationOf should be refactored in a severe
way...

-Chris
------- Comment #7 From Chris Lattner 2003-12-12 01:21:42 -------
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
------- Comment #8 From Chris Lattner 2003-12-19 21:38:51 -------
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

First Last Prev Next    No search results available