Linkages handling

Hello,
looking at Printer::doFinalization, I have some question about support of the
different linkages. Here's a table of how that method handles the possible
combinations:

                                 Initialized Null
Internal .data, local .data, .comm, .local
External .data, .globl .bss, .globl,
Appending ??? ???
LinkOnce llvm.linkonce.d data, .comm
                           .weak
Weak ??? ???

And the question I have are:

1. Does ld really supports appending linkage?
2. The difference between LLVM linkonce and weak is that linkone symbols can
be discared, if not used. I don't think there's anything in ld which matches
LLVM linkonce -- the symbols are never discarded. Am I wrong?
3. I've tries to figure out how linkonce works with ld. It appears that it
special cases sections starting with ".gnu.linkonce". In other words, naming
a spection "llvm.linkonce.d" has no effect. Is it true?
4. Can internal null-initialized data be placed in the ".bss" section, instead
of '.data' with '.comm' attribute, as is done now?
5. Can linkonce null-initialized data be placed in the ".data" section, with
the ".weak" attribute, instead of ".comm" attribute.

- Volodya

Hello,
looking at Printer::doFinalization, I have some question about support of the
different linkages. Here's a table of how that method handles the possible
combinations:

                                 Initialized Null
Internal .data, local .data, .comm, .local
External .data, .globl .bss, .globl,
Appending ??? ???
LinkOnce llvm.linkonce.d data, .comm
                           .weak
Weak ??? ???

And the question I have are:

1. Does ld really supports appending linkage?

Sorta. Appending linkage is the LLVM way of supporting the ld
"concatenation of sections" mechanism. I don't think any of our current
code generators support doing this, but the idea is that an appending
array could be emitted to a special section, which the linker will happily
append for you.

2. The difference between LLVM linkonce and weak is that linkone symbols can
be discared, if not used.

That is correct.

I don't think there's anything in ld which matches LLVM linkonce -- the
symbols are never discarded. Am I wrong?

I'm not sure, but it's safe to codegen linkonce the same as weak in a
backend. linkonce is primarily useful for LLVM->LLVM optimizers, such as
the dead global elimination pass.

3. I've tries to figure out how linkonce works with ld. It appears that it
special cases sections starting with ".gnu.linkonce". In other words, naming
a spection "llvm.linkonce.d" has no effect. Is it true?

I dunno. :slight_smile: I vagely recall reading something like that, and I'm pretty
sure there is SOME support for discarding unused objects, and I *think*
it's by section, but I don't really know. :slight_smile:

In any case, the LLVM optimizer should have done its job already, so I
wouldn't worry too much about this.

4. Can internal null-initialized data be placed in the ".bss" section, instead
of '.data' with '.comm' attribute, as is done now?

Yes, I think the X86 backend puts zero initialized globals in the .bss
section. The conditions are:

  if (GV->hasInitializer()) // if the global is not external
    if (GV->getInitializer()->isNullValue()) // zero initailized
      // it can go in .bss

If you look in X86/Printer.cpp:Printer::doFinalization you can see the
logic it is using. This was patterned mostly after what GCC was doing for
various cases, though it has a HUGE number of strange linkage types that
interact in bizarre ways so it's hard to tell.

5. Can linkonce null-initialized data be placed in the ".data" section, with
the ".weak" attribute, instead of ".comm" attribute.

I'm not sure, sorry.

-Chris