I am working with LLVM 2.9. So far I have used “llc -march=c” and “llc -march=cpp” respectively to generate C and C++ source code from LLVM IR/BitCode. My questions follow:
- I can see that there is a significant difference between the code generated by C and C++ backends. Former one generates code to be compiled by gcc to generate a native executable, while the later one is targeted to generated LLVM IR itself. Surprisingly, both the diametrically opposite functionalities have been put together in the same utility called '‘llc’. I wonder if there is any official doc available online to point out the striking difference.
- This question is simpler even: How can I make use of the C++ code generated by LLVM C++ backend? In other words, can it be compiled to a standalone, native binary that can be used to write out corresponding LLVM IR? If so, what will the compiler and linker switches be?
Thanks in advance.
The llc utility is complete interface to the LLVM back-ends, it helps you translate LLVM IR into a target's native code. As such there are more "target architectures" that you can select when using llc, you can get a list of them with "llc --version" (at least, that's how it works with the current versions of LLVM, 2.9 is rather ancient).
The C and C++ back-ends are rather special cases. The C back-end (which no-longer exists in the current LLVM version as it wasn't maintained anymore) aims at translating the IR back to compilable C code, as you already observed. The intent of this back-end was that it allows a user to utilize the optimizations and front-end of LLVM even if LLVM doesn't support the user's target architecture by generating an "optimized" C code which can then be used with another compiler.
The C++ back-end has a different purpose, it serves to show how IR code can be generated from LLVM's C++ library interface. This is more useful if you are writing a program that should generate IR code input for LLVM and want to see how a particular IR construct can be created. There are probably other uses for the C++ back-end but that's the main one I've seen so far.
So, in general, if you want to generate code that is compilable into a native binary, use the C back-end (although it may be broken in many ways due to lack of maintenance), or try to see if there is a real back-end for your target architecture so that you can generate code more directly.
I understand that C and C++ backends are special cases. My concern is, since two different functionalities are offered by two deceptively identical arguments (i.e. march=c and march=cpp), it’s easy for a beginner like me to stumble upon at this inconsistency. I myself had a hard time grasping the fact, especially when the official documentation is inadequate.
The llc command compiles LLVM source inputs into assembly language for a specified architecture. The assembly language output can then be passed through a native assembler and linker to generate a native executable.
The choice of architecture for the output assembly code is automatically determined from the input file, unless the -march option is used to override the default.
At this point, I know that the support for C backend has been dropped in LLVM release 3.1 and above.
The C backend has been removed. It had numerous problems, to the point of not being able to compile any nontrivial program.
At the same time, I’d be interested to know the use-cases of C++ backend and how to compile the C++ code (to generate IR) that LLVM C++ backend generates.