[LLVMdev] A number of newbie questions

Chris Lattner sabre at nondot.org
Mon Jan 9 15:09:50 PST 2006


On Mon, 9 Jan 2006, Marcel Weiher wrote:
> [large executables]
>
>> It depends on what you're building.  A release build of LLVM (make 
>> ENABLE_OPTIMIZED=1, with the results in llvm/Release) is significantly 
>> smaller than a debug build.  Even with that, however, the binaries are 
>> larger than they should be (5M?).  Noone has spent the time to track 
>> down why this is to my knowledge.
> Ahh...yes, one thing I like about multi-CPU machines is that they make 
> background compiles very smooth.  Anyway, the framework is now down to 5 
> MB, 4 MB after stripping with -x, and that compresses down to around 1.1 
> MB with gzip, so quite good enough for now.  Lovely!

Great!

> [thanks for the ""-function-name trick]

No problem.

>>> 3.	Modules / JITs / functions
> [...]
>>> I've now made the Module (or rather my wrapper) a singleton, 
>>> effectively a global, but I don't feel very comfortable about it.
>> 
>> This should work.  This of it as just a container for the LLVM code 
>> you are creating.
>
> Yeah, but I really don't like globals, especially if they accumulate 
> stuff as this one does.  It would be *great* if there were a way to 
> isolate these guys, but I haven't found one yet.

Yeah, I understand.  Just file it away whereever you put your JIT... 
leading to...

>>> Also, I also remember some issues with not being able to create a 
>>> second JIT later, so it seems like one module per lifetime of a 
>>> process that wants to do jitting.
>> 
>> I'm not sure what you mean here.
>
> In my unit test code, I tried to allocate a new JIT for each test in 
> order to isolate the tests (not really a conscious decision, more 
> standard operating procedure).  The program crashed once I tried to use 
> the second allocated JIT.

Hrm.  This is a bug, please try to track down how it's crashing and we 
will try to fix it.

> Combining this (possibly flawed) observation with the fact that a JIT 
> has to be initialized with a module, it seems that you can only have a 
> single module in a process (as having a second module would require a 
> second JIT).

Nope, other stuff creates multiple modules at the same time.  Nothing that 
I'm aware of tries to create multiple JIT's though.  Probably a JIT bug.

> It is quite likely that I was doing something wrong at the time, these 
> were my very first baby steps, but from what I've gleamed it *appears* 
> to be that LLVM sort of expects these to be pretty much singletons, or 
> at the very least some sot of hierarchical invocation as you would see 
> in a command line compiler, and it also expects a process to do a (big) 
> compilation job and then exit. Is this impression correct or am I 
> misinterpreting my initial experiences?

I wouldn't be suprised if there was a hidden assumption that the JIT had 
to be a singleton, but Modules shouldn't be.

>>> 4.	Jitted functions / ownership / memory
>>> 
>>> Once a function is jitted I can get a function pointer to it and call 
>>> it, that's great.  Can I also find out how long it is, for example if 
>>> I wanted to write an object file?
>>> All in all, the jit-result seems to be fairly opaque and hidden.  Is 
>>> this intentional, or is there more I am missing?
>> 
>> There are ways, but there isn't an elegant public interface for this 
>> yet.
>> For a couple of reasons, it is tricky to JIT code to memory, then wrap 
>> it up into an object file (in particular, the JIT'd code is already 
>> relocated).
>
> OK, writing an object file was possibly not the best example, but it 
> would be good to be able to take control of the result and control its 
> lifecycle.  For example, imagine an IDE-type environment where you want 
> to overwrite a particular method (and not necessarily with code coming 
> from LLVM).

Two things you can do.  First, after a Function has been JITed, you can 
delete the LLVM IR for it, by calling Function::deleteBody().  You don't 
want to delete the Function itself because the JIT retains pointers to it.

The second thing you can do is call 
ExecutionEngine::recompileAndRelinkFunction.  This is useful if you have a 
function whose implementation you want to change.  Generally you'd call 
deleteBody() and rebuild a new body, or you would toy around with the 
current body, then call this method.  See comments above for what it does.

Also available is ExecutionEngine::freeMachineCodeForFunction, but that is 
currently a noop (because noone has implemented it yet, not because it 
can't be implemented).

>> The start of a direct ELF writer is available in lib/CodeGen/ 
>> ELFWriter.cpp, but it is not complete yet.  It uses the same codegen 
>> interfaces as the JIT to do the writing.
>
> Very cool, will have to take a look at that...though what I will need, 
> at least initially, is Mach-O, not ELF... :-)

Looking into my mystical crystal ball, I wouldn't be suprised if that 
(mach-o writing) got implemented in the next 6-12 months, but that is 
probably too long for you to wait.

-Chris

-- 
http://nondot.org/sabre/
http://llvm.org/




More information about the llvm-dev mailing list