summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/MC/StringTableBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/MC/StringTableBuilder.cpp')
-rw-r--r--contrib/llvm/lib/MC/StringTableBuilder.cpp77
1 files changed, 62 insertions, 15 deletions
diff --git a/contrib/llvm/lib/MC/StringTableBuilder.cpp b/contrib/llvm/lib/MC/StringTableBuilder.cpp
index 80e5522..9d95952 100644
--- a/contrib/llvm/lib/MC/StringTableBuilder.cpp
+++ b/contrib/llvm/lib/MC/StringTableBuilder.cpp
@@ -16,13 +16,29 @@
using namespace llvm;
-StringTableBuilder::StringTableBuilder(Kind K) : K(K) {}
+StringTableBuilder::StringTableBuilder(Kind K, unsigned Alignment)
+ : K(K), Alignment(Alignment) {
+ // Account for leading bytes in table so that offsets returned from add are
+ // correct.
+ switch (K) {
+ case RAW:
+ Size = 0;
+ break;
+ case MachO:
+ case ELF:
+ Size = 1;
+ break;
+ case WinCOFF:
+ Size = 4;
+ break;
+ }
+}
-typedef std::pair<StringRef, size_t> StringPair;
+typedef std::pair<CachedHash<StringRef>, size_t> StringPair;
// Returns the character at Pos from end of a string.
static int charTailAt(StringPair *P, size_t Pos) {
- StringRef S = P->first;
+ StringRef S = P->first.Val;
if (Pos >= S.size())
return -1;
return (unsigned char)S[S.size() - Pos - 1];
@@ -62,13 +78,32 @@ tailcall:
}
void StringTableBuilder::finalize() {
- std::vector<std::pair<StringRef, size_t> *> Strings;
+ finalizeStringTable(/*Optimize=*/true);
+}
+
+void StringTableBuilder::finalizeInOrder() {
+ finalizeStringTable(/*Optimize=*/false);
+}
+
+void StringTableBuilder::finalizeStringTable(bool Optimize) {
+ typedef std::pair<CachedHash<StringRef>, size_t> StringOffsetPair;
+ std::vector<StringOffsetPair *> Strings;
Strings.reserve(StringIndexMap.size());
- for (std::pair<StringRef, size_t> &P : StringIndexMap)
+ for (StringOffsetPair &P : StringIndexMap)
Strings.push_back(&P);
- if (!Strings.empty())
- multikey_qsort(&Strings[0], &Strings[0] + Strings.size(), 0);
+ if (!Strings.empty()) {
+ // If we're optimizing, sort by name. If not, sort by previously assigned
+ // offset.
+ if (Optimize) {
+ multikey_qsort(&Strings[0], &Strings[0] + Strings.size(), 0);
+ } else {
+ std::sort(Strings.begin(), Strings.end(),
+ [](const StringOffsetPair *LHS, const StringOffsetPair *RHS) {
+ return LHS->second < RHS->second;
+ });
+ }
+ }
switch (K) {
case RAW:
@@ -85,17 +120,28 @@ void StringTableBuilder::finalize() {
}
StringRef Previous;
- for (std::pair<StringRef, size_t> *P : Strings) {
- StringRef S = P->first;
+ for (StringOffsetPair *P : Strings) {
+ StringRef S = P->first.Val;
if (K == WinCOFF)
assert(S.size() > COFF::NameSize && "Short string in COFF string table!");
- if (Previous.endswith(S)) {
- P->second = StringTable.size() - S.size() - (K != RAW);
- continue;
+ if (Optimize && Previous.endswith(S)) {
+ size_t Pos = StringTable.size() - S.size() - (K != RAW);
+ if (!(Pos & (Alignment - 1))) {
+ P->second = Pos;
+ continue;
+ }
+ }
+
+ if (Optimize) {
+ size_t Start = alignTo(StringTable.size(), Alignment);
+ P->second = Start;
+ StringTable.append(Start - StringTable.size(), '\0');
+ } else {
+ assert(P->second == StringTable.size() &&
+ "different strtab offset after finalization");
}
- P->second = StringTable.size();
StringTable += S;
if (K != RAW)
StringTable += '\x00';
@@ -137,8 +183,9 @@ size_t StringTableBuilder::getOffset(StringRef S) const {
size_t StringTableBuilder::add(StringRef S) {
assert(!isFinalized());
- auto P = StringIndexMap.insert(std::make_pair(S, Size));
+ size_t Start = alignTo(Size, Alignment);
+ auto P = StringIndexMap.insert(std::make_pair(S, Start));
if (P.second)
- Size += S.size() + (K != RAW);
+ Size = Start + S.size() + (K != RAW);
return P.first->second;
}
OpenPOWER on IntegriCloud