1e6d15924SDimitry Andric //===- RemarkStringTable.cpp ----------------------------------------------===// 2e6d15924SDimitry Andric // 3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e6d15924SDimitry Andric // 7e6d15924SDimitry Andric //===----------------------------------------------------------------------===// 8e6d15924SDimitry Andric // 9e6d15924SDimitry Andric // Implementation of the Remark string table used at remark generation. 10e6d15924SDimitry Andric // 11e6d15924SDimitry Andric //===----------------------------------------------------------------------===// 12e6d15924SDimitry Andric 13e6d15924SDimitry Andric #include "llvm/Remarks/RemarkStringTable.h" 14cfca06d7SDimitry Andric #include "llvm/ADT/StringRef.h" 151d5ae102SDimitry Andric #include "llvm/Remarks/Remark.h" 161d5ae102SDimitry Andric #include "llvm/Remarks/RemarkParser.h" 17cfca06d7SDimitry Andric #include "llvm/Support/raw_ostream.h" 18e6d15924SDimitry Andric #include <vector> 19e6d15924SDimitry Andric 20e6d15924SDimitry Andric using namespace llvm; 21e6d15924SDimitry Andric using namespace llvm::remarks; 22e6d15924SDimitry Andric StringTable(const ParsedStringTable & Other)236f8fc217SDimitry AndricStringTable::StringTable(const ParsedStringTable &Other) { 241d5ae102SDimitry Andric for (unsigned i = 0, e = Other.size(); i < e; ++i) 251d5ae102SDimitry Andric if (Expected<StringRef> MaybeStr = Other[i]) 261d5ae102SDimitry Andric add(*MaybeStr); 271d5ae102SDimitry Andric else 281d5ae102SDimitry Andric llvm_unreachable("Unexpected error while building remarks string table."); 291d5ae102SDimitry Andric } 301d5ae102SDimitry Andric add(StringRef Str)31e6d15924SDimitry Andricstd::pair<unsigned, StringRef> StringTable::add(StringRef Str) { 32e6d15924SDimitry Andric size_t NextID = StrTab.size(); 33e6d15924SDimitry Andric auto KV = StrTab.insert({Str, NextID}); 34e6d15924SDimitry Andric // If it's a new string, add it to the final size. 35e6d15924SDimitry Andric if (KV.second) 36e6d15924SDimitry Andric SerializedSize += KV.first->first().size() + 1; // +1 for the '\0' 37e6d15924SDimitry Andric // Can be either NextID or the previous ID if the string is already there. 38e6d15924SDimitry Andric return {KV.first->second, KV.first->first()}; 39e6d15924SDimitry Andric } 40e6d15924SDimitry Andric internalize(Remark & R)411d5ae102SDimitry Andricvoid StringTable::internalize(Remark &R) { 421d5ae102SDimitry Andric auto Impl = [&](StringRef &S) { S = add(S).second; }; 431d5ae102SDimitry Andric Impl(R.PassName); 441d5ae102SDimitry Andric Impl(R.RemarkName); 451d5ae102SDimitry Andric Impl(R.FunctionName); 461d5ae102SDimitry Andric if (R.Loc) 471d5ae102SDimitry Andric Impl(R.Loc->SourceFilePath); 481d5ae102SDimitry Andric for (Argument &Arg : R.Args) { 491d5ae102SDimitry Andric Impl(Arg.Key); 501d5ae102SDimitry Andric Impl(Arg.Val); 511d5ae102SDimitry Andric if (Arg.Loc) 521d5ae102SDimitry Andric Impl(Arg.Loc->SourceFilePath); 531d5ae102SDimitry Andric } 541d5ae102SDimitry Andric } 551d5ae102SDimitry Andric serialize(raw_ostream & OS) const56e6d15924SDimitry Andricvoid StringTable::serialize(raw_ostream &OS) const { 57e6d15924SDimitry Andric // Emit the sequence of strings. 58e6d15924SDimitry Andric for (StringRef Str : serialize()) { 59e6d15924SDimitry Andric OS << Str; 60e6d15924SDimitry Andric // Explicitly emit a '\0'. 61e6d15924SDimitry Andric OS.write('\0'); 62e6d15924SDimitry Andric } 63e6d15924SDimitry Andric } 64e6d15924SDimitry Andric serialize() const65e6d15924SDimitry Andricstd::vector<StringRef> StringTable::serialize() const { 66e6d15924SDimitry Andric std::vector<StringRef> Strings{StrTab.size()}; 67e6d15924SDimitry Andric for (const auto &KV : StrTab) 68e6d15924SDimitry Andric Strings[KV.second] = KV.first(); 69e6d15924SDimitry Andric return Strings; 70e6d15924SDimitry Andric } 71