mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-12 10:52:38 +00:00
[Remarks] Add support for internalizing a remark in a string table
In order to keep remarks around, we need to make them tied to a string table. Users then can delete the parser and rely on the string table to keep the memory of the strings alive and deduplicated. llvm-svn: 371233
This commit is contained in:
parent
a050307c05
commit
e14c0c5ae0
@ -51,6 +51,9 @@ struct StringTable {
|
||||
|
||||
/// Add a string to the table. It returns an unique ID of the string.
|
||||
std::pair<unsigned, StringRef> add(StringRef Str);
|
||||
/// Modify \p R to use strings from this string table. If the string table
|
||||
/// does not contain the strings, it adds them.
|
||||
void internalize(Remark &R);
|
||||
/// Serialize the string table to a stream. It is serialized as a little
|
||||
/// endian uint64 (the size of the table in bytes) followed by a sequence of
|
||||
/// NULL-terminated strings, where the N-th string is the string with the ID N
|
||||
|
@ -11,6 +11,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Remarks/RemarkStringTable.h"
|
||||
#include "llvm/Remarks/Remark.h"
|
||||
#include "llvm/Remarks/RemarkParser.h"
|
||||
#include "llvm/Support/EndianStream.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
@ -37,6 +38,22 @@ std::pair<unsigned, StringRef> StringTable::add(StringRef Str) {
|
||||
return {KV.first->second, KV.first->first()};
|
||||
}
|
||||
|
||||
void StringTable::internalize(Remark &R) {
|
||||
auto Impl = [&](StringRef &S) { S = add(S).second; };
|
||||
Impl(R.PassName);
|
||||
Impl(R.RemarkName);
|
||||
Impl(R.FunctionName);
|
||||
if (R.Loc)
|
||||
Impl(R.Loc->SourceFilePath);
|
||||
for (Argument &Arg : R.Args) {
|
||||
// We need to mutate elements from an ArrayRef here.
|
||||
Impl(Arg.Key);
|
||||
Impl(Arg.Val);
|
||||
if (Arg.Loc)
|
||||
Impl(Arg.Loc->SourceFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
void StringTable::serialize(raw_ostream &OS) const {
|
||||
// Emit the sequence of strings.
|
||||
for (StringRef Str : serialize()) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Remarks/Remark.h"
|
||||
#include "llvm/Remarks/RemarkStringTable.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
@ -75,3 +76,48 @@ TEST(RemarksAPI, ArgsAsMsg) {
|
||||
|
||||
EXPECT_EQ(R.getArgsAsMsg(), "can not do this because of that.");
|
||||
}
|
||||
|
||||
TEST(RemarksAPI, StringTableInternalize) {
|
||||
remarks::StringTable StrTab;
|
||||
|
||||
// Empty table.
|
||||
EXPECT_EQ(StrTab.SerializedSize, 0UL);
|
||||
|
||||
remarks::Remark R;
|
||||
R.RemarkType = remarks::Type::Missed;
|
||||
R.PassName = "pass";
|
||||
R.RemarkName = "name";
|
||||
R.FunctionName = "func";
|
||||
R.Loc = remarks::RemarkLocation{"path", 3, 4};
|
||||
R.Args.emplace_back();
|
||||
R.Args.back().Key = "keydebug";
|
||||
R.Args.back().Val = "valuedebug";
|
||||
R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
|
||||
|
||||
// Check that internalize starts using the strings from the string table.
|
||||
remarks::Remark R2 = R.clone();
|
||||
StrTab.internalize(R2);
|
||||
|
||||
// Check that the pointers in the remarks are different.
|
||||
EXPECT_NE(R.PassName.data(), R2.PassName.data());
|
||||
EXPECT_NE(R.RemarkName.data(), R2.RemarkName.data());
|
||||
EXPECT_NE(R.FunctionName.data(), R2.FunctionName.data());
|
||||
EXPECT_NE(R.Loc->SourceFilePath.data(), R2.Loc->SourceFilePath.data());
|
||||
EXPECT_NE(R.Args.back().Key.data(), R2.Args.back().Key.data());
|
||||
EXPECT_NE(R.Args.back().Val.data(), R2.Args.back().Val.data());
|
||||
EXPECT_NE(R.Args.back().Loc->SourceFilePath.data(),
|
||||
R2.Args.back().Loc->SourceFilePath.data());
|
||||
|
||||
// Check that the internalized remark is using the pointers from the string table.
|
||||
EXPECT_EQ(StrTab.add(R.PassName).second.data(), R2.PassName.data());
|
||||
EXPECT_EQ(StrTab.add(R.RemarkName).second.data(), R2.RemarkName.data());
|
||||
EXPECT_EQ(StrTab.add(R.FunctionName).second.data(), R2.FunctionName.data());
|
||||
EXPECT_EQ(StrTab.add(R.Loc->SourceFilePath).second.data(),
|
||||
R2.Loc->SourceFilePath.data());
|
||||
EXPECT_EQ(StrTab.add(R.Args.back().Key).second.data(),
|
||||
R2.Args.back().Key.data());
|
||||
EXPECT_EQ(StrTab.add(R.Args.back().Val).second.data(),
|
||||
R2.Args.back().Val.data());
|
||||
EXPECT_EQ(StrTab.add(R.Args.back().Loc->SourceFilePath).second.data(),
|
||||
R2.Args.back().Loc->SourceFilePath.data());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user