diff options
| author | Hans Wennborg <hans@hanshq.net> | 2014-04-30 16:25:02 +0000 |
|---|---|---|
| committer | Hans Wennborg <hans@hanshq.net> | 2014-04-30 16:25:02 +0000 |
| commit | 83e6e1e926088ddb0dc3ec2356785044740e1421 (patch) | |
| tree | 04b81b9436fcb551f0f8d39fac928b5bf988857c /llvm/lib/Object/StringTableBuilder.cpp | |
| parent | a8c577e4544c8b7d8be51c5565cd341e5a4fb38f (diff) | |
| download | bcm5719-llvm-83e6e1e926088ddb0dc3ec2356785044740e1421.tar.gz bcm5719-llvm-83e6e1e926088ddb0dc3ec2356785044740e1421.zip | |
ELFObjectWriter: deduplicate suffices in strtab
We already do this for shstrtab, so might as well do it for strtab. This
extracts the string table building code into a separate class. The idea
is to use it for other object formats too.
I mostly wanted to do this for the general principle, but it does save a
little bit on object file size. I tried this on a clang bootstrap and
saved 0.54% on the sum of object file sizes (1.14 MB out of 212 MB for
a release build).
Differential Revision: http://reviews.llvm.org/D3533
llvm-svn: 207670
Diffstat (limited to 'llvm/lib/Object/StringTableBuilder.cpp')
| -rw-r--r-- | llvm/lib/Object/StringTableBuilder.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/llvm/lib/Object/StringTableBuilder.cpp b/llvm/lib/Object/StringTableBuilder.cpp new file mode 100644 index 00000000000..9152834a296 --- /dev/null +++ b/llvm/lib/Object/StringTableBuilder.cpp @@ -0,0 +1,51 @@ +//===-- StringTableBuilder.cpp - String table building utility ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/SmallVector.h" +#include "llvm/Object/StringTableBuilder.h" + +using namespace llvm; + +static bool compareBySuffix(StringRef a, StringRef b) { + size_t sizeA = a.size(); + size_t sizeB = b.size(); + size_t len = std::min(sizeA, sizeB); + for (size_t i = 0; i < len; ++i) { + char ca = a[sizeA - i - 1]; + char cb = b[sizeB - i - 1]; + if (ca != cb) + return ca > cb; + } + return sizeA > sizeB; +} + +void StringTableBuilder::finalize() { + SmallVector<StringRef, 8> Strings; + for (auto i = StringIndexMap.begin(), e = StringIndexMap.end(); i != e; ++i) + Strings.push_back(i->getKey()); + + std::sort(Strings.begin(), Strings.end(), compareBySuffix); + + // FIXME: Starting with a null byte is ELF specific. Generalize this so we + // can use the class with other object formats. + StringTable += '\x00'; + + StringRef Previous; + for (StringRef s : Strings) { + if (Previous.endswith(s)) { + StringIndexMap[s] = StringTable.size() - 1 - s.size(); + continue; + } + + StringIndexMap[s] = StringTable.size(); + StringTable += s; + StringTable += '\x00'; + Previous = s; + } +} |

