[cfe-dev] Question about libc++ basic_string methods, inline, and LTO linking in 3.5 vs 3.6

Eric Fiselier eric at efcs.ca
Tue Feb 17 10:36:18 PST 2015


> Some basic_string methods have "_LIBCPP_INLINE_VISIBILITY" in the <string> header, while others are not. Where can I look up the rules for which should be inline and which should not?

I'm not sure if there are rules. Ones that are not marked
_LIBCPP_INLINE_VISIBILITY should be externally instantiated in the
dynlib.

I'll look into what we are doing with operator+



On Wed, Feb 11, 2015 at 6:01 PM, Jan Voung <jvoung at chromium.org> wrote:
> Hi all,
>
> I hope someone could shed some light on the following.
>
> Some basic_string methods have "_LIBCPP_INLINE_VISIBILITY" in the <string>
> header, while others are not. Where can I look up the rules for which should
> be inline and which should not?
>
> Perhaps that is not the right question to ask, but it is related to a
> problem I'm seeing in LTO linking with LLVM/Clang/libc++ 3.5 vs 3.6. The
> string headers have not changed much so I'm thinking the relevant change is
> in LLVM or Clang.
>
> For PNaCl, we do linking in this manner:
>
> Step (1) LTO link of bitcode using gold, and the gold plugin.
>
> gold -plugin LLVMgold.so -plugin-opt=emit-llvm -o merged.bc bc.o bc2.o ...
> -lapp_native1.a -lapp_native2.a ...  -lc++ -lm ...
>
> For various reasons, the setup is such that bc{1,2,...}.o are bitcode,
> libc++ and libm are bitcode, and the libapp_native{1,2,...}.a are x86.
>
> Step (2) compile the merged.bc to x86 (as merged.o).
>
> Step (3) link native code: gold -o a.out merged.o -lapp_native1.a
> -lapp_native2.a ...
>
> Note that there is no native version of libc++ and libm, so they are absent
> in this step.
>
> In LLVM 3.5, step (1) would produce a merged.bc where
> "_ZNSt3__1plIcNS_11char_traitsIcEENS_9allocatorIcEEEENS_12basic_stringIT_T0_T1_EEPKS6_RKS9_"
> (an operator+ variant) is defined, but in 3.6 it is just a declaration.
>
> If I use the linker "-y _ZNSt3..." option in step (1), it explains that
> there are a few references to operator+ from within libc++, but no
> references from any of the bc.o, bc2.o. It is not defined in any of the
> bc.o, bc2.o either, but it is defined in libapp_native1.a and libc++. This
> is the same in 3.5 and 3.6.
>
> Since the operator+ variant is not in merged.bc w/ 3.6, step (3) ends up
> pulling the definition from a libapp_native1.a member. However, that member
> depends on libm for log/exp. For some reason, step (1) does not pull log/exp
> into merged.bc from the bitcode libm. So in the end, linking in step (3)
> fails with undefined references to log/exp. In 3.5, step 3 never needed to
> pull in that member of libapp_native1.a.
>
> If the operator+ variant was marked inline, then it would end up in
> merged.bc and there is no need to worry about log/exp either. That is why I
> ask about the "inline" rules.
>
> Otherwise, I'm wondering if it is a bug that, for reasons besides inline,
> step (1) did not end up with the operator+ definition in merged.bc. Or, is
> entirely reasonable for merged.bc to not have the definition of operator+
> (deferring to libapp_native1), and the bug is that merged.bc doesn't end up
> with the definition of log/exp? <speculation> Maybe a problem is that the
> member thought to have supplied operator+ from libapp_native1.a in step (1)
> is one that doesn't depend on log/exp, but the one ultimately chosen in step
> (3) is one that does depend on log/exp </speculation>.
>
> Or, is this whole setup of (1), (2), (3) unusual and not expected to work
> well?
>
> Thanks in advance,
>
> - Jan
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>



More information about the cfe-dev mailing list