Transparent LTO on Mac OS X

Dear All,

I'm trying to use transparent link-time optimization on Mac OS X.

I've got Xcode 3.2 installed, and I'm trying to compile code with llvm-gcc -O4. However, I get the following error:

gcc -O4 -o dftables .libs/dftables.o
ld: warning: in .libs/dftables.o, file is not of required architecture
Undefined symbols:
  "_main", referenced from:
      start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

It seems that the linker doesn't understand the bitcode format. Am I missing a command line option? Do I need a newer version of XCode?

-- John T.

John Criswell wrote:

Dear All,

I'm trying to use transparent link-time optimization on Mac OS X.

I've got Xcode 3.2 installed, and I'm trying to compile code with llvm-gcc -O4. However, I get the following error:

gcc -O4 -o dftables .libs/dftables.o
ld: warning: in .libs/dftables.o, file is not of required architecture
Undefined symbols:
  "_main", referenced from:
      start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
  

I should add that the gcc above is a symbolic link to llvm-gcc.

-- John T.

Are you building llvm-gcc yourself? If so, what version?

Xcode releases include an older llvm-gcc and libLTO.dylib, which may not understand bitcode generated by newer self-built compilers.

If you are only using llvm-gcc from the Xcode tools release, use the driver from:
/Developer/usr/bin/llvm-gcc-4.2

If you are building llvm-gcc yourself, try, in this order:
1) sudo ln -s ../../Developer/usr/lib/libLTO.dylib /usr/lib/libLTO.dylib

2) If you still get errors, try installing the libLTO.dylib from your LLVM build into /Developer/usr/lib. Make sure that if you're on a 64-bit machine, you built llvm for x86_64-apple-darwin10 (which should be the default)

Shantonu Sen
ssen@apple.com

Shantonu Sen wrote:

Are you building llvm-gcc yourself? If so, what version?

Xcode releases include an older llvm-gcc and libLTO.dylib, which may not understand bitcode generated by newer self-built compilers.
  

Thanks. A bitcode format mismatch was the problem. I'm not sure if the problem stems from the fact that the bitcode was generated for the wrong architecture (32 vs. 64 bit) or if the bitcode format changed during the development of LLVM 2.6 (I'm using the LLVM 2.6 release, while XCode 3.2 seems to be using some version of LLVM in-between LLVM 2.5 and LLVM 2.6).

If you are only using llvm-gcc from the Xcode tools release, use the driver from:
/Developer/usr/bin/llvm-gcc-4.2

If you are building llvm-gcc yourself, try, in this order:
1) sudo ln -s ../../Developer/usr/lib/libLTO.dylib /usr/lib/libLTO.dylib

2) If you still get errors, try installing the libLTO.dylib from your LLVM build into /Developer/usr/lib. Make sure that if you're on a 64-bit machine, you built llvm for x86_64-apple-darwin10 (which should be the default)
  

The problem I'm going to have (now that LTO works) is that I want to replace libLTO.dylib with my own (I'm trying to do transparent whole-program analysis within libLTO). My libLTO is going to generate bitcode that /Developer/usr/bin/ld (probably) won't understand because the format seems to be newer (LLVM 2.6).

Is the source code to Apple's ld linker publicly available, and if so, in what package is it in the Mac OS X sources?

-- John T.

I'm confused. libLTO takes bitcode files as input and creates a native object file as output. Why would libLTO create bitcode as output? If so, you're changing the existing API contract. Or are you creating an out-of-band bitcode file, in which case the linker would never see it.

ld doesn't have bitcode support, it has libLTO support, and libLTO is what processes the bitcode.

<http://opensource.apple.com/source/ld64/ld64-95.2.12/>

Shantonu Sen
ssen@apple.com

Shantonu Sen wrote:

I'm confused. libLTO takes bitcode files as input and creates a native object file as output. Why would libLTO create bitcode as output? If so, you're changing the existing API contract. Or are you creating an out-of-band bitcode file, in which case the linker would never see it.

I thought libLTO generates LLVM bitcode when doing relinked object files (i.e., ld -r) and generates native code when creating the final executable. Is this incorrect?

ld doesn't have bitcode support, it has libLTO support, and libLTO is what processes the bitcode.
  
<http://opensource.apple.com/source/ld64/ld64-95.2.12/>
  

Thanks.

-- John T.

Hi John,

'ld' doesn't know anything about the bitcode format. If you replace liblto with something from mainline, then 'ld' will understand mainline LLVM .bc files.

Note that the linker looks relative to itself. This means that if you want to use /usr/bin/ld that you need to install liblto in /usr/lib. If you want to use /Developer/usr/bin/ld you need to update /Developer/usr/lib.

-Chris

'ld' doesn't know anything about the bitcode format. If you replace
liblto with something from mainline, then 'ld' will understand
mainline LLVM .bc files.

Note that the linker looks relative to itself. This means that if you
want to use /usr/bin/ld that you need to install liblto in /usr/lib.
If you want to use /Developer/usr/bin/ld you need to update /Developer/
usr/lib.

In my experience, the easiest way is to set DYLD_LIBRARY_PATH before invoking ‘ld’. You can do this in a small shell script, put in the relevant ‘…/libexec/gcc/…’ directory also containing ‘cc1’ and so on. For example:

#!/bin/sh
export DYLD_LIBRARY_PATH=/opt/llvm/lib
exec /usr/bin/ld "$@"

Unfortunately, this won't work with other tools in Snow Leopard, such as ‘nm’ and ‘ar’. They have the search path hard coded: