Hi all,
This is a problem that occurs for me only on Darwin (MacOS) and not on Linux.
When llvm 2.8 (or 2.9) is compiled with ENABLE_OPTIMIZED=1, the “opt” tool fails to load LLVM passes in dynamic libraries (.dylib) files, regardless of how they themselves were built. When opt is built with ENABLE_OPTIMIZED=0, all is well.
Here is some informative output. Seems to me the problem is in stripping the symbols of the assignPassManager virtual method from the various subclasses of llvm::Pass.
Please advise!
// the release version has all the necessary symbols in place before it is installed to /usr/local/bin
$ nm -m Release+Asserts/bin/opt | grep assignPass
000000010042b7c0 (__TEXT,__text) external __ZN4llvm10ModulePass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
00000001002a27c0 (__TEXT,__text) external __ZN4llvm10RegionPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
000000010042b490 (__TEXT,__text) external __ZN4llvm12FunctionPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
000000010042b260 (__TEXT,__text) external __ZN4llvm14BasicBlockPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
00000001002053a0 (__TEXT,__text) external __ZN4llvm16CallGraphSCCPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
00000001004223d0 (__TEXT,__text) weak external __ZN4llvm4Pass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
0000000100262120 (__TEXT,__text) external __ZN4llvm8LoopPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
00000001004d7936 (__TEXT,__cstring) non-external ZZN4llvm10ModulePass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeEE8__func
00000001004bcf42 (__TEXT,__cstring) non-external ZZN4llvm10RegionPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeEE8__func
00000001004d7924 (__TEXT,__cstring) non-external ZZN4llvm12FunctionPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeEE8__func
00000001004d7901 (__TEXT,__cstring) non-external ZZN4llvm14BasicBlockPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeEE8__func
00000001004b404f (__TEXT,__cstring) non-external ZZN4llvm16CallGraphSCCPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeEE8__func
00000001004b9ce0 (__TEXT,__cstring) non-external ZZN4llvm8LoopPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeEE8__func
// same is true for the debug build
$ nm -m Debug+Asserts/bin/opt | grep assignPass
000000010040ea82 (__TEXT,__text) external __ZN4llvm10ModulePass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
0000000100299a82 (__TEXT,__text) external __ZN4llvm10RegionPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
000000010040e8a0 (__TEXT,__text) external __ZN4llvm12FunctionPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
000000010040e758 (__TEXT,__text) external __ZN4llvm14BasicBlockPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
00000001001fcb5e (__TEXT,__text) external __ZN4llvm16CallGraphSCCPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
00000001004093a8 (__TEXT,__text) weak external __ZN4llvm4Pass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
000000010025687e (__TEXT,__text) external __ZN4llvm8LoopPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
00000001004e349b (__TEXT,__cstring) non-external ZZN4llvm10ModulePass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeEE8__func
00000001004c8414 (__TEXT,__cstring) non-external ZZN4llvm10RegionPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeEE8__func
00000001004e3489 (__TEXT,__cstring) non-external ZZN4llvm12FunctionPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeEE8__func
00000001004e3466 (__TEXT,__cstring) non-external ZZN4llvm14BasicBlockPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeEE8__func
00000001004bf4e6 (__TEXT,__cstring) non-external ZZN4llvm16CallGraphSCCPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeEE8__func
00000001004c5402 (__TEXT,__cstring) non-external ZZN4llvm8LoopPass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeEE8__func
// however, once it is installed with “make install” to /usr/local/bin, it’s stripped of most of the relevant symbols (those of the llvm::Pass subclasses)
$ nm -m /usr/local/bin/opt | grep assignPass
00000001004223d0 (__TEXT,__text) weak external __ZN4llvm4Pass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
// my dynamic library contains a ModulePass, with a matching symbol that is missing in the installed “opt” binary
$ nm -m /usr/local/lib/libMyPass.dylib | grep assignPass
(undefined) external __ZN4llvm10ModulePass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
// and indeed, when opt tries to load it, it fails.
$ opt -load /usr/local/lib/libMyPass.dylib
Error opening ‘/usr/local/lib/libMyPass.dylib’: dlopen(/usr/local/lib/libMyPass.dylib, 9): Symbol not found: __ZN4llvm10ModulePass17assignPassManagerERNS_7PMStackENS_15PassManagerTypeE
Referenced from: /usr/local/lib/libMyPass.dylib
Expected in: flat namespace
in /usr/local/lib/libMyPass.dylib
-load request ignored.
Thanks a lot,
Harel Cain