After trying the recommended use of -O4 -fvisibility=hidden to
compile xplor-nih with full LTO optimizations, I discovered three
symbols become undefined...
llvm-gcc-4 -O4 -fvisibility=hidden -o xplor xplor.o \
\
-L. -lxplorCmd -lxplor -L/Users/howarth/xplor-nih-2.21/bin.Darwin_9_x86/ -lfft -lintVar -lvmd -lpy -lswigpy-xplor -ltclXplor -lswigtcl8-xplor -lnmrPot -lcommon -lmarvin \
-lcrypto -L/sw/lib/llvm-gcc-4.2/lib -lgfortran -llapack -lblas -L/Users/howarth/xplor-nih-2.21/bin.Darwin_9_x86/ \
Undefined symbols:
"_xplorwrapproc_slave_", referenced from:
llvm bitcode in xplor.o
"_python_interp_", referenced from:
llvm bitcode in xplor.o
"_tcl_interp_", referenced from:
llvm bitcode in xplor.o
ld: symbol(s) not found
These are all defined as extern as follows...
extern "C" void
FORTRAN(tcl_interp) (const long& canReturn,
long& qterm,
long& fd)
extern "C" void
FORTRAN(python_init)(const long& argc,
char** argv)
extern "C" void FORTRAN(xplorwrapproc_slave)();
The only symbols that become undefined are those extern
symbols which calling fortran routines from c++ code.
I'll look into creating a testcase and opening a PR for
this issue.
Jack
After trying the recommended use of -O4 -fvisibility=hidden to
compile xplor-nih with full LTO optimizations, I discovered three
symbols become undefined...
llvm-gcc-4 -O4 -fvisibility=hidden -o xplor xplor.o \
\
-L. -lxplorCmd -lxplor -L/Users/howarth/xplor-nih-2.21/bin.Darwin_9_x86/ -lfft -lintVar -lvmd -lpy -lswigpy-xplor -ltclXplor -lswigtcl8-xplor -lnmrPot -lcommon -lmarvin \
-lcrypto -L/sw/lib/llvm-gcc-4.2/lib -lgfortran -llapack -lblas -L/Users/howarth/xplor-nih-2.21/bin.Darwin_9_x86/ \
Undefined symbols:
"_xplorwrapproc_slave_", referenced from:
llvm bitcode in xplor.o
"_python_interp_", referenced from:
llvm bitcode in xplor.o
"_tcl_interp_", referenced from:
llvm bitcode in xplor.o
ld: symbol(s) not found
These are all defined as extern as follows...
extern "C" void
FORTRAN(tcl_interp) (const long& canReturn,
long& qterm,
long& fd)
extern "C" void
FORTRAN(python_init)(const long& argc,
char** argv)
extern "C" void FORTRAN(xplorwrapproc_slave)();
defining them as extern is not enough to mark them as "exported".
You should use the visibility attribute.
extern "C" void FORTRAN(xplorwrapproc_slave)() __attribute__((visibility("default")));
Jean-Daniel,
Doing that changes the error messages into a bus
error on the darwin linker. I'll try using -fvisibility=
hidden first with current gcc trunk's compilers and come
back to llvm-gcc4.2 later. I noticed that there are
known issues with using -fvisibility with fortran...
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35827
I have removed all of the -fvisibility=hidden flags
from the gfortran compiles but wonder if this is still
an issue since the fortran calls are being accessed
from c++ files with the -fvisibility=hidden flag in
use. Perhaps PR35827 also includes fortran calls in
c++ not understanding the use of -fvisibility as
well as fortran code itself.
Jack
Hi Jack,
Doing that changes the error messages into a bus
error on the darwin linker.
Pl. file bugzilla report (or radar) with a reproducible test case so that we can investigate this linker crash.
As you know, one way to control symbol visibility is to use gcc's (inherited by llvm-gcc) visibility support. GCC supports, 1) command line options 2) attributes and 3) pragmas in this regard. Following document provides good summary...
http://developer.apple.com/documentation/DeveloperTools/Conceptual/CppRuntimeEnv/Articles/SymbolVisibility.html#//apple_ref/doc/uid/TP40001670
Another way to control symbol visibility is to use linker's interface. See ld man page for more info on -exported_symbols_list, -exported_symbols, -unexported_symbols_list etc.. flags. If you're going to try this approach, pl. read ld man page first.
Devang,
I was surprised to discover that I could build all of
pymol with -fvisibility=hidden using gcc 4.4 or
llvm-gcc-4.2 with only a single header change...
--- pymol-1.1/layer4/Cmd.h.orig 2009-01-30 18:58:58.000000000 -0500
+++ pymol-1.1/layer4/Cmd.h 2009-01-30 19:00:17.000000000 -0500
@@ -18,7 +18,8 @@
#include"os_python.h"
-void init_cmd(void);
+void init_cmd(void)
+__attribute__((visibility("default")));
extern PyObject *PM_Globals;
One of the advantages of running as a python module I guess. I was
also able to build pymol with -O4 using the llvm 2.5 libLTO.dylib
so that full Link Time Optimizations were performed. Everything
compiled and linked fine. The resulting pymol runs its demos without
regressions. Nice.
Jack
I was able to also build sparky (Sparky - NMR Assignment Program)
at -O4 under llvm-gcc-4.2 and llvm-g++-4.2 on darwin with minor patches...
--- sparky/c++/_tkinter.c.orig 2009-01-30 22:14:28.000000000 -0500
+++ sparky/c++/_tkinter.c 2009-01-30 22:16:40.000000000 -0500
@@ -3089,6 +3089,9 @@
}
}
+PyMODINIT_FUNC
+init_tkinter(void)
+__attribute__((visibility("default")));
PyMODINIT_FUNC
init_tkinter(void)
--- sparky/c++/python.cc.orig 2009-01-30 22:23:07.000000000 -0500
+++ sparky/c++/python.cc 2009-01-30 22:23:36.000000000 -0500
@@ -3566,6 +3566,9 @@
// Initialization routine called by python when module is dynamically loaded.
//
extern "C" void initspy()
+__attribute__((visibility("default")));
Tk/Python driven software appears very friendly to -fvisibility=hidden.
Nice!
Are there any particular optimization options that one should use besides
-O4 -fvisibility=hidden to enable all of the possible llvm Link Time Optimizations?
Nope, that should be enough. "-O4" is effectively -O3 + -flto. You might also try -O2 -flto explicitly if you care about code size.
Also, I assume that one only needs to compile the object files with
-O4 -fvisibility=hidden and that the actual linkage doesn't need those
flags to enable full LTO, correct?
Right.
Is there a significant code size or perf difference with lto?
-Chris