Is there any way to convert the llvm IR to c code and keep its semantics?
For example, can we compile the c code first to llvm IR and then compile it back to another piece of c code. I don't expect that these two files will be the same. But they need to have the same functionality.
Thanks
You can use the C backend, with llc -march=c
Related
I have multiple .cpp files that I am converting into LLVM IR .ll and then trying to link them with llvm-link before the pass and I could easily link my files without debugging flag -g. However if I convert .cpp into .ll with debugging flag and then try to link it, it gives me an error regarding subprograms as follows :
llvm-link: test.ll:228:224: error: invalid field 'subprograms'
which I believe was generated because of the debug information. This is the same problem I get even when I try to run opt on my LLVM IR with debug information in it. Is there any alternate ways to link LLVM IR that has the debug Information in it.
P.S. I am using llvm 3.8
I'm working on a compiler for a small language. Inside the compiler, I'm using the LLVM C++ API to generate llvm code, similar to the LLVM Kaleidoscope tutorial. So I'm using TheModule, TheContext, BasicBlocks,
and calls to Builder.Create...().
I can currently generate valid llvm code for arithmetic, control flow, and methods. However, I would also like my small language to support very simple OpenMP pragmas. For example,
#pragma omp parallel
{
print "Hello World"
}
I've tried writing a similar program in C++,
#include <iostream>
int main() {
#pragma omp parallel
{
std::cout << "Hi";
}
}
and generating llvm using clang++ -S -emit-llvm file.cpp -fopenmp. Along with the rest of the code, this generates the following lines which seem to implement the OpenMP functionality:
declare void #__kmpc_fork_call(%ident_t*, i32, void (i32*, i32*, ...)*, ...)
define internal void #.omp_outlined.(...)
From researching these statements, I found the Clang OpenMP API that contains calls like
OMPParallelDirective * OMPParallelDirective::Create(...)
I'm guessing this is what the Clang compiler uses to generate the statements above. However, it seems to be separate from the LLVM C++ API, as it doesn't reference TheContext, TheModule, etc...
So my question: Is there any way to leverage the Clang OpenMP API calls with my LLVM C++ API calls to generate the kmpc__fork_call and #.omp_outlined IR needed for parallel computation?
I did try decompiling the llvm generated from the C++ code back into LLVM C++ API code using llc -march=cpp file.bc ... but was unsuccessful.
The API you found operate on clang AST and are hardly usable outside clang. In fact, there are no OpenMP constructs at the LLVM IR level - everything is already lowered down to runtime calls, etc.
So, you'd really need to implement codegeneration for OpenMP by yourself emitting runtime calls as necessary (and per your language semantics).
I am attempting to compile a C++ library for a Tegra TK1. The library links to TBB, which I pulled using the package manager. During compilation I got the following error
/tmp/cc4iLbKz.s: Assembler messages:
/tmp/cc4iLbKz.s:9541: Error: thumb conditional instruction should be in IT block -- `strexeq r2,r3,[r4]'
A bit of googling and this question led me to try adding -mimplicit-it=thumb to CMAKE_CXX_FLAGS, but the compiler doesn't recognize it.
I am compiling on the tegra with kernal 3.10.40-grinch-21.3.4, and using gcc 4.8.4 compiler (thats what comes back when I type c++ -v)
I'm not sure what the initial error message means, though I think it has something to do with the TBB linked library rather than the source I'm compiling. The problem with the fix is also mysterious. Can anyone shed some light on this?
-mimplicit-it is an option to the assembler, not to the compiler. Thus, in the absence of specific assembler flags in your makefile (which you probably don't have, given that you don't appear to be using a separate assembler step), you'll need to use the -Wa option to the compiler to pass it through, i.e. -Wa,-mimplicit-it=thumb.
The source of the issue is almost certainly some inline assembly - possibly from a static inline in a header file if you're really only linking pre-built libraries - which contains conditionally-executed instructions (I'm going to guess its something like a cmpxchg implementation). Since your toolchain could well be configured to compile to the Thumb instruction set - which requires a preceding it (If-Then) instruction to set up conditional instructions - by default, another alternative might be to just compile with -marm (and/or remove -mthumb if appropriate) and sidestep the issue by not using Thumb at all.
Adding compiler option:
-wa
should solve the problem.
Working on a C++ based application, it takes user input and generates a C++ function and compile it to create a .so file and links the function to the main application. Currently had to call an external command "g++" to do it. Wonder if it's possible to call some kind of function, say, "compile" which takes as input an code snippet and produces an .so. More precisely, I need a function that has the following syntax:
sizeOfObjBuf = compile(codeBuf, objBuf);
First parameter is a null terminated string containing a code snippet, the second parameter is the output buffer that hold the compiled code and it returns the size of size of compiled code.
The whole idea is to get rid of dependency on an external program (g++) so the application can run on any Linux system (even when it doesn't have g++ installed).
Thanks.
I'm afraid the answer is "no".
You could implement that function by executing G++ (or some other compiler) in a separate process and waiting for it to finish, but that still requires the user to have a compiler installed.
You can't compile C++ code without a C++ compiler.
I am not going to do the research to figure out how it is done, but I believe the LLVM C++ compiler can be used in this way. All of the parts of LLVM are designed to run as a library, in theory.
OK, a tiny bit of research and I found this: http://clang.llvm.org/docs/LibTooling.html
I'm currently working on a compiler project using llvm. I have followed various tutorials to the point where I have a parser to create a syntax tree and then the tree is converted into an llvm Module using the provided IRBuilder.
My goal is to create an executable, and I am confused as what to do next. All the tutorials I've found just create the llvm module and print out the assembly using Module.dump(). Additionally, the only documentation I can find is for llvm developers, and not end users of the project.
If I want to generate machine code, what are the next steps? The llvm-mc project looks like it may do what I want, but I can't find any sort of documentation on it.
Perhaps I'm expecting llvm to do something that it doesn't. My expectation is that I can build a Module, then there would be an API that I can call with the Module and a target triple and an object file will be produced. I have found documentation and examples on producing a JIT, and I am not interested in that. I am looking for how to produce compiled binaries.
I am working on OS X, if that has any impact.
Use llc -filetype=obj to emit a linkable object file from your IR. You can look at the code of llc to see the LLVM API calls it makes to emit such code. At least for Mac OS X and Linux, the objects emitted in such a manner should be pretty good (i.e. this is not a "alpha quality" option by now).
LLVM does not contain a linker (yet!), however. So to actually link this object file into some executable or shared library, you will need to use the system linker. Note that even if you have an executable consisting of a single object file, the latter has to be linked anyway. Developers in the LLVM community are working on a real linker for LLVM, called lld. You can visit its page or search the mailing list archives to follow its progress.
As you can read on the llc guide, it is indeed intended to just generate the assembly, and then "The assembly language output can then be passed through a native assembler and linker to generate a native executable" - e.g. the gnu assembler (as) and linker (ld).
So the main answer here is to use native tools for assembling and linking.
However, there's experimental support for generating the native object directly from an IR file, via llc:
-filetype - Choose a file type (not all types are supported by all targets):
=asm - Emit an assembly ('.s') file
=obj - Emit a native object ('.o') file [experimental]
Or you can use llvm-mc to assemble it from the .s file:
-filetype - Choose an output file type:
=asm - Emit an assembly ('.s') file
=null - Don't emit anything (for timing purposes)
=obj - Emit a native object ('.o') file
I don't know about linkers, though.
In addition, I recommend checking out the tools/bugpoint/ToolRunner.h file, which exposes a wrapper combining llc and the platform's native C toolchain for generating machine code. From its header comment:
This file exposes an abstraction around a platform C compiler, used to compile C and assembly code.
Check out these functions in llvm-c/TargetMachine.h:
/** Emits an asm or object file for the given module to the filename. This
wraps several c++ only classes (among them a file stream). Returns any
error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. */
LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage);
/** Compile the LLVM IR stored in \p M and store the result in \p OutMemBuf. */
LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, LLVMModuleRef M,
LLVMCodeGenFileType codegen, char** ErrorMessage, LLVMMemoryBufferRef *OutMemBuf);
To run the example BrainF program, compile it and run:
echo ,. > test.bf
./BrainF test.bf -o test.bc
llc -filetype=obj test.bc
gcc test.o -o a.out
./a.out
then type a single letter and press Enter. It should echo that letter back to you. (That's what ,. does.)
The above was tested with LLVM version 3.5.0.