LLVM Link IR files with debugged information - c++

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

Related

Error compiling Boost.Log

I am trying to compile the boost log library and I keep getting this error from the dump_avx2.cpp file
error: always_inline function '_mm256_set1_epi32' requires target feature 'sse4.2', but would be inlined into function 'dump_data_avx2' that is compiled without support for 'sse4.2'
boost/boost/libs/log/src/dump_avx2.cpp:71:31: note: expanded from macro 'BOOST_LOG_AUX_MM_CONSTANTS'
const __m256i mm_char_0 = _mm256_set1_epi32(0x30303030);\
^
I get a lot of errors that are very similar to the one above, all of them have the same error message but different locations in the file where they occur, for reference I am on the commit hash 68701167a1020b0b4c47b76e31d3a3da9e2faf3f for the Boost.Log submodule as fetched from the github repo (https://github.com/boostorg/boost)
Does anyone know how I can go about resolving this issue? I am building with a C++14 compiler and this is what I get when I type g++ --version
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Thanks!
Note I should clarify that in this context it is required that I compile this library separately.
Note There seem to be two related source files dump_ssse3.cpp and the mentioned dump_avx2.cpp file, do I have to compile only one of them? I cannot make out what to do from the Jamfile in the build folder :(
That looks like a bug in clang (LLVM). First, the intrinsic belongs to AVX2, not SSE4.2. Second, the whole dump_avx2.cpp file is compiled with -mavx2, so the required extensions are enabled. You can see the compiler switches in the error message from b2. And no, both dump_ssse3.cpp and dump_avx2.cpp should be compiled. The library does runtime detection of the available instructions in the CPU and selects the proper implementation.

Assembler Messages: no such instruction when Compiling C++

I am attempting to compile a C++ code using gcc/5.3 on Scientific Linux release 6.7. I keep getting the following errors whenever I run my Makefile though:
/tmp/ccjZqIED.s: Assembler messages:
/tmp/ccjZqIED.s:768: Error: no such instruction: `shlx %rax,%rdx,%rdx'
/tmp/ccjZqIED.s:1067: Error: no such instruction: `shlx %rax,%rdx,%rdx'
/tmp/ccjZqIED.s: Assembler messages:
/tmp/ccjZqIED.s:6229: Error: no such instruction: `mulx %r10,%rcx,%rbx'
/tmp/ccjZqIED.s:6248: Error: no such instruction: `mulx %r13,%rcx,%rbx'
/tmp/ccjZqIED.s:7109: Error: no such instruction: `mulx %r10,%rcx,%rbx'
/tmp/ccjZqIED.s:7128: Error: no such instruction: `mulx %r13,%rcx,%rbx'
I've attmpted to follow the advice from this question with no change to my output:
Compile errors with Assembler messages
My compiler options are currently:
CXXFLAGS = -g -Wall -O0 -pg -std=c++11
Does anyone have any idea what could be causing this?
This means that GCC is outputting an instruction that your assembler doesn't support. Either that's coming from inline asm in the source code, or that shouldn't happen, and suggests that you have compiled GCC on a different machine with a newer assembler, then copied it to another machine where it doesn't work properly.
Assuming those instructions aren't used explicitly in an asm statement you should be able to tell GCC not to emit those instructions with a suitable flag such as -mno-avx (or whatever flag is appropriate to disable use of those particular instructions).
#jonathan-wakely's answer is correct in that the assembler, which your compiler invokes, does not understand the assembly code, which your compiler generates.
As to why that happens, there are multiple possibilities:
You installed the newer compiler by hand without also updating your assembler
Your compiler generates 64-bit instructions, but assembler is limited to 32-bit ones for some reason
Disabling AVX (-mno-avx) is unlikely to help, because it is not explicitly requested either -- there is no -march in the quoted CXXFLAGS. If it did help, then you did not show us all of the compiler flags -- it would've been best, if you simply included the entire compiler command-line.
If my suspicion is correct in 1. above, then you should build and/or install the latest binutils package, which will provide as aware of AVX instructions, among other things. You would then need to rebuild the compiler with the --with-as=/path/to/the/updated/as flag passed to configure.
If your Linux installation is 32-bit only (suspicion 2.), then you should not be generating 64-bit binaries at all. It is possible, but not trivial...
Do post the output of uname -a and your entire compiler command-line leading to the above error-messages.

Link error while compiling llvm with a new optimization pass

I have written a new LLVM optimization pass. I have added this pass by making a new directory at following location:
llvm/lib/Transform/AddSub
I am following the steps as mentioned in the llvm documentation:
http://llvm.org/docs/WritingAnLLVMPass.html
But while compiling I am getting linking errors. May be my build and makefile settings are not correct.
relocation R_X86_64_PC32 against undefined symbol `_ZTVN12_GLOBAL__N_18AddSubE' can not be used when making a shared object; recompile with -fPIC
If I have written an independent llvm pass and added it in a new directory inside llvm at:
llvm/lib/Transform/
what Makefile or build changes do I need to make while writing an independent pass?
I ran into this same error when I was trying to follow the Writing An LLVM Pass guide. For me, the fix was adding a line like this:
char MyPassName::ID = 0;
(I had skipped over that step in the directions.)

What's -fPIC compile option?

Today, When trying to build my so lib project with mongodb c++ client, I got the error:
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../libmongoclient.a(connection_factory.o): relocation R_X86_64_32S against `_ZTVN5mongo17AScopedConnectionE' can not be used when making a shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../libmongoclient.a: error adding symbols: Bad value
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I googled -fPIC, but got nothing. Where can I find the doc about this? What's this? I am using clang++ for building.
PIC stands for Position Independent Code. Quoting from man gcc:
If supported for the target machine, emit position-independent code,
suitable for dynamic linking and avoiding any limit on the size of the
global offset table.
You compiled shared library without having relocatable code turned on at compile time. It is strongly suggested to use position independent code (PIC or PIE) when building shared libraries.
Please refer http://en.wikipedia.org/wiki/Position-independent_code for more details.
There is a bug in this system,you can not use .o or .a compiled intermediate file to generate dynamic lib(xx.so file),you may try to directly use the .cpp or .c file to generate a dynamic lib,also you may see this link to fix this bug (link site)

How to generate machine code with llvm

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.