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://[email protected]/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 _______________________________________________ Gnustep-dev mailing list [email protected] http://lists.gnu.org/mailman/listinfo/gnustep-dev
