[llvm] 628f11f - [DWARFLinkerParallel] Add StringTable class.
Alexey Lapshin via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 5 02:49:32 PDT 2023
Author: Alexey Lapshin
Date: 2023-04-05T11:42:24+02:00
New Revision: 628f11f78d33a182dbd9d8746a6e93dce08a8c44
URL: https://github.com/llvm/llvm-project/commit/628f11f78d33a182dbd9d8746a6e93dce08a8c44
DIFF: https://github.com/llvm/llvm-project/commit/628f11f78d33a182dbd9d8746a6e93dce08a8c44.diff
LOG: [DWARFLinkerParallel] Add StringTable class.
This patch adds StringTable class which is used to prepare
strings for emission into the .debug_str table. Specifically,
this class translates strings if necessary, keeps them in order,
assigns index and offset.
Differential Revision: https://reviews.llvm.org/D147529
Added:
llvm/include/llvm/DWARFLinkerParallel/StringTable.h
llvm/unittests/DWARFLinkerParallel/StringTableTest.cpp
Modified:
llvm/include/llvm/DWARFLinkerParallel/StringPool.h
llvm/unittests/DWARFLinkerParallel/CMakeLists.txt
Removed:
################################################################################
diff --git a/llvm/include/llvm/DWARFLinkerParallel/StringPool.h b/llvm/include/llvm/DWARFLinkerParallel/StringPool.h
index 52fb64cea1d1d..9eb0d759f6a9c 100644
--- a/llvm/include/llvm/DWARFLinkerParallel/StringPool.h
+++ b/llvm/include/llvm/DWARFLinkerParallel/StringPool.h
@@ -75,6 +75,8 @@ class StringPool : public ConcurrentHashTableByPtr<StringRef, StringEntry,
PerThreadStringAllocator, StringPoolEntryInfo>(
Allocator, InitialSize) {}
+ PerThreadStringAllocator &getAllocatorRef() { return Allocator; }
+
private:
PerThreadStringAllocator Allocator;
};
diff --git a/llvm/include/llvm/DWARFLinkerParallel/StringTable.h b/llvm/include/llvm/DWARFLinkerParallel/StringTable.h
new file mode 100644
index 0000000000000..ac1c39f3dcc66
--- /dev/null
+++ b/llvm/include/llvm/DWARFLinkerParallel/StringTable.h
@@ -0,0 +1,84 @@
+//===- StringTable.h --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DWARFLINKERPARALLEL_STRINGTABLE_H
+#define LLVM_DWARFLINKERPARALLEL_STRINGTABLE_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/DWARFLinkerParallel/StringPool.h"
+
+namespace llvm {
+namespace dwarflinker_parallel {
+
+using StringsVector = SmallVector<StringEntry *>;
+
+/// This class prepares strings for emission into .debug_str table:
+/// translates string if necessary, assigns index and offset, keeps in order.
+class StringTable {
+public:
+ StringTable(StringPool &Strings,
+ std::function<StringRef(StringRef)> StringsTranslator)
+ : Strings(Strings), StringsTranslator(StringsTranslator) {}
+ ~StringTable() {}
+
+ /// Add string to the vector of strings which should be emitted.
+ /// Translate input string if neccessary, assign index and offset.
+ /// \returns updated string entry.
+ StringEntry *add(StringEntry *String) {
+ // Translate string if necessary.
+ if (StringsTranslator)
+ String = Strings.insert(StringsTranslator(String->first())).first;
+
+ // Store String for emission and assign index and offset.
+ if (String->getValue() == nullptr) {
+ DwarfStringPoolEntry *NewEntry =
+ Strings.getAllocatorRef().Allocate<DwarfStringPoolEntry>();
+
+ NewEntry->Symbol = nullptr;
+ NewEntry->Index = StringEntriesForEmission.size();
+
+ if (StringEntriesForEmission.empty())
+ NewEntry->Offset = 0;
+ else {
+ StringEntry *PrevString = StringEntriesForEmission.back();
+ NewEntry->Offset =
+ PrevString->getValue()->Offset + PrevString->getKeyLength() + 1;
+ }
+
+ String->getValue() = NewEntry;
+ StringEntriesForEmission.push_back(String);
+ }
+
+ return String;
+ }
+
+ /// Erase contents of StringsForEmission.
+ void clear() { StringEntriesForEmission.clear(); }
+
+ /// Enumerate all strings in sequential order and call \p Handler for each
+ /// string.
+ void forEach(function_ref<void(DwarfStringPoolEntryRef)> Handler) const {
+ for (const StringEntry *Entry : StringEntriesForEmission)
+ Handler(*Entry);
+ }
+
+protected:
+ /// List of strings for emission.
+ StringsVector StringEntriesForEmission;
+
+ /// String pool for the translated strings.
+ StringPool &Strings;
+
+ /// Translator for the strings.
+ std::function<StringRef(StringRef)> StringsTranslator;
+};
+
+} // end of namespace dwarflinker_parallel
+} // end namespace llvm
+
+#endif // LLVM_DWARFLINKERPARALLEL_STRINGTABLE_H
diff --git a/llvm/unittests/DWARFLinkerParallel/CMakeLists.txt b/llvm/unittests/DWARFLinkerParallel/CMakeLists.txt
index ca2cb47283483..9f27c03fe46f7 100644
--- a/llvm/unittests/DWARFLinkerParallel/CMakeLists.txt
+++ b/llvm/unittests/DWARFLinkerParallel/CMakeLists.txt
@@ -6,6 +6,7 @@ set(LLVM_LINK_COMPONENTS
add_llvm_unittest(DWARFLinkerParallelTests
DWARFLinkerTest.cpp
StringPoolTest.cpp
+ StringTableTest.cpp
)
target_link_libraries(DWARFLinkerParallelTests PRIVATE LLVMTestingSupport)
diff --git a/llvm/unittests/DWARFLinkerParallel/StringTableTest.cpp b/llvm/unittests/DWARFLinkerParallel/StringTableTest.cpp
new file mode 100644
index 0000000000000..40795f5d38ae6
--- /dev/null
+++ b/llvm/unittests/DWARFLinkerParallel/StringTableTest.cpp
@@ -0,0 +1,104 @@
+//===- llvm/unittest/DWARFLinkerParallel/StringTableTest.cpp --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DWARFLinkerParallel/StringTable.h"
+#include "llvm/Support/Parallel.h"
+#include "gtest/gtest.h"
+#include <cstdlib>
+
+using namespace llvm;
+using namespace dwarflinker_parallel;
+
+namespace {
+
+TEST(StringPoolTest, TestStringTable) {
+ struct StringDescription {
+ const char *Str = nullptr;
+ uint64_t Idx = 0;
+ uint64_t Offset = 0;
+ };
+
+ SmallVector<StringDescription> InputStrings = {
+ {"first", 0, 0}, {"second", 1, 6}, {"third", 2, 13}};
+
+ StringPool Strings;
+ StringTable OutStrings(Strings, nullptr);
+
+ // Check string insertion.
+ StringEntry *FirstPtr = Strings.insert(InputStrings[0].Str).first;
+ StringEntry *SecondPtr = Strings.insert(InputStrings[1].Str).first;
+ StringEntry *ThirdPtr = Strings.insert(InputStrings[2].Str).first;
+
+ FirstPtr = OutStrings.add(FirstPtr);
+ SecondPtr = OutStrings.add(SecondPtr);
+ ThirdPtr = OutStrings.add(ThirdPtr);
+
+ // Check fields of inserted strings.
+ EXPECT_TRUE(FirstPtr->getKey() == InputStrings[0].Str);
+ EXPECT_TRUE(FirstPtr->getValue()->Offset == InputStrings[0].Offset);
+ EXPECT_TRUE(FirstPtr->getValue()->Index == InputStrings[0].Idx);
+
+ EXPECT_TRUE(SecondPtr->getKey() == InputStrings[1].Str);
+ EXPECT_TRUE(SecondPtr->getValue()->Offset == InputStrings[1].Offset);
+ EXPECT_TRUE(SecondPtr->getValue()->Index == InputStrings[1].Idx);
+
+ EXPECT_TRUE(ThirdPtr->getKey() == InputStrings[2].Str);
+ EXPECT_TRUE(ThirdPtr->getValue()->Offset == InputStrings[2].Offset);
+ EXPECT_TRUE(ThirdPtr->getValue()->Index == InputStrings[2].Idx);
+
+ // Check order enumerated strings.
+ uint64_t CurIdx = 0;
+ std::function<void(DwarfStringPoolEntryRef)> checkStr =
+ [&](DwarfStringPoolEntryRef Entry) {
+ EXPECT_TRUE(Entry.getEntry().isIndexed());
+ EXPECT_TRUE(Entry.getIndex() == CurIdx);
+ EXPECT_TRUE(Entry.getOffset() == InputStrings[CurIdx].Offset);
+ EXPECT_TRUE(Entry.getString() == InputStrings[CurIdx].Str);
+
+ CurIdx++;
+ };
+
+ OutStrings.forEach(checkStr);
+}
+
+TEST(StringPoolTest, TestStringTableWithTranslator) {
+ std::string Word;
+ std::function<StringRef(StringRef)> TranslatorFunc =
+ [&](StringRef InputString) -> StringRef {
+ Word.clear();
+ for (auto Sym : InputString)
+ Word.insert(Word.begin(), Sym);
+ Word += '0';
+ return Word;
+ };
+
+ StringPool Strings;
+ StringTable OutStrings(Strings, TranslatorFunc);
+
+ StringEntry *FirstPtr = Strings.insert("first").first;
+ StringEntry *SecondPtr = Strings.insert("second").first;
+ StringEntry *ThirdPtr = Strings.insert("third").first;
+
+ FirstPtr = OutStrings.add(FirstPtr);
+ SecondPtr = OutStrings.add(SecondPtr);
+ ThirdPtr = OutStrings.add(ThirdPtr);
+
+ EXPECT_TRUE(FirstPtr->getKey() == "tsrif0");
+ EXPECT_TRUE(FirstPtr->getValue()->Offset == 0);
+ EXPECT_TRUE(FirstPtr->getValue()->Index == 0);
+
+ EXPECT_TRUE(SecondPtr->getKey() == "dnoces0");
+ EXPECT_TRUE(SecondPtr->getValue()->Offset == 7);
+ EXPECT_TRUE(SecondPtr->getValue()->Index == 1);
+
+ EXPECT_TRUE(ThirdPtr->getKey() == "driht0");
+ EXPECT_TRUE(ThirdPtr->getValue()->Offset == 15);
+ EXPECT_TRUE(ThirdPtr->getValue()->Index == 2);
+}
+
+} // anonymous namespace
More information about the llvm-commits
mailing list