Commit Graph

2721 Commits

Author SHA1 Message Date
Chandler Carruth cd632dc486 Don't rely on the elf test suites inputs when testing the driver. We
already have a perfectly cromulent test archive in the driver inputs.

llvm-svn: 231976
2015-03-11 22:12:40 +00:00
Chandler Carruth 5ad16c2ad0 Move the 'linker-script-test' binary to the tools directory.
The canonical LLVM directory arrangement places binaries in the 'utils/'
tree when they are used as part of building the project. For example,
the tblgen binaries are built out of 'utils/' trees.

Tools which are not used by any other part of the build, including
testing utilities, are just in the 'tools' directory. For example, in
Clang we have 'c-index-test' which is exactly the same kind of thing as
'linker-script-test'.

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

llvm-svn: 231973
2015-03-11 22:05:49 +00:00
Chandler Carruth c9cdc502f3 Fix a comparison function to actually be a SWO so that it conforms to
the spec required by std::sort and friends.

Ordering things this way also dramatically simplifies the code as
short-circuit ensures we can skip all of the negative tests.

I've left one FIXME where we're establishing a fairly arbitrary
ordering. Previously, the function compared all types as equal except
for the ones it explicitly handled, but it didn't delegate correctly to
the atomflags when doing so, and so it would fail to be a SWO. The two
possible fixes are to stop comparing the atom flags entirely, or to
establish some arbitrary ordering of the types.

Since it was pure luck which ordering of unequal types we ended up with
previously (the caller was std::sort, not std::stable_sort) I chose to
make the ordering explicit and guaranteed. This seems like the best
conservative approach as I suspect we would want to switch to
stable_sort otherwise in order to have deterministic output.

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

llvm-svn: 231968
2015-03-11 21:34:33 +00:00
Meador Inge 2ce1ea86d0 LinkerScript: Add parsing of the MEMORY command
This patch implements parsing of the GNU ld MEMORY command [1].
The command and the memory block definitions are parsed as
specified (including the slightly strange "o" and "l" keywords).
Evaluation will be added at a later point in time.

[1] https://sourceware.org/binutils/docs-2.25/ld/MEMORY.html

llvm-svn: 231928
2015-03-11 15:34:44 +00:00
Davide Italiano 243e03d819 Garbage collect an unused class in Atoms.h
This will be replaced by a more generic class to handle
all the default symbols in an executable, e.g. __init_array.

Differential Revision:	 http://reviews.llvm.org/D8234
Reviewed by:	shankare

llvm-svn: 231906
2015-03-11 05:31:07 +00:00
Chandler Carruth 96f02da75a The LLD tests require 'llvm-nm' to run as well, ensure that this is
built before running the test suite.

llvm-svn: 231770
2015-03-10 08:08:58 +00:00
Chandler Carruth 8300c76b15 Don't write output to 'a.out', write it to a temporary file. This fixes
the test when run frem a read-only checkout of the source tree.

llvm-svn: 231769
2015-03-10 08:06:49 +00:00
Chandler Carruth 1bdbf48fff Fix the local variable naming I used in r231765 to follow the LLD coding
conventions. Sorry for missing this before I committed the patch!

llvm-svn: 231766
2015-03-10 07:54:34 +00:00
Chandler Carruth b952e2287b Fix a bug where the code would use subscript a std::vector with the size
of the vector. For a vector 'v', '&v[v.size()]' isn't a valid way to
compute a pointer one-past-the-end of the vector. Instead, write the
loop in terms of iterators and save the beginning iterator. Once we have
that we can compute the beginning pointer from the beginning iterator,
and compute the distance which we should increment the beginning pointer
by subtracting the iterators.

What might be simpler would be to convert the function accepting a raw
pointer for begin and end to accept iterators or a range or some other
construct, but I wanted to keep this to a minimal bug-fix change.

This fixes a crash on any debug STL implementation which checks for
indexing out of bounds.

llvm-svn: 231765
2015-03-10 07:53:02 +00:00
Rui Ueyama 81ad639ed3 Use template aliases.
We dropped Visual Studio 2012 support, so we can use template aliases.

llvm-svn: 231756
2015-03-10 05:14:24 +00:00
Rui Ueyama 4a8821d48d Add SimpleAbsoluteAtom which is analogous to other Simple* atoms.
llvm-svn: 231718
2015-03-09 22:34:59 +00:00
Rui Ueyama bf3ac0b878 Remove COFFReference and use SimpleReference instead.
SimpleReference, which is defined in Core, provides the same functionality
as COFFReference does, so we don't need a custom class.

llvm-svn: 231715
2015-03-09 22:18:51 +00:00
Rafael Auler ad11d4c196 [LinkerScript] Implement linker script expression evaluation
The expression evaluation is needed when interpreting linker scripts, in order
to calculate the value for new symbols or to determine a new position to load
sections in memory. This commit extends Expression nodes from the linker script
AST with evaluation functions, and also contains a unit test.

http://reviews.llvm.org/D8156

llvm-svn: 231707
2015-03-09 21:43:35 +00:00
Rui Ueyama 6a3167d35a Remove dead code.
llvm-svn: 231688
2015-03-09 18:59:55 +00:00
Simon Atanasyan b9a1443576 [Mips] Remove unused include
No functional changes.

llvm-svn: 231646
2015-03-09 10:54:11 +00:00
Simon Atanasyan 01396035a2 [Mips] Remove redundant namespace qualifiers
No functional changes.

llvm-svn: 231645
2015-03-09 10:54:05 +00:00
Simon Atanasyan 45354087b1 [Mips] Rename local variables
No functional changes.

llvm-svn: 231644
2015-03-09 10:53:58 +00:00
Simon Atanasyan d3388cc9b6 [Mips] Implement R_MIPS_SUB relocation handling
llvm-svn: 231643
2015-03-09 10:53:50 +00:00
Simon Atanasyan 1397f520d4 [Mips] Implement R_MIPS_64 relocation handling
llvm-svn: 231642
2015-03-09 10:53:41 +00:00
Simon Atanasyan cc0ed289b4 [Mips] Refactoring of relocation handling functions
1. Move relocation addendum reading code to the MipsRelocationHandler
class to reduce code duplication.
2. Factor out the relocations calculation code into the separate
function to be ready to handle MIPS N64 ABI relocation chains.

No functional changes.

llvm-svn: 231641
2015-03-09 10:53:32 +00:00
Simon Atanasyan e604e8f970 [Mips] Show error message and stop linking in case of cross mode jump errors
llvm-svn: 231640
2015-03-09 10:53:24 +00:00
Simon Atanasyan 9af798f5e4 [Mips] Fix incorrect handling of cross mode jumps
We should not take in account a type of "source" symbol. Cross mode jump
adjustment is requred when target symbol and relocation belong to
different (regular/microMIPS) instruction sets.

llvm-svn: 231639
2015-03-09 10:53:15 +00:00
Davide Italiano 7b68b90c15 [MachO] Use setter for globalsAreDeadStripRoots. NFC intended.
llvm-svn: 231629
2015-03-09 06:05:42 +00:00
Rui Ueyama 5768e9fde9 Test: Use layout-after instead of layout-before.
Update the tests so that they use layout-after instead of layout-before.
In all other places, we use layout-afters as primary edges.

llvm-svn: 231627
2015-03-09 04:00:29 +00:00
Rui Ueyama 4cefbd8b72 Resolver: Fix incorrect DenseMap mapping info.
Previously, getEmptyKey and getTombstoneKey return the same value
in the sense of isEqual defined by the same class, although they
need to be distinct values. This could confuse DenseMap.

We didn't see any issue by this wrong code because we don't delete
elements from the symbol table. We only add or replace elements.
But this is a bug and needs to be fixed anyway.

llvm-svn: 231618
2015-03-09 02:00:54 +00:00
Rui Ueyama 2a08dca3f7 Remove unused function.
llvm-svn: 231616
2015-03-09 01:05:04 +00:00
Rui Ueyama d18a97cb7a PECOFF: Create layout-afters instead of layout-befores.
All readers except PE/COFF reader create layout-after edges to preserve
the original symbol order. PE/COFF uses layout-before edges as primary
edges for no reason.

This patch makes PE/COFF reader to create layout-after edges.
Resolver is updated to recognize reverse edges of layout-after edges
in the garbage collection pass.

Now we can retire layout-before edges. I don't do that in this patch
because if I do, I would have updated many tests to replace all
occurrrences of "layout-before" with "layout-after". So that's a TODO.

llvm-svn: 231615
2015-03-09 00:06:07 +00:00
Rui Ueyama f46b190465 PECOFF: Define and use BaseReloc type instead of std::pair.
"first" and "second" are not easy to memorize.
Define a type to use meaningful names.

llvm-svn: 231614
2015-03-08 22:49:27 +00:00
Rui Ueyama 803150c9d0 Revert r231552: Resolver: optimize fallback atoms.
This patch broke a buildbot.

llvm-svn: 231611
2015-03-08 21:31:38 +00:00
Rui Ueyama 04597ac258 Re-commit r231545: PECOFF: Do not add extraneous symbols to the dead strip root
That commit was reverted in r231582 as it was a culprit for
buildbot breakage. Turned out it's not.

llvm-svn: 231610
2015-03-08 21:31:36 +00:00
Rui Ueyama 47d101e613 PECOFF: Fix off-by-one error.
We accidentally skipped the last base relocation entry for each block.

llvm-svn: 231586
2015-03-08 03:23:43 +00:00
Rui Ueyama 31777ce9a1 PECOFF: Parallelize base relocation creation.
If an output is large, its base relocation section can be also large.
For example, chrome.dll is almost 300 MB, and it has about 9 million
base relocations. Creating the section took 1.5 seconds on my machine.

This patch changes the way to create the section so that we can use
parallel_sort to group base relocations by high bits. This change
makes the linker almost 4% faster for the above test case on my machine.
If I replace parallel_sort with std::sort, performance remains the same,
so single thread performance should remain the same.

This has no functionality change. The output should be identical as
before.

llvm-svn: 231585
2015-03-08 02:44:53 +00:00
Rui Ueyama 8ade983734 Resolver: Use LLVM StringMap and DenseMap.
All defined symbols from all archive files are inserted to _archiveMap,
so performance of hash table matters here (I'm not trying to convert
all std::maps with DenseMaps). This change seems to make the linker
0.5% - 1% faster for my test case.

llvm-svn: 231584
2015-03-08 02:44:51 +00:00
Rui Ueyama 0536677ad6 Remove sectionPosition attribute.
This code is simply dead. No one is using it.

http://reviews.llvm.org/D8125

llvm-svn: 231583
2015-03-08 01:01:40 +00:00
Rui Ueyama 316d64ea1d Revert r231545 to unbreak buildbot.
This patch reverts r231545 "PECOFF: Do not add extraneous symbols
to the dead strip root." CrWinClangLLD buildbot is currently broken.
Since I can't reproduce the issue locally, I'm reverting the most
relevant change.

llvm-svn: 231582
2015-03-08 00:26:53 +00:00
Rui Ueyama c6bf34418a Remove duplicate code. NFC.
llvm-svn: 231570
2015-03-07 16:49:14 +00:00
Rui Ueyama 51ae7e8622 Remove redundant empty destructors.
Both File and Atom have virtual destructors. We don't need to repeat
that in derived classes.

llvm-svn: 231568
2015-03-07 16:01:13 +00:00
Chandler Carruth 9244582b8d Update makefile to reflect that the Passes directory is gone here.
llvm-svn: 231557
2015-03-07 09:03:17 +00:00
Rui Ueyama 9b21ded6c8 Resolver: optimize fallback atoms.
Atoms with fallback atoms are never be added to the symbol table.
However, we added such atoms to _undefines array. We had to call
isCoalescedAway to identify and skip them. We should just stop
adding them in the first place.

This seems to make the linker ~1% faster in my test case.

llvm-svn: 231552
2015-03-07 04:23:46 +00:00
Rui Ueyama abd39f0549 Resolver: Reduce number of SymbolTable::isDefined function calls.
If an undefined symbol is added to the symbol table by the previous
call of SymbolTable::add, SymbolTable::isDefined will always return
false for the same symbol.

llvm-svn: 231551
2015-03-07 03:55:32 +00:00
Rui Ueyama 923147b954 Resolver: Reduce number of hash function call.
This is yet another optimization patch. Previously we called
SymbolTable::isDefined() and SymbolTable::findByName() from a very
frequently executed function. Because isDefined calls findByName,
findByName is called twice on each iteration.

findByName is not a cheap function. It computes a hash value for a
given symbol name. When linking C++ programs, it can be expensive
because of C++ mangled long symbols.

This patch reduces the number of call from 2 to 1. Performance
improvements by this patch was larger than I expected. Linking time
of chrome.dll gets almost 5% shorter.

llvm-svn: 231549
2015-03-07 03:22:37 +00:00
Rui Ueyama e9d646d448 PECOFF: Do not add extraneous symbols to the dead strip root.
Previously we added all undefined symbols found in object files to
the dead strip root. This patch makes the linker to stop doing that.
Undefined symbols would be resolved anyway, so this patch doesn't
change the linker behavior. It should slightly improve performance
but it's really marginal. This is a cleanup.

llvm-svn: 231545
2015-03-07 01:35:50 +00:00
Rui Ueyama d4dc7d5739 Remove unused typedefs.
llvm-svn: 231543
2015-03-07 01:04:40 +00:00
Rui Ueyama 48c134ecd9 Use multimap<T, U> instead of map<T, set<U>>. NFC.
llvm-svn: 231542
2015-03-07 01:00:44 +00:00
Rui Ueyama 2039fc1f42 Resolver: move code inside an assert.
llvm-svn: 231518
2015-03-06 21:15:06 +00:00
Rui Ueyama 93ceadfb7b PECOFF: Optimize the writer using parallel_for.
Previously applying 1 million relocations took about 2 seconds on my
Xeon 2.4GHz 8 core workstation. After this patch, it takes about 300
milliseconds. As a result, time to link chrome.dll becomes 23 seconds
to 21 seconds.

llvm-svn: 231454
2015-03-06 06:53:13 +00:00
Davide Italiano 5dfe0ffb0c We want to add the entry point to the root set unconditionally, but these
asserts don't allow us to do it. Remove them, they're not really needed
anyway. 

llvm-svn: 231445
2015-03-06 02:05:03 +00:00
Rui Ueyama 41ee2e3ff9 Remove unused function.
llvm-svn: 231444
2015-03-06 01:44:07 +00:00
Rui Ueyama 13003d7774 Core: Make the resolver faster.
In the resolver, we maintain a list of undefined symbols, and when we
visit an archive file, we check that file if undefined symbols can be
resolved using files in the archive. The archive file class provides
find() function to lookup a symbol.

Previously, we call find() for each undefined symbols. Archive files
may be visited multiple times if they are in a --start-group and
--end-group. If we visit a file M times and if we have N undefined
symbols, find() is called M*N times. I found that that is one of the
most significant bottlenecks in LLD when linking a large executable.

find() is not a very cheap operation because it looks up a hash table
for a given string. And a string, or a symbol name, can be pretty long
if you are dealing with C++ symbols.

We can eliminate the bottleneck.

Calling find() with the same symbol multiple times is a waste. If a
result of looking up a symbol is "not found", it stays "not found"
forever because the symbol simply doesn't exist in the archive.
Thus, we should call find() only for newly-added undefined symbols.
This optimization makes O(M*N) O(N).

In this patch, all undefined symbols are added to a vector. For each
archive/shared library file, we maintain a start position P. All
symbols [0, P) are already searched. [P, end of the vector) are not
searched yet. For each file, we scan the vector only once.

This patch changes the order in which undefined symbols are looked for.
Previously, we iterated over the result of _symbolTable.undefines().
Now we iterate over the new vector. This is a benign change but caused
differences in output if remaining undefines exist. This is why some
tests are updated.

The performance improvement of this patch seems sometimes significant.
Previously, linking chrome.dll on my workstation (Xeon 2.4GHz 8 cores)
took about 70 seconds. Now it takes (only?) 30 seconds!

http://reviews.llvm.org/D8091

llvm-svn: 231434
2015-03-06 00:28:41 +00:00
Rui Ueyama 25d5abdb3a Optimize resolver by using std::unordered_multimap.
_reverseRef is a multimap from atoms to atoms. The map contains
reverse edges of "layout-before" and "group" edges for dead-stripping.

The type of the variable was DenseMap<Atom *, DenseSet<Atom *>>.
This patch changes that to std::unordered_multimap<Atom *, Atom *>.

A DenseMap with a value type of DenseSet was not fast. Inserting 900k
items to the map took about 1.6 seconds on my workstation.
unordered_multimap on the other hand took only 0.6 seconds.
Use of the map also got faster -- originally markLive took 1.3 seconds
in the same test case, and it now took 1.0 seconds. In total we shove
off 1.3 seconds out of 27 seconds in that test case.

llvm-svn: 231432
2015-03-06 00:22:48 +00:00