Clang: How to check if LTO was performed - clang

For gcc, this answer tells us how we can verify that Link-Time Optimization was performed. For clang, I cannot see any entries similar to .gnu.lto.
More specifically, I have a binary where I am quite sure that LTO should have a significant benefit, but I am seeing nothing. I wonder if cmake actually does the right thing.
Is there any way to tell if clang performed LTO by looking at a binary or an *.o file?

An option would be to try running llvm-dis on one of your .o files. If the LTO was actually performed, the .o files contain llvm bitcode and llvm-dis will produce the .ll file containing humain-readable llvm ir. Otherwise it will produce the error message "error: Invalid bitcode signature".

The file utility will report that the file is "LLVM IR bitcode". LLVM/clang's LTO facilities don't produce "fat" object files, it's just IR.

Related

How to get bitcode llvm after linking?

I am trying to get LLVM IR for a file which is linked with some static libararies.
I tried to link using llvm-link . It just copy the .bc files in one file ( not like native linking).
clang -L$(T_LIB_PATH) -lpthread -emit-llvm gives an error: emit-llvm can not be used with linking. When passing -c option, it gives warning that the linking options were not used.
My main goal is to get .bc file with all resolved symbols and references. How can I achieve that with clang version 3.4.?
You may have a look at wllvm. It is a wrapper on the compiler, which enable to build a project and extract the LLVM bitcode of the whole program.
You need to use wllvm and wllvm++ for C and C++, respectively (after setting some environment variables).
Some symbols come from source code via LLVM IR. IR is short for intermediate representation. Those symbols are easy to handle, just stop in the middle of the build process.
Some others come from a library and probably were generated by some other compiler, one that never makes any IR, and in any case the compiler was run by some other people at some other location. You can't go back in time and make those people build IR for you, even if their compiler has the right options. All you can do is obtain the source code for the libraries and build your entire application from source.

clang -module-file-info doesn't generate any output

I'm trying to move a cross-compiled CMake project to Clang Modules to see whether compile time reduction is worth it. However, it seems that Clang is generating lots of duplicate modules in it's ModuleCache.
I'd like to figure out why (maybe some CMake config, etc), so I'm trying to run clang -module-file-info on the generated module files.
However, clang's output is just empty whenever I provide a proper module file. Am I doing anything wrong? Is there anything special that I need to take care of?
The files all have a reasonable size (from a few kB to a few MB), look fine in a Hex editor (start with CPCH, have some recognizable strings, etc) and whenever I specify a wrong file (or a file compiled with a different version of clang) I get the appropriate errors.
I've tried with clang 7.0.1 as well as 8.0.0.
I also tried --verbose but that didn't show any problems either.
To answer my own question:
clang doesn't output the stats on the command line, it puts it into a file by default written in the current directory.

Tools to control, edit, or emit the LC_UUID of a dylib?

I'm producing dylibs with embedded bitcode and using the -bitcode-symbol-map flag to specify an output directory where files of the form UUID.bcsymbolmap get produced. I'd like to teach my build system about those bcsymbolmap files so I can install and package them, but it is hard to do so since the output name for the file is determined by the LC_UUID value in the dylib which seems to be determined by ld. It seems I have two choices:
Find a way to explicitly set the LC_UUID of the dylib when building it, so that I can predict the output name of the bcsymbolmap file.
Specify a well known name for the bcsymbolmap file (the -bitcode-symbol-map option does support this) which does not contain the UUID, and then at install time, figure out the LC_UUID of the associated dylib and rename the bcsymbolmap file appropriately.
However, I don't see either a linker flag that will let me specify the LC_UUID of the library when building it, or a tool to let me change it after the fact (thinking here of something like install_name_tool), nor do I see a utility that will easily give me back the LC_UUID of a given library (to do the needed renaming of the bcsymbolmap file), short of parsing the output of otool -l, which seems fragile and unpleasant.
I'd prefer to keep my options limited to things that ship with XCode. Does anyone know of tools to easily inject, edit, or emit the LC_UUID for a dylib?
Found something slightly better than parsing otool -l output: running dwarfdump -u on the target will list the UUIDs:
$ dwarfdump -u build/libfoo.dylib
UUID: BF8FAFCC-5B1F-3FC8-B2AF-FCDA16609D71 (arm64) build/libfoo.dylib
It still isn't ideal, but at least is trivial to parse with awk or similar.
Apple engineers, if anyone ever sees this, it would be very build system friendly to add an option to ld to explicitly set the LC_UUID at build time. The flag -no_uuid already exists, it would seem easy to add a -uuid flag that took a UUID as an argument and used that instead of generating one.

LLVM compilation process and LLD

I've been trying to make the switch to LLVM, since I'd like to get more into the whole 'software-dev' scene, and it seems like right now, LLVM is the future. I built LLVM/Clang/LLD/compiler-rt/libcxx from source several times now, both with GNU/GCC and LLVM/Clang.
The problem appears when I try to use the newly compiled compilers. From what I can see, clang is using GNU ld rather than LLVM's lld. Is this true?
LLD seems to be a very limited program from the lld -help output, but from what I have read, it is as full featured as ld. I cannot find documentation on how to use it anywhere -- does anyone know where I can find some kind of comprehensive manual on it?
Thank you.
Pass -fuse-ld=lld to clang to make it use lld for linking. By now, it's in very good shape.
You can pass -v or -### to clang to make it print which linker command it runs or would run.
There's no manual for the moment and depending on platform may work well enough for you. That said, if lld were "production ready" we'd have switched clang to using it by default for the various platforms. It's not there yet so I wouldn't suggest you use it for your day to day development.
The LLVM team say that is production ready because FreeBSD can compile and link a lot of things with LLD.
The documentation on the LLD project can be found on http://lld.llvm.org/.
It's written :
LLD is a drop-in replacement for the GNU linkers.
That accepts the same command line arguments and linker scripts as GNU.
So you can use same arguments than GNU LD.
I know this question is old, but there is a newer solution to it:
To use the ld.lld linker when building any llvm target, just pass -DLLVM_ENABLE_LLD=ON in the commandline to cmake.
//Use lld as C and C++ linker.
LLVM_ENABLE_LLD:BOOL=TRUE
For other cmake projects, pass: -DCMAKE_LINKER=/etc/bin/ld.lld

force cmake to compile openCV with llvm

Background
My goal is to compile OpenCV for ios with support for the armv7s (the s is the hard part) architecture but have been unable to make any progress. My most recent theory is that the problem is that the cmake files that come with the library use gcc as a compiler which I do not think supports armv7s (if I am wrong please tell me). I am completely new to cmake however and have not been able to change the compiler.
The reason I suspect the compiler is because of the line
set (CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_BIT)" CACHE string "Build architecture for iOS")
which as far as I know should include armv7s. Changing that line to
set (CMAKE_OSX_ARCHITECTURES "armv6;armv7;armv7s;i386" CACHE string "Build architecture for iOS")
had no effect.
I know there are explanations of how to set the compiler here, here, and here. My problem is that I am trying to change an existing cmake system and don't know what ramifications my changes could have. The code in question can be downloaded here. To build the framework I run the python script in OpenCV-2.4.2/ios
python build_framework.py ~/Desktop
from what I can tell the relevant cmake files are located in OpenCV-2.4.2/ios/cmake. There are only 3 and all are fairly short. My most recent attempt was to change two lines in the toolchains
CMAKE_FORCE_C_COMPILER (gcc gcc)
CMAKE_FORCE_CXX_COMPILER (g++ g++)
to
SET (DEVROOT "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer")
SET (CC "${DEVROOT}/usr/bin/llvm-gcc-4.2")
SET (CXX "${DEVROOT}/usr/bin/llvm-g++-4.2")
CMAKE_FORCE_C_COMPILER (${CC} CLang)
CMAKE_FORCE_CXX_COMPILER (${CXX} CLang)
in an attempt to copy this SO question.
Question
My first and most important question is if this is out of my depth. I have been assuming that changing the compiler/target architecture would be a simple flag set somewhere but I am becoming less convinced that is true. Also, there is an entire directory OpenCV-2.4.2/cmake filled with much larger cmake files that I have been avoiding in the hopes I don't need to worry about their contents. Is this a problem I am going to be able to solve in less than 10 hours?
If you answered yes to the previous question, can you give me any direction? Suggested reading? Am I justified in ignoring the contents of OpenCV-2.4.2/cmake? I have been shooting in the dark for quite a while now without success.
If it turns out this is as simple as I originally hoped, how do I do it?
Update
I never did figure out how to do this, but there is an xcode version of the library here from which the compiling settings can be changed easily.
Set CMAKE_C_COMPILIER and CMAKE_CXX_COMPILIER to what you need.
Edit: this supposes you already had success with building this for armv7.
Edit2: this will just change the compiler.
I see a lot of links in your question, but didn't find original link with information how to cross compile with CMake.
You should not change anything in existing build system.
In general you need to create toolchain file for your target architecture and run cmake with it.
cmake -DCMAKE_TOOLCHAIN_FILE=< your toolchain file > < path to CMakeLists.txt from opencv >

Resources