External function 'pthread_once' could not be resolved

Hi LLVM'ers,

I'm trying to build the DotGNU project with the LLVM-tools.

After minor modifications of source and build code and some configure housekeeping, it seems that I've managed so far to build all the DotGNU tools. However, when extensively using the DotGNU tools I get this error message:

make[1]: Entering directory `/home/hb/projects/build/LLVM/pnet-1-1/samples'
../ilasm/ilasm -o evenodd.exe /home/hb/projects/src/pnet-1/pnet-0.7.0/samples/evenodd.il
ERROR: Program used external function 'pthread_once' which could not be resolved!
lli(_ZN85_GLOBAL__N__home_hb_projects_src_llvm_1_llvm_lib_System_Signals.cpp_17E02520_F7D322F615PrintStackTraceEv+0x1f)[0x835c40f]
/lib/tls/libc.so.6(abort+0x1d2)[0x201302]
lli[0x8116dbb]
make[1]: *** [evenodd.exe] Aborted

The 'pthread_once' is located in the native library binary file: /usr/lib/libpthread.a. I've also included the path to the library in LLVM_LIB_SEARCH_PATH environment variable.

When LLVM tool gccld is linking above program, it doesn't complain that it cannot find the function or library.

Any ideas?

make[1]: Entering directory `/home/hb/projects/build/LLVM/pnet-1-1/samples'
../ilasm/ilasm -o evenodd.exe
/home/hb/projects/src/pnet-1/pnet-0.7.0/samples/evenodd.il
ERROR: Program used external function 'pthread_once' which could not be
resolved!
lli(_ZN85_GLOBAL__N__home_hb_projects_src_llvm_1_llvm_lib_System_Signals.cpp_17E02520_F7D322F615PrintStackTraceEv+0x1f)[0x835c40f]
/lib/tls/libc.so.6(abort+0x1d2)[0x201302]
lli[0x8116dbb]
make[1]: *** [evenodd.exe] Aborted

The 'pthread_once' is located in the native library binary file:
/usr/lib/libpthread.a. I've also included the path to the library in
LLVM_LIB_SEARCH_PATH environment variable.

is there a .so of this?

When LLVM tool gccld is linking above program, it doesn't complain that it
cannot find the function or library.

The problem is, I believe, that you are running things through the
interpreter. If you compiled to native code you shouldn't have this
problem. (If there is a .so of pthreads, try linking with that one).

Andrew

From: Andrew Lenharth
Date: Thu, 07 Jul 2005 10:37:53 -0500

> make[1]: Entering directory `/home/hb/projects/build/LLVM/pnet-1-1/samples'
> ../ilasm/ilasm -o evenodd.exe
> /home/hb/projects/src/pnet-1/pnet-0.7.0/samples/evenodd.il
> ERROR: Program used external function 'pthread_once' which could not be
> resolved!
> lli(_ZN85_GLOBAL__N__home_hb_projects_src_llvm_1_llvm_lib_System_Signals.cpp_17E02520_F7D322F615PrintStackTraceEv+0x1f)[0x835c40f]
> /lib/tls/libc.so.6(abort+0x1d2)[0x201302]
> lli[0x8116dbb]
> make[1]: *** [evenodd.exe] Aborted
>
> The 'pthread_once' is located in the native library binary file:
> /usr/lib/libpthread.a. I've also included the path to the library in
> LLVM_LIB_SEARCH_PATH environment variable.

is there a .so of this?

Yes.

> When LLVM tool gccld is linking above program, it doesn't complain that it
> cannot find the function or library.

The problem is, I believe, that you are running things through the
interpreter. If you compiled to native code you shouldn't have this
problem. (If there is a .so of pthreads, try linking with that one).

The idea is to move the bytecode files between systems and thus have llvm backends to compile or interprete these. Hence, I don't want to compile to native code, other than what the systems provide through native libraries.

Henrik

If libpthread.a is a static library, lli won't be successful loading it. Try relinking lli, but add this to its tools/lli/Makefile:

TOOLLINKOPTS := -lpthread

-Chris

From: Chris Lattner
Date: Thu, 7 Jul 2005 11:26:48 -0500 (CDT)

The 'pthread_once' is located in the native library binary file: /usr/lib/libpthread.a. I've also included the path to the library in LLVM_LIB_SEARCH_PATH environment variable.

If libpthread.a is a static library, lli won't be successful loading it. Try relinking lli, but add this to its tools/lli/Makefile:

TOOLLINKOPTS := -lpthread

There is both a static (.a) and dynamic (.so) version of the library. The above advise worked for the static library. However, I think it is more convenient to use the dynamic version. How do I achieve that?

Henrik.

I am investigating some inlining issue, so I did

llvm-gcc aaa.c bbb.c ... nnn.c -o output
opt -inline -inline-threshold=xxx < output.bc | llc -march=c > output_inline.c

1)
I noticed that even if I set xxx to 0 or even a very small negative number, many functions are eliminated. I am wondering if these functions are inlined by the frontend, or identified as deadcode.

For instance, SPEC2k bzip2 has 79 functions, after these two steps, only 61 functions are left. no other optimizations are used.

2)
I noticed that the inlining condition (in Transforms/IPO/InlineSimple.cpp) is tested during llvm-gcc but not during the opt phase ? Can anybody explain what happens during llvm-gcc and opt respectively ?

thanks,
--Long

Long Fei wrote:

I am investigating some inlining issue, so I did

llvm-gcc aaa.c bbb.c ... nnn.c -o output
opt -inline -inline-threshold=xxx < output.bc | llc -march=c > output_inline.c

I am unsure of whether the LLVM GCC frontend does any inlining. However, I do know that your methods above run the LLVM inlining pass, albeit indirectly.

If you use llvm-gcc to generate and link LLVM bytecode files (as you do in the example above), llvm-gcc runs gccas and gccld (the optimizing assembler and optimizing linker, respectively). Both gccas and gccld run various LLVM optimizations, including inlining. This allows llvm-gcc to automatically perform interprocedural optimizations.

To get a completely unoptimized bytecode file, do the following:

llvm-gcc aaa.c bbb.c ... nnn.c -Wa,-disable-opt -Wl,-disable-opt -o output

That should disable all LLVM optimizations.

-- John T.

John answered the llvm-gcc part, so let me address the opt part.

`opt' is a modular optimizer, but it will do exactly what you tell it to
do, and nothing more, so if you say "opt -inline < input.bc > output.bc"
it will only inline. Note that if you say "opt < old.bc > new.bc" opt
will do nothing.

This differs from gccas and gccld which have a built-in list of
optimizations that they run, which you can get a list of if you follow
the directions here:

http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html#gccas
http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html#gccld

or just read their source code.

lli -load /path/to/libpthread.so foo.bc

-Chris

I am attempting to get started with LLVM passes by running the Hello
pass. On my FreeBSD 5.x box, I've written and compiled (with
llvm-gcc) a Hello program, and also compiled the Hello pass in the
lib/Transforms/Hello directory.

I know that this results in a number of files, as follows:

ls -l LLVM/llvm/lib/Transforms/Hello/Debug/

total 128
-rw-r--r-- 1 sean staff 11004 Jul 8 16:25 Hello.d
-rw-r--r-- 1 sean staff 358 Jul 8 16:25 Hello.lo
-rw-r--r-- 1 sean staff 115984 Jul 8 16:25 Hello.o

However, running the opt command results in the following error:

opt -load LLVM/llvm/lib/Transforms/Hello/Debug/Hello.lo < hello.bc > /dev/null

Error opening 'LLVM/llvm/lib/Transforms/Hello/Debug/Hello.lo': Can't
open :LLVM/llvm/lib/Transforms/Hello/Debug/Hello.lo: Cannot open
"LLVM/llvm/lib/Transforms/Hello/Debug/Hello.lo.so"
  -load request ignored.

Is there some sort of debugging output that can show why opt is
actualy having trouble opening the Hello.lo file? I did try to run
with the -debug flag, but that also resulted in an error complaining
about a missing .so file, which is true, but perhaps also correct??

opt -debug -load LLVM/llvm/lib/Transforms/Hello/Debug/Hello.lo < hello.bc > /dev/null

Error opening 'LLVM/llvm/lib/Transforms/Hello/Debug/Hello.lo': Can't
open :LLVM/llvm/lib/Transforms/Hello/Debug/Hello.lo: Cannot open
"LLVM/llvm/lib/Transforms/Hello/Debug/Hello.lo.so"
  -load request ignored.

Thanks,
Sean

-load works with shared objects (.so files), not libtool objects. The trick is that they get built into your llvm/Debug/lib/ directory. Try something like this:

opt -load LLVM/llvm/Debug/lib/libhello.so ...

-Chris

This didn't work as I tried with 197.parser. it works without "-Wl,-disable-opt" switch though.

[197.parser]$ llvm-gcc analyze-linkage.c and.c build-disjuncts.c extract-links.c fast-match.c idiom.c main.c massage.c parse.c post-process.c print.c prune.c read-dict.c utilities.c xalloc.c word-file.c strncasecmp.c -Wa,-disable-opt -Wl,-disable-opt -lm -o llvm_parser
[197.parser]$ opt -inline -inline-threshold=200 < llvm_parser.bc | llc -march=c > parser_inline.c llc: bytecode didn't read correctly.

Does opt call Transform/IPO/InlineSimple to do inlining ? as I added instrumentation into it, I found:
1) getInlineCost() is called when doing llvm-gcc (without the -disable* flags)
2) getInlineCost() is not called when doing opt

does the .bc code emitted by llvm-gcc carry inlining cost info ? otherwise, how does opt do inlining without the cost info ?

thanks,
--Long

Misha Brukman wrote:

I noticed that the inlining condition (in
Transforms/IPO/InlineSimple.cpp) is tested during llvm-gcc but not
during the opt phase ? Can anybody explain what happens during
llvm-gcc and opt respectively ?

John answered the llvm-gcc part, so let me address the opt part.

`opt' is a modular optimizer, but it will do exactly what you tell it to
do, and nothing more, so if you say "opt -inline < input.bc > output.bc"
it will only inline. Note that if you say "opt < old.bc > new.bc" opt
will do nothing.

This differs from gccas and gccld which have a built-in list of
optimizations that they run, which you can get a list of if you follow
the directions here:

http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html#gccas
http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html#gccld

or just read their source code.

John Criswell wrote:

This didn't work as I tried with 197.parser. it works without "-Wl,-disable-opt" switch though.

[197.parser]$ llvm-gcc analyze-linkage.c and.c build-disjuncts.c extract-links.c fast-match.c idiom.c main.c massage.c parse.c post-process.c print.c prune.c read-dict.c utilities.c xalloc.c word-file.c strncasecmp.c -Wa,-disable-opt -Wl,-disable-opt -lm -o llvm_parser

Note that this will do NO optimization at all, giving you a very very ugly .bc file. You might try just -W[al],-disable-inlining instead of disabling all optimization.

[197.parser]$ opt -inline -inline-threshold=200 < llvm_parser.bc | llc -march=c > parser_inline.c llc: bytecode didn't read correctly.

This should work, what does opt print? Can you send me [off list] the llvm_parser.bc file?

Does opt call Transform/IPO/InlineSimple to do inlining?

Yes.

as I added instrumentation into it, I found:
1) getInlineCost() is called when doing llvm-gcc (without the -disable* flags)

Yes, by default llvm-gcc does optimization, including inlining.

2) getInlineCost() is not called when doing opt

I assume that this is because opt is crashing or something (which is why LLC complains). Please send me the .bc file and I'll try to figure out what is going on.

does the .bc code emitted by llvm-gcc carry inlining cost info ? otherwise, how does opt do inlining without the cost info ?

No, the bc file contains no inlining information. The inlining pass looks at the IR for the callee and caller and uses heuristics to decide the cost of inlining at each call site. The code for this lives in lib/Transforms/IPO as misha pointed out before.

-Chris

Misha Brukman wrote:

I noticed that the inlining condition (in
Transforms/IPO/InlineSimple.cpp) is tested during llvm-gcc but not
during the opt phase ? Can anybody explain what happens during
llvm-gcc and opt respectively ?

John answered the llvm-gcc part, so let me address the opt part.

`opt' is a modular optimizer, but it will do exactly what you tell it to
do, and nothing more, so if you say "opt -inline < input.bc > output.bc"
it will only inline. Note that if you say "opt < old.bc > new.bc" opt
will do nothing.

This differs from gccas and gccld which have a built-in list of
optimizations that they run, which you can get a list of if you follow
the directions here:

http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html#gccas
http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html#gccld

or just read their source code.

John Criswell wrote:

Long Fei wrote:

I am investigating some inlining issue, so I did

llvm-gcc aaa.c bbb.c ... nnn.c -o output
opt -inline -inline-threshold=xxx < output.bc | llc -march=c > output_inline.c

I am unsure of whether the LLVM GCC frontend does any inlining. However, I do know that your methods above run the LLVM inlining pass, albeit indirectly.

If you use llvm-gcc to generate and link LLVM bytecode files (as you do in the example above), llvm-gcc runs gccas and gccld (the optimizing assembler and optimizing linker, respectively). Both gccas and gccld run various LLVM optimizations, including inlining. This allows llvm-gcc to automatically perform interprocedural optimizations.

To get a completely unoptimized bytecode file, do the following:

llvm-gcc aaa.c bbb.c ... nnn.c -Wa,-disable-opt -Wl,-disable-opt -o output

That should disable all LLVM optimizations.

-- John T.

1)
I noticed that even if I set xxx to 0 or even a very small negative number, many functions are eliminated. I am wondering if these functions are inlined by the frontend, or identified as deadcode.

For instance, SPEC2k bzip2 has 79 functions, after these two steps, only 61 functions are left. no other optimizations are used.

2)
I noticed that the inlining condition (in Transforms/IPO/InlineSimple.cpp) is tested during llvm-gcc but not during the opt phase ? Can anybody explain what happens during llvm-gcc and opt respectively ?

thanks,
--Long

_______________________________________________
LLVM Developers mailing list
LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev

_______________________________________________
LLVM Developers mailing list
LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev

-Chris

Chris,

I tried what you said in last email. It didn't work as expected.

[197.parser]$ llvm-gcc analyze-linkage.c and.c build-disjuncts.c extract-links.c fast-match.c idiom.c main.c massage.c parse.c post-process.c print.c prune.c read-dict.c utilities.c xalloc.c word-file.c strncasecmp.c -lm -W[al],-disable-inlining -o llvm_parser
[hash inlined] [table_pointer inlined] ...

[197.parser]$ opt -inline -inline-threshold=200 < llvm_parser.bc | llc -march=c > parser_inline.c
<no message here>

The "[xxx inlined]" message is generated from instrumentation in getInlineCost() (I changed it a little bit so it returns 0 if the callee is in a list of must-inline functions, it spits out this message in this case). It seems that getInlineCost() is evaluated only in llvm-gcc (even when -disable-inlining flag is set) but not in opt -inline. [If you disable inlining by returning a very large cost, it might explain.]

I will send another email with the .bc file directly to your email address (in order to get around the mailing-list manager).

thanks,
--Long

Chris Lattner wrote: