Is it safe to link compiled object files from different GCC versions? - gcc

Is it safe to link objects generated from sources compiled with different GCC versions into a shared library?
I assume not, but in case the used GCCs have no difference in regards to code generation and optimization improvement? Is there an information to know which GCC compiler is not backward compatible?
My question is also concerns the binaries, I looked in
https://gcc.gnu.org/onlinedocs/gcc/Compatibility.html
From my understanding, different GCC version would be compatible as long as they Conform to the same ABI

So After doing a research on the web, and reading several GCC release notes, it seems that GCC is backward compatible if there is no ABI change.
In general, this would be stated in the release notes.
I also did some experiment using different GCC compilers and GCC linkers (by different meaning from different versions of GCC) and I got linker errors when it was incompatible (different ABI versions).

Related

Is it possible to build gcc 1.0 without a C compiler?

Is it possible to build gcc 1.0 with only an assembler, without any C compilers? If it is possible, how can I build it? If it is not possible, how did the first C compiler come out?
Let's say if we have a new architecture of CPU with a new set of instructions, and the only software that has been made for it, is the assembler, then how can I build a gcc compiler for it?
Early versions of GCC were written in C. At the time, the operating systems GCC targeted came with at least a rudimentary C compiler (maybe for K&R C only, without support for prototypes). There was no bootstrap from assembler code involved, even in the first release. For those who did not or could not build GCC by themselves, the FSF provided pre-built binaries on tape, for a fee.
Support for new architectures (if they support self-hosting at all) was and still is implemented using cross-compilers.

What it takes to make OpenACC/OpenMP4.0 offloading to nvidia/mic work om GCC?

I am trying to understand how exactly I can use OpenACC to offload computation to my nvidia GPU on GCC 5.3. The more I google things the more confused I become. All the guides I find, they involve recompiling the entire gcc along with two libs called nvptx-tools and nvptx-newlib. Other sources say that OpenACC is part of GOMP library. Other sources say that the development for OpenACC support will continue only on GCC 6.x. Also I have read that support for OpenACC is in the main brunch of GCC. However if I compile a program with -fopenacc and -foffload=nvptx-non is just wont work. Can someone explain to me what exactly it takes to compiler and run OpenACC code with gcc 5.3+?
Why some guides seem to require (re)compilation of nvptx-tools, nvptx-newlib, and GCC, if, as some internet sources say, OpenACC support is part of GCC's main branch?
What is the role of the GOMP library in all this?
Is it true that development for OpenACC support will only be happening for GCC 6+ from now on?
When OpenACC support matures, is it the goal to enable it in a similar way we enable OpenMP (i.e., by just adding a couple of compiler flags)?
Can someone also provide answers to all the above after replacing "OpenACC" with "OpenMP 4.0 GPU/MIC offload capability"?
Thanks in advance
The link below contains a script that will compile gcc for OpenACC support.
https://github.com/olcf/OLCFHack15/blob/master/GCC5OffloadTest/auto-gcc5-offload-openacc-build-install.sh
OpenACC is part of GCC's main branch now, but there are some points to note. Even if there are libraries that are part of gcc, when you compile gcc, you have to specify which libraries to compile. Not all of them will be compiled by default. For OpenACC there's an additional problem. Since, NVIDIA drivers are not open source, GCC cannot compile OpenACC directly to binaries. It needs to compile OpenACC to the intermediate NVPTX instructions which the Nvidia runtime will handle. Therefore you also need to install nvptx libs.
GOMP library is the intermediate library that handles both OpenMP and OpenACC
Yes, I think OpenACC development will only be happening in GCC 6, but it may still be backported to GCC 5. But your best best would be to use GCC 6.
While I cannot comment on what GCC developers decide to do, I think in the first point I have already stated what the problems are. Unless NVIDIA make their drivers open source, I think an extra step will always be necessary.
I believe right now OpenMP is planned only for CPU's and MIC. I believe OpenMP support for both will probably become default behavior. I am not sure whether OpenMP targeting NVIDIA GPU's are immediately part of their target, but since GCC is using GOMP for both OpenMP and OpenACC, I believe eventually they might be able to do it. Also, GCC is also targeting HSA using OpenMP, so basically AMD APU's. I am not sure whether AMD GPU's will work the same way, but it maybe possible. Since, AMD is making their drivers open source, I believe they maybe easier to integrate into default behavior.

gcc __sync builtins and x86

I was looking at a question about atomic compare and swap and gcc intrinsics. I noticed that an answer quoted from the gcc manual (note the answer I looked at quoted from an earlier version of gcc but I've linked to the latest versions manual because I had checked to see if anything changed). However, when I looked at the text in the manual I saw that it appears to reference Itanium rather than x86:
The following builtins are intended to be compatible with those
described in the Intel Itanium Processor-specific Application Binary
Interface, section 7.4. As such, they depart from the normal GCC
practice of using the “__builtin_” prefix, and further that they are
overloaded such that they work on multiple types.
My question is why does gcc reference Itanium documentation and does that effect how the intrinsics work on x86? Are there any differences or is it safe to assume that even though the gcc manual references the Itanium manual that everything the gcc manual describes will work correctly on an x86 system?
My understanding is that a lot of gcc's ABI decisions (the egcs fork) were based on the ABI specs for the good ship Itanic. This included the name mangling conventions for C++ symbols. There was a large effort (Project Trillian) to have IA-64 Linux (and GCC) ready to go when the actual processor became available. The semantics are intended to be platform-independent, though they will be replaced by the __atomic builtins.

GCC: disguising between GCC versions

This question was emerged from this question.
The problem is that there is a NVidia driver for Linux, compiled wth GCC 4.5. The kernel is compiled with GCC 4.6. Well, the stuff doesn't work because of the version number difference between GCCs. (the installer says the driver won't work - for details please visit the link above)
Could one disguise a binary compiled with GCC 4.5 to a binary compiled with GCC 4.6? If it is possible, under what circumstances would it work well?
Your problem is called ABI: Application Binary Interface. This is a set of rules (among others) how functions in a piece of code get their arguments (ordering, padding of types on the stack), naming of the function so the linker can resolve symbols and padding/alignment of fields in structures.
GCC tries to keep the ABI stable between compiler versions but that's not always possible.
For example, GCC 4.4 fixed a bug in packed bit-fields which means that old/new code can't read structures using this feature properly anymore. If you would mix versions before and after 4.4, data corruption would occur without any crashes.
There is no indication in the 4.6 release notes that the ABI was changed but that's something which the Linux kernel can't know - it just reads the compiler version used to compile the code and if the first two numbers change, it assumes that running the code isn't safe.
There are two solutions:
You can compile the Nvidia driver with the same compiler as the kernel. This is strongly recommended
You can patch the version string in the binary. This will trick the kernel into loading the module but at the risk of causing data corruption to internal data structures.

Can/should libiomp5 and libgomp mix?

We are compiling an application that uses OpenMP. We are using gcc 4.4, with -fopenmp. The app also uses IPP, which includes its own version of OpenMP (libiomp5). (Note: we are disabling IPP's internal threading by calling ippSetNumThread(1). According to Intel's documentation, this should avoid conflicts with other threading libraries. However, linking with IPP still links in libiomp5.so.)
Since libiomp5.so is already linked in, we have not been linking with libgomp.so (gcc's version of OpenMP). For a long time this has worked, but after a seemingly inconsequential change we started seeing very odd OpenMP-related crashes on one of four platforms we support (the other three platforms still work fine).
I can make the crashes go away if I link in libgomp.so as well as libiomp5.so.
I have a couple questions about this:
Is linking with both these libraries safe? It seems like they would both define the same symbols.
Is there a way to tell what version of OpenMP libiomp5.so supports? With gcc 4.4, libgomp.so should be at OpenMP v3.0. I can't find any information in Intel's documentation about the OpenMP version of libiomp5.so.
Since no one has answered for a few days, I'll just report what I've found out independently:
Is linking with both these libraries safe?
No. Here's the most useful page I found on this topic:
http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011/compiler_c/optaps/common/optaps_par_openmp_multiple_compilers.htm
Intel recommends that if you are going to be mixing IPP's internal OpenMP threading with your own OpenMP threading, you link to libiomp5 instead of your compiler's OpenMP library. The current version of libiomp5 provides "source compatibility and object-level interoperability" with gcc's OpenMP, but only if you are using gcc "4.42" (sic; I assume they mean 4.4.2) or later.
Is there a way to tell what version of OpenMP libiomp5.so supports?
Yes. Set the environment variable KMP_VERSION=1, then run your application. You'll get some debugging output printed by libiomp5 to your console. If you are using IPP v7 or later, one line will be something like
Intel(R) OMP API version: 3.0 (200805)
If you are using IPP 6, it won't tell you the API version, but it will tell you when it was built and with which version of the Intel compiler. Then you can check and see what version of OpenMP that compiler supported. (11.0 was the first version of the Intel compiler to support OpenMP v3.0.)

Resources