Link errors with "-ipo" enabled.

Link errors with "-ipo" enabled.

Good morning/day/evening/night.

I try like to compile MaNGOS (free project emulating World of Warcraft server) with ICC x64 to compare resulting performance with the same core compiled by GNU GCC. Of course I'd like to test such features of ICC as IPO and Auto Parallelism.

If I compile the source code without "-ipo" the compiler and linker produce valid results. But if I specify this option, I receive strange link errors. They are:

../shared/libmangosshared.a(Log.o): In function `Log::InitColors(std::string const&)':
ipo_out.c:(.text+0x4400): multiple definition of `Log::InitColors(std::string const&)'
/tmp/ipo_icpcAK1ePp3.o:/tmp/ipo_icpcAK1ePp3.c:(.texthot00123+0x1f50): first defined here
../shared/libmangosshared.a(Log.o): In function `Log::outCharDump(char const*, unsigned int, unsigned int, char const*)':
ipo_out.c:(.text+0x4b50): multiple definition of `Log::outCharDump(char const*, unsigned int, unsigned int, char const*)'
/tmp/ipo_icpcAK1ePp3.o:/tmp/ipo_icpcAK1ePp3.c:(.texthot00125+0x0): first defined here

According to these errors and previous messages from make process I can see that ipo produces 3 temporary *.o objects (like /tmp/ipo_icpcAK1ePp3.o) from supplied original *.o objects and some static/shared libraries. But later linker tries to link both temporary IPO files and original libraries into final executable, that results in a lot of 'multiple definition' errors.

To be honest I don't really know whether this error is because of bug in ICC or it is related to mangos. I'm not able to clarify it as mangos uses autoconf, automake, libtool, etc. and I have never worked with autotools before. Though I can't find any weird logic in produced Makefiles. But I experience this issue only with IPO enabled, so decided to write
here.

OS: Ubuntu Linux 9.10 x64 Desktop.
ICC version: 11.1.056 for IA-32/Intel 64.
GCC version: 4.4.1.

How to reproduce this issue:

1. Set environment variables to properly use ICC: 'source /opt/intel/Compiler/11.1/056/bin/iccvars.sh intel64'.
2. Download latest ACE Framework from here. You can build and install it using guides provided at Intel website (i.e this one). I have installed ACE libs to /usr/lib because this directory is in standard library search path.
3. Install client for git version control system. On Ubuntu it can be done with 'sudo apt-get install git-core'.
4. Download mangos core files: 'git clone git://github.com/mangos/mangos.git'. It will create directory called 'mangos' in your current dir and download all the necessary files there.
5. Change your current dir to mangos: 'cd mangos'. After that you should execute 'autoreconf -if' to produce valid configure script.
6. Edit file 'src/framework/Utilities/UnorderedMap.h' with your favourite text editor. You should make following changes (note: text below is in diff format):

 using stdext::hash_map;
 #elif COMPILER == COMPILER_INTEL
-#define UNORDERED_MAP std::hash_map
-using std::hash_map;
+// ICC supports neither variadic templates, nor std::hash_map, so use following construction here.
+#define UNORDERED_MAP __gnu_cxx::hash_map
+
+namespace __gnu_cxx
+{
+    template<> struct hash
+    {
+        size_t operator()(const unsigned long long &__x) const { return (size_t)__x; }
+    };
+    template struct hash
+    {
+        size_t operator()(T * const &__x) const { return (size_t)__x; }
+    };
+
+};
 #elif COMPILER == COMPILER_GNU && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 3)
 #define UNORDERED_MAP std::tr1::unordered_map

7. Execute 'mkdir build && cd build'. After that run configure with such command: '../configure CC="icc" CXX="icpc" LD="xild" AR="xiar" CXXFLAGS="-ipo" --disable-builtin-ace'. Usage of builtin ACE results in compiler errors so I decided to install it manually as described in step 3.
8. Finally run make: 'make -j 8'. 8 concurrent make jobs is a maximum for my notebook, you are free to specify any number that you want. At the end you will receive link errors that I described earlier.

As a workaround I can:

1. Disable ipo. But it's not what I want to do.
2. Pass '-z muldefs' to linker by manually editing options in file 'mangos/build/src/mangosd/Makefile'. It allows to use only first definition of function and link stage completes successfully. But of course it does not fix the source of this problem.

I will be glad to receive any help. Thanks in advance. Sorry if my English is bad, it's not my native language and last time I have practised in it many-many years ago.

1 post / 0 new
For more complete information about compiler optimizations, see our Optimization Notice.