[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
LLVM passes for the GNU runtime
From: |
David Chisnall |
Subject: |
LLVM passes for the GNU runtime |
Date: |
Wed, 28 Apr 2010 00:03:05 +0100 |
Hello the people,
You might have noticed that the libobjc2 directory contains an opts
subdirectory. This contains a couple of optimisations that, being specific to
the GNU runtime, are not included with LLVM. To compile them, you need to have
an LLVM tree:
$ cd llvm/lib/Transforms
$ svn co svn+ssh://address@hidden/svn/gnustep/libs/libobjc2/trunk/opts
GNURuntime
$ gmake
This produces the file ~llvm/Debug/lib/GNUObjCRuntime.so, which is a loadable
library containing the passes.
You can then run them on any LLVM bitcode files. The simplest way of creating
some of these is to pass the -emit-llvm flag to clang, like this:
$ clang -c -emit-llvm -fobjc-nonfragile-abi msgSendSpeed.m -g
This will produce a .o file containing LLVM bitcode. You then need to use opt
to run the passes:
$ opt -load ~/llvm/Debug/lib/GNUObjCRuntime.so -gnu-loop-imp-cache
msgSendSpeed.o -o msgSendSpeed.bc
This runs the pass that automatically inserts IMP caching for messages sent in
loops. The other one that currently works is -gnu-nonfragile-ivar, which turns
non-fragile ivar references into fixed offsets, where it is safe to do so (i.e.
when the compilation unit contains all of the superclasses of the class other
than NSObject). This one works best as a link-time optimization; use llvm-ld
or llvm-link to combine bitcode files.
You might also want to pass some other options to opt. Adding -O3 adds some
quite aggressive optimisations. Once you've done this, you need to turn it
into a binary. llc will produce an assembly file and you can then assemble
this with the compiler driver.
$ llc msgSendSpeed.bc
$ clang msgSendSpeed.s -L /Local/Library/Libraries/ -lobjc -lgnustep-base &&
./a.out
This is quite complicated, and it would be nice if GNUstep-make could do some
of it for you.
I've not benchmarked the ivar pass - it's a bit difficult to do because it
probably won't make much difference unless you're in a cache-contrained
situation, which microbenchmarks typically aren't.
On my simple program that sends a message which does nothing to an object
1000000000 times in row, the execution time is 10 seconds with no
optimisations, 8 with the the -O3 set, 5 with the IMP caching pass, and 3 with
both -O3 and the IMP caching set. Of course, this is a microbenchmark just
testing message sending speed. For other code, your milage may vary. This can
be relatively easily extended to perform polymorphic inline caching[1].
Note that this only works if you use the non-fragile ABI. The old ABI did not
include a mechanism for safe IMP caching, so the runtime can not invalidate the
cache if methods are added or removed during the loop's execution. Without
this, the compiler isn't free to automatically insert IMP caching, because it
can alter the program semantics.
David
[1] http://research.sun.com/self/papers/pics.html
-- Sent from my PDP-11
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- LLVM passes for the GNU runtime,
David Chisnall <=