gnustep-dev
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]