Commit Graph

197 Commits

Author SHA1 Message Date
Peter Collingbourne f7b27d15f2 COFF: Implement SymbolBody::getDebugName() for DefinedBitcode symbols.
Differential Revision: http://reviews.llvm.org/D10827

llvm-svn: 241029
2015-06-30 00:47:52 +00:00
Rui Ueyama c15139bb6d COFF: Make DefinedCOFF one pointer smaller.
The size of this class actually matters because this is the
most popular class among all classes. We create a Defined symbol
for each defined symbol in a symbol table. That can be millions
for a large program. For example, linking LLD instantiates this
class millions times.

llvm-svn: 241025
2015-06-30 00:10:54 +00:00
Peter Collingbourne 79cfd437b5 COFF: Use LTOModule::getLinkerOpts() instead of reading the linker directives ourselves.
llvm-svn: 241020
2015-06-29 23:26:28 +00:00
Rui Ueyama dae1661436 COFF: Split ObjectFile::createSymbolBody into small functions. NFC.
llvm-svn: 241011
2015-06-29 22:16:21 +00:00
Rui Ueyama 579c21537a Move llvm_unreachable out of switch to avoid -Wswitch-covered-defualt.
llvm-svn: 241008
2015-06-29 21:59:34 +00:00
Rui Ueyama 81dd16a1e0 Silence MSVC "not all control paths return a value" warning.
llvm-svn: 241004
2015-06-29 21:46:46 +00:00
Chandler Carruth 64c17c7d67 [opt] Devirtualize the SymbolBody type hierarchy and start compacting
its members into the base class.

First, to help motivate this kind of change, understand that in
a self-link, LLD creates 5.5 million defined regular symbol bodies (and
6 million symbol bodies total). A significant portion of its time is
spent allocating the memory for these symbols, and befor ethis patch
the defined regular symbol body objects alone consumed some 420mb of
memory during the self link.

As a consequence, I think it is worth expending considerable effort to
make these objects as memory efficient as possible. This is the first of
several components of that. This change starts with the goal of removing
the virtual functins from SymbolBody so that it can avoid having a vptr
embedded in it when it already contains a "kind" member, and that member
can be much more compact than a vptr.

The primary way of doing this is to sink as much of the logic that we
would have to dispatch for into data in the base class. As part of this,
I made the various flags bits that will pack into a bitfield with the
kind tag. I also sank the Name down to eliminate the dispatch for that,
and used LLVM's RTTI-style dispatch for everything else (most of which
is cold and so doesn't matter terribly if we get minutely worse lowering
than a vtable dispatch).

As I was doing this, I wanted to make the RTTI-dispatch (which would
become much hotter than before) as efficient as possible, so I've
re-organized the tags somewhat. Notably, the common case (regular
defined symbols) is now zero which we can test for faster.

I also needed to rewrite the comparison routine used during resolving
symbols. This proved to be quite complex as the semantics of the
existing one were very subtle due to the back-and-forth virtual dispatch
caused by re-dispatching with reversed operands. I've consolidated it to
a single function and tried to comment it quite a bit more to help
explain what is going on. However, this may need more comments or other
explanations. It at least passes all the regression tests. I'm not
working on Windows, so I can't fully test it.

With all of these changes, the size of a DefinedRegular symbol on
a 64-bit build goes from 80 bytes to 64 bytes, and we save approximately
84mb or 20% of the memory consumed by these symbol bodies during the
link.

The link time appears marginally faster as well, and the profile hotness
of the memory allocation subsystem got a bit better, but there is still
a lot of allocation traffic.

Differential Revision: http://reviews.llvm.org/D10792

llvm-svn: 241001
2015-06-29 21:35:48 +00:00
Chandler Carruth ee5bf526eb [cleanup] Clean up the flow of creating a symbol body for regular symbols.
This uses a single cast and test to get the section for the symbol, and
uses the cast_or_null<> pattern throughout to handle the known type but
unknown non-null-ness.

No functionality changed.

Differential Revision: http://reviews.llvm.org/D10791

llvm-svn: 241000
2015-06-29 21:32:37 +00:00
Chandler Carruth 59013c387e [opt] Replace the recursive walk for GC with a worklist algorithm.
This flattens the entire liveness walk from a recursive mark approach to
a worklist approach. It also sinks the worklist management completely
out of the SectionChunk and into the Writer by exposing the ability to
iterato over children of a chunk and over the symbol bodies of relocated
symbols. I'm not 100% happy with the API names, so suggestions welcome
there.

This allows us to use a single worklist for the entire recursive walk
and would also be a natural place to take advantage of parallelism at
some future point.

With this, we completely inline away the GC walk into the
Writer::markLive function and it makes it very easy to profile what is
slow. Currently, time is being wasted checking whether a Chunk isa
SectionChunk (it essentially always is), finding (or skipping)
a replacement for a symbol, and chasing pointers between symbols and
their chunks. There are a bunch of things we can do to fix this, and its
easier to do them after this change IMO.

This change alone saves 1-2% of the time for my self-link of lld.exe
(which I'm running and benchmarking on Linux ironically).

Perhaps more notably, we'll no longer blow out the stack for large
links. =]

Just as an FYI, at this point, I/O is starting to really dominate the
profile. Well over 10% of the time appears to be inside the kernel doing
page table silliness. I think a decent chunk of this can be nuked as
well, but it's a little odd as cross-linking in this way isn't really
the primary goal here.

Differential Revision: http://reviews.llvm.org/D10790

llvm-svn: 240995
2015-06-29 21:12:49 +00:00
Chandler Carruth be6e80b012 [opt] Hoist the call throuh SymbolBody::getReplacement out of the inline
method to get a SymbolBody and into the callers, and kill now dead
includes.

This removes the need to have the SymbolBody definition when we're
defining the inline method and makes it a better inline method. That was
the only reason for a lot of header includes here. Removing these and
using forward declarations actually uncovers a bunch of cross-header
dependencies that I've fixed while I'm here, and will allow me to
introduce some *important* inline code into Chunks.h that requires the
definition of ObjectFile.

No functionality changed at this point.

Differential Revision: http://reviews.llvm.org/D10789

llvm-svn: 240982
2015-06-29 18:50:11 +00:00
Rui Ueyama 2d5e917bce COFF: Handle mangled entry symbol name.
Compilers recognize "main" function and don't mangle its name.
But if you use a different function as a user-defined entry name,
and if you didn't define that function with extern C, your entry
point function name is mangled. And the linker has to be able to
find that. This is relatively rare but can happen.

llvm-svn: 240953
2015-06-29 14:43:07 +00:00
Rui Ueyama 0fc26d21bd COFF: Create an empty file for /pdb.
Most build system depends on existence or time stamp of a file.
This patch is to create an empty file for /pdb:<filename> option
just to satisfy some build rules.

llvm-svn: 240948
2015-06-29 14:27:12 +00:00
Rui Ueyama 6b79ed128a COFF: Fix /export.
Mangled dllexported symbols may be defined in a library.
If that's the case, we have to read a member file from the library.

llvm-svn: 240947
2015-06-29 14:27:10 +00:00
Rui Ueyama 45044f47d3 COFF: Fix logic to find default entry name or subsystem.
The previous logic to find default entry name or subsystem does not
seem correct (i.e. was not compatible with MSVC linker). Previously,
default entry name was inferred from CRT functions and user-defined
entry functions. Subsystem was inferred from CRT functions.

Default entry name and subsystem are now inferred based on the
following table. Note that we no longer use CRT functions to infer
them.

               Entry name           Subsystem
  main         mainCRTStartup       console
  wmain        wmainCRTStartup      console
  WinMain      WinMainCRTStartup    windows
  wWinMain     wWinMainCRTStartup   windows

llvm-svn: 240922
2015-06-29 01:03:53 +00:00
Rui Ueyama f5313b3498 COFF: Allow mangled symbols as arguments for /export.
Usually dllexported symbols are defined with 'extern "C"',
so identifying them is easy. We can just do hash table lookup
to look up exported symbols.

However, C++ non-member functions are also allowed to be exported,
and they can be specified with unmangled name. So, if /export:foo
is given, we need to look up not only "foo" but also its all
mangled names. In MSVC mangling scheme, that means that we need to
look up any symbol which starts with "?foo@@Y".

In this patch, we scan the entire symbol table to search for
a mangled symbol. The symbol table is a DenseMap, and that doesn't
support table lookup by string prefix. This is of course very
inefficient. But that should be probably OK because the user
should always add 'extern "C"' to dllexported symbols.

llvm-svn: 240919
2015-06-28 22:16:41 +00:00
Rui Ueyama f24e6f8607 COFF: Undefined weak aliases are not fatal if /force is given.
llvm-svn: 240917
2015-06-28 20:34:09 +00:00
Rui Ueyama 016414f557 COFF: Add a comment.
llvm-svn: 240916
2015-06-28 20:07:08 +00:00
Rui Ueyama a8b60458ea COFF: Add /noentry flag.
This option is sometimes used to create a resource-only DLL that
doesn't need any initialization.

llvm-svn: 240915
2015-06-28 19:56:30 +00:00
Rui Ueyama 95925fd1ab COFF: Support /force flag.
This option is to ignore remaining undefined symbols and force
the linker to create an output file anyways.

The existing code assumes that there's no undefined symbol after
reportRemainingUndefines(). That assumption is legitimate.
I also don't want to mess up the existing code for this minor feature.
In order to keep it as is, remaining undefined symbols are replaced
with dummy defined symbols.

llvm-svn: 240913
2015-06-28 19:35:15 +00:00
Rui Ueyama 9d72f09efd COFF: Remove a function that doesn't do much itself. NFC.
llvm-svn: 240901
2015-06-28 03:05:38 +00:00
Rui Ueyama 06cf3df2d5 COFF: Handle LINK environment variable.
If LINK is defined and not empty, it's supposed to contain
command line options.

llvm-svn: 240900
2015-06-28 02:35:31 +00:00
Rui Ueyama b0a360bf15 COFF: Remove useless "explicit".
llvm-svn: 240899
2015-06-28 02:00:33 +00:00
Rui Ueyama 50be6edfa6 COFF: Make doICF non-recursive. NFC.
llvm-svn: 240898
2015-06-28 01:35:59 +00:00
Rui Ueyama 871847e32d COFF: Fix ICF correctness bug.
When comparing two COMDAT sections, we need to take section values
and associative sections into account. This patch fixes that bug.
It fixes a crash bug of llvm-tblgen when linked with /opt:lldicf.

One thing I don't understand yet is that this logic seems to be
too strict. MSVC linker is able to create more compact executables
(which of course work correctly). With this ICF algorithm, LLD is
able to make executable smaller, but the outputs are larger than
MSVC's. There must be something I'm missing here.

llvm-svn: 240897
2015-06-28 01:30:54 +00:00
Chandler Carruth 52eb355765 [opt] Inline a trivial lookup function into the header.
This function is actually *very* hot. It is hard to see currently
because the call graph is very recursive, but I'm working to remove that
and when I do this function becomes significantly higher on the profile
(up to 5%!) and so worth avoiding the call overhead.

No specific perf gain I can measure yet (below the noise), but likely to
have more impact as we stop cluttering the call graph.

Differential Revision: http://reviews.llvm.org/D10788

llvm-svn: 240873
2015-06-27 03:40:10 +00:00
Chandler Carruth 2eb15fff94 Switch the new COFF linker's symbol table to use a DenseMap of
StringRefs. This uses the LLVM hashing rather than the standard library
and a closed addressed hash table rather than chaining.

This improves the Windows self-link of LLD by 4.4% (averaged over 10
runs, with well under 1% of variance on each).

There is still some room to improve here. Two things I clearly see in
the profile:

1) This is one of the biggest stress tests for the LLVM hashing code. It
   actually consumes something like 3-4% of the link time after the
   change.
2) The way that StringRef keys are handled in the DenseMap interface is
   pretty suboptimal. We pay the price of checking for empty and
   tombstone keys when we could only possibly be looking for a normal
   key. But fixing this requires invasive API changes.

So there is still some headroom here.

Differential Revision: http://reviews.llvm.org/D10684

llvm-svn: 240871
2015-06-27 02:05:40 +00:00
Rui Ueyama 77731b4909 COFF: Use vector::erase instead of reallocating entire vector. NFC.
llvm-svn: 240862
2015-06-26 23:59:13 +00:00
Rui Ueyama 605e1f6b6c COFF: Avoid vector reallocation. NFC.
llvm-svn: 240859
2015-06-26 23:51:45 +00:00
Rui Ueyama 81ba1353ce COFF: Remove dead code.
llvm-svn: 240846
2015-06-26 22:14:41 +00:00
Rui Ueyama 810551a694 COFF: Add base relocation for delay-import table.
Because the address table of the delay-import table contains
absolute address, it needs to be added to the base relocation
table.

llvm-svn: 240844
2015-06-26 22:05:32 +00:00
Rui Ueyama 382dc96e29 COFF: Fix delay-import tables.
There were a few issues with the previous delay-import tables.

 - "Attribute" field should have been 1 instead of 0.
   (I don't know the meaning of this field, though.)
 - LEA and CALL operands had wrong addresses.
 - Address tables are in .didat (which is read-only).
   They should have been in .data.

llvm-svn: 240837
2015-06-26 21:40:15 +00:00
Peter Collingbourne baf5f87b6c Fix MSVC build.
llvm-svn: 240818
2015-06-26 19:20:09 +00:00
Peter Collingbourne be54955bba COFF: Implement /lldmap flag.
This flag can be used to produce a map file, which is essentially a list
of objects linked into the final output file together with the RVAs of
their symbols. Because our format differs from MSVC's we expose it as a
separate flag.

Differential Revision: http://reviews.llvm.org/D10773

llvm-svn: 240812
2015-06-26 18:58:24 +00:00
Rui Ueyama 7383562bc9 COFF: Align DLL import thunks on 16-byte boundaries.
llvm-svn: 240806
2015-06-26 18:28:56 +00:00
Rui Ueyama 5740abd7d3 COFF: Fix README.
llvm-svn: 240802
2015-06-26 17:59:12 +00:00
Rui Ueyama 3afe908294 COFF: Update README with the latest performance numbers.
llvm-svn: 240759
2015-06-26 04:26:02 +00:00
Rui Ueyama 32f8e1cb4e COFF: Change symbol resolution order for entry and /include.
We were resolving entry symbols and /include'd symbols after all other
symbols are resolved. But looks like it's too late. I found that it
causes some program to fail to link.

Let's say we have an object file A which defines symbols X and Y in an
archive. We also have another file B after A which defines X, Y and
_DLLMainCRTStartup in another archive. They conflict each other, so
either A or B can be linked.

If we have _DLLMainCRTStartup as an undefined symbol, file B is always
chosen. If not, there's a chance that A is chosen. If the linker
find it needs _DllMainCRTStartup after that, it's too late.

This patch adds undefined symbols to the symbol table as soon as
possible to fix the issue.

llvm-svn: 240757
2015-06-26 03:44:00 +00:00
Rui Ueyama ccde19d77e COFF: Fix local absolute symbols.
Absolute symbols were always handled as external symbols, so if two
or more object files define the same absolute symbol, they would
conflict even if the symbol is private to each file.
This patch fixes that bug.

llvm-svn: 240756
2015-06-26 03:09:23 +00:00
Rui Ueyama a29948873f COFF: Don't read non-x64 object files.
Currently the new LLD supports only x86-64.

llvm-svn: 240749
2015-06-26 00:42:21 +00:00
Rui Ueyama f799edef28 COFF: Rename /opt:icf -> /opt:lldicf.
ICF implemented in LLD is so experimental that we don't want to
enable that even if /opt:icf option is passed. I'll rename it back
once the feature is complete.

llvm-svn: 240721
2015-06-25 23:26:58 +00:00
Rui Ueyama 68633f1719 COFF: Better error message for duplicate symbols.
Now the symbol table prints out not only symbol names but
also file names for duplicate symbols.

llvm-svn: 240719
2015-06-25 23:22:00 +00:00
Rui Ueyama 9b921e5dc9 COFF: Merge DefinedRegular and DefinedCOMDAT.
I split them in r240319 because I thought they are different enough
that we should treat them as different types. It turned out that
that was not a good idea. They are so similar that we ended up having
many duplicate code.

llvm-svn: 240706
2015-06-25 22:00:42 +00:00
Rui Ueyama 5817ebb0c8 COFF: Fix lexer for the module-definition file.
Previously it would hang if there's a stray punctuation (e.g. ?).

llvm-svn: 240697
2015-06-25 21:06:00 +00:00
Rui Ueyama b0c001c055 COFF: Remove dead code.
llvm-svn: 240682
2015-06-25 20:12:15 +00:00
Rui Ueyama fc510f4cf8 COFF: Devirtualize mark(), markLive() and isCOMDAT().
Only SectionChunk can be dead-stripped. Previously,
all types of chunks implemented these functions,
but their functions were blank.

Likewise, only DefinedRegular and DefinedCOMDAT symbols
can be dead-stripped. markLive() function was implemented
for other symbol types, but they were blank.

I started thinking that the change I made in r240319 was
a mistake. I separated DefinedCOMDAT from DefinedRegular
because I thought that would make the code cleaner, but now
we want to handle them as the same type here. Maybe we
should roll it back.

This change should improve readability a bit as this removes
some dubious uses of reinterpret_cast. Previously, we
assumed that all COMDAT chunks are actually SectionChunks,
which was not very obvious.

llvm-svn: 240675
2015-06-25 19:10:58 +00:00
Rui Ueyama f34c088515 COFF: Simplify. NFC.
llvm-svn: 240666
2015-06-25 17:56:36 +00:00
Rui Ueyama c6fcfbc98a COFF: Use std::equal to compare two lists of relocations.
llvm-svn: 240665
2015-06-25 17:51:07 +00:00
Rui Ueyama 02c302790f COFF: Don't use COFFHeader->NumberOfRelocations.
The size of the field is 16 bit, so it's inaccurate if the
number of relocations in a section is more than 65535.

llvm-svn: 240661
2015-06-25 17:43:37 +00:00
Rui Ueyama 88e0f9206b COFF: Fix a bug of __imp_ symbol.
The change I made in r240620 was not correct. If a symbol foo is
defined, and if you use __imp_foo, __imp_foo symbol is automatically
defined as a pointer (not just an alias) to foo.

Now that we need to create a chunk for automatically-created symbols.
I defined LocalImportChunk class for them.

llvm-svn: 240622
2015-06-25 03:31:47 +00:00
Rui Ueyama d766653534 COFF: Handle undefined symbols starting with __imp_ in a special way.
MSVC linker is able to link an object file created from the following code.
Note that __imp_hello is not defined anywhere.

  void hello() { printf("Hello\n"); }
  extern void (*__imp_hello)();
  int main() { __imp_hello(); }

Function symbols exported from DLLs are automatically mangled by appending
__imp_ prefix, so they have two names (original one and with the prefix).
This "feature" seems to simulate that behavior even for non-DLL symbols.

This is in my opnion very odd feature. Even MSVC linker warns if you use this.
I'm adding that anyway for the sake of compatibiltiy.

llvm-svn: 240620
2015-06-25 02:21:44 +00:00