19bb55568SKyungwoo Lee //===- CodeGenDataWriter.cpp ----------------------------------------------===// 29bb55568SKyungwoo Lee // 39bb55568SKyungwoo Lee // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 49bb55568SKyungwoo Lee // See https://llvm.org/LICENSE.txt for license information. 59bb55568SKyungwoo Lee // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 69bb55568SKyungwoo Lee // 79bb55568SKyungwoo Lee //===----------------------------------------------------------------------===// 89bb55568SKyungwoo Lee // 99bb55568SKyungwoo Lee // This file contains support for writing codegen data. 109bb55568SKyungwoo Lee // 119bb55568SKyungwoo Lee //===----------------------------------------------------------------------===// 129bb55568SKyungwoo Lee 139bb55568SKyungwoo Lee #include "llvm/CGData/CodeGenDataWriter.h" 149bb55568SKyungwoo Lee 159bb55568SKyungwoo Lee #define DEBUG_TYPE "cg-data-writer" 169bb55568SKyungwoo Lee 179bb55568SKyungwoo Lee using namespace llvm; 189bb55568SKyungwoo Lee 199bb55568SKyungwoo Lee void CGDataOStream::patch(ArrayRef<CGDataPatchItem> P) { 209bb55568SKyungwoo Lee using namespace support; 219bb55568SKyungwoo Lee 229bb55568SKyungwoo Lee if (IsFDOStream) { 239bb55568SKyungwoo Lee raw_fd_ostream &FDOStream = static_cast<raw_fd_ostream &>(OS); 249bb55568SKyungwoo Lee const uint64_t LastPos = FDOStream.tell(); 259bb55568SKyungwoo Lee for (const auto &K : P) { 269bb55568SKyungwoo Lee FDOStream.seek(K.Pos); 279bb55568SKyungwoo Lee for (int I = 0; I < K.N; I++) 289bb55568SKyungwoo Lee write(K.D[I]); 299bb55568SKyungwoo Lee } 309bb55568SKyungwoo Lee // Reset the stream to the last position after patching so that users 319bb55568SKyungwoo Lee // don't accidentally overwrite data. This makes it consistent with 329bb55568SKyungwoo Lee // the string stream below which replaces the data directly. 339bb55568SKyungwoo Lee FDOStream.seek(LastPos); 349bb55568SKyungwoo Lee } else { 359bb55568SKyungwoo Lee raw_string_ostream &SOStream = static_cast<raw_string_ostream &>(OS); 369bb55568SKyungwoo Lee std::string &Data = SOStream.str(); // with flush 379bb55568SKyungwoo Lee for (const auto &K : P) { 389bb55568SKyungwoo Lee for (int I = 0; I < K.N; I++) { 399bb55568SKyungwoo Lee uint64_t Bytes = 409bb55568SKyungwoo Lee endian::byte_swap<uint64_t, llvm::endianness::little>(K.D[I]); 419bb55568SKyungwoo Lee Data.replace(K.Pos + I * sizeof(uint64_t), sizeof(uint64_t), 429bb55568SKyungwoo Lee reinterpret_cast<const char *>(&Bytes), sizeof(uint64_t)); 439bb55568SKyungwoo Lee } 449bb55568SKyungwoo Lee } 459bb55568SKyungwoo Lee } 469bb55568SKyungwoo Lee } 479bb55568SKyungwoo Lee 489bb55568SKyungwoo Lee void CodeGenDataWriter::addRecord(OutlinedHashTreeRecord &Record) { 499bb55568SKyungwoo Lee assert(Record.HashTree && "empty hash tree in the record"); 509bb55568SKyungwoo Lee HashTreeRecord.HashTree = std::move(Record.HashTree); 519bb55568SKyungwoo Lee 529bb55568SKyungwoo Lee DataKind |= CGDataKind::FunctionOutlinedHashTree; 539bb55568SKyungwoo Lee } 549bb55568SKyungwoo Lee 55*ffcf3c86SKyungwoo Lee void CodeGenDataWriter::addRecord(StableFunctionMapRecord &Record) { 56*ffcf3c86SKyungwoo Lee assert(Record.FunctionMap && "empty function map in the record"); 57*ffcf3c86SKyungwoo Lee FunctionMapRecord.FunctionMap = std::move(Record.FunctionMap); 58*ffcf3c86SKyungwoo Lee 59*ffcf3c86SKyungwoo Lee DataKind |= CGDataKind::StableFunctionMergingMap; 60*ffcf3c86SKyungwoo Lee } 61*ffcf3c86SKyungwoo Lee 629bb55568SKyungwoo Lee Error CodeGenDataWriter::write(raw_fd_ostream &OS) { 639bb55568SKyungwoo Lee CGDataOStream COS(OS); 649bb55568SKyungwoo Lee return writeImpl(COS); 659bb55568SKyungwoo Lee } 669bb55568SKyungwoo Lee 679bb55568SKyungwoo Lee Error CodeGenDataWriter::writeHeader(CGDataOStream &COS) { 689bb55568SKyungwoo Lee using namespace support; 699bb55568SKyungwoo Lee IndexedCGData::Header Header; 709bb55568SKyungwoo Lee Header.Magic = IndexedCGData::Magic; 719bb55568SKyungwoo Lee Header.Version = IndexedCGData::Version; 729bb55568SKyungwoo Lee 739bb55568SKyungwoo Lee // Set the CGDataKind depending on the kind. 749bb55568SKyungwoo Lee Header.DataKind = 0; 759bb55568SKyungwoo Lee if (static_cast<bool>(DataKind & CGDataKind::FunctionOutlinedHashTree)) 769bb55568SKyungwoo Lee Header.DataKind |= 779bb55568SKyungwoo Lee static_cast<uint32_t>(CGDataKind::FunctionOutlinedHashTree); 78*ffcf3c86SKyungwoo Lee if (static_cast<bool>(DataKind & CGDataKind::StableFunctionMergingMap)) 79*ffcf3c86SKyungwoo Lee Header.DataKind |= 80*ffcf3c86SKyungwoo Lee static_cast<uint32_t>(CGDataKind::StableFunctionMergingMap); 819bb55568SKyungwoo Lee Header.OutlinedHashTreeOffset = 0; 82*ffcf3c86SKyungwoo Lee Header.StableFunctionMapOffset = 0; 839bb55568SKyungwoo Lee 849bb55568SKyungwoo Lee // Only write up to the CGDataKind. We need to remember the offset of the 859bb55568SKyungwoo Lee // remaining fields to allow back-patching later. 869bb55568SKyungwoo Lee COS.write(Header.Magic); 879bb55568SKyungwoo Lee COS.write32(Header.Version); 889bb55568SKyungwoo Lee COS.write32(Header.DataKind); 899bb55568SKyungwoo Lee 909bb55568SKyungwoo Lee // Save the location of Header.OutlinedHashTreeOffset field in \c COS. 919bb55568SKyungwoo Lee OutlinedHashTreeOffset = COS.tell(); 929bb55568SKyungwoo Lee 939bb55568SKyungwoo Lee // Reserve the space for OutlinedHashTreeOffset field. 949bb55568SKyungwoo Lee COS.write(0); 959bb55568SKyungwoo Lee 96*ffcf3c86SKyungwoo Lee // Save the location of Header.StableFunctionMapOffset field in \c COS. 97*ffcf3c86SKyungwoo Lee StableFunctionMapOffset = COS.tell(); 98*ffcf3c86SKyungwoo Lee 99*ffcf3c86SKyungwoo Lee // Reserve the space for StableFunctionMapOffset field. 100*ffcf3c86SKyungwoo Lee COS.write(0); 101*ffcf3c86SKyungwoo Lee 1029bb55568SKyungwoo Lee return Error::success(); 1039bb55568SKyungwoo Lee } 1049bb55568SKyungwoo Lee 1059bb55568SKyungwoo Lee Error CodeGenDataWriter::writeImpl(CGDataOStream &COS) { 1069bb55568SKyungwoo Lee if (Error E = writeHeader(COS)) 1079bb55568SKyungwoo Lee return E; 1089bb55568SKyungwoo Lee 1099bb55568SKyungwoo Lee uint64_t OutlinedHashTreeFieldStart = COS.tell(); 1109bb55568SKyungwoo Lee if (hasOutlinedHashTree()) 1119bb55568SKyungwoo Lee HashTreeRecord.serialize(COS.OS); 112*ffcf3c86SKyungwoo Lee uint64_t StableFunctionMapFieldStart = COS.tell(); 113*ffcf3c86SKyungwoo Lee if (hasStableFunctionMap()) 114*ffcf3c86SKyungwoo Lee FunctionMapRecord.serialize(COS.OS); 1159bb55568SKyungwoo Lee 1169bb55568SKyungwoo Lee // Back patch the offsets. 1179bb55568SKyungwoo Lee CGDataPatchItem PatchItems[] = { 118*ffcf3c86SKyungwoo Lee {OutlinedHashTreeOffset, &OutlinedHashTreeFieldStart, 1}, 119*ffcf3c86SKyungwoo Lee {StableFunctionMapOffset, &StableFunctionMapFieldStart, 1}}; 1209bb55568SKyungwoo Lee COS.patch(PatchItems); 1219bb55568SKyungwoo Lee 1229bb55568SKyungwoo Lee return Error::success(); 1239bb55568SKyungwoo Lee } 1249bb55568SKyungwoo Lee 1259bb55568SKyungwoo Lee Error CodeGenDataWriter::writeHeaderText(raw_fd_ostream &OS) { 1269bb55568SKyungwoo Lee if (hasOutlinedHashTree()) 1279bb55568SKyungwoo Lee OS << "# Outlined stable hash tree\n:outlined_hash_tree\n"; 1289bb55568SKyungwoo Lee 129*ffcf3c86SKyungwoo Lee if (hasStableFunctionMap()) 130*ffcf3c86SKyungwoo Lee OS << "# Stable function map\n:stable_function_map\n"; 131*ffcf3c86SKyungwoo Lee 1329bb55568SKyungwoo Lee // TODO: Add more data types in this header 1339bb55568SKyungwoo Lee 1349bb55568SKyungwoo Lee return Error::success(); 1359bb55568SKyungwoo Lee } 1369bb55568SKyungwoo Lee 1379bb55568SKyungwoo Lee Error CodeGenDataWriter::writeText(raw_fd_ostream &OS) { 1389bb55568SKyungwoo Lee if (Error E = writeHeaderText(OS)) 1399bb55568SKyungwoo Lee return E; 1409bb55568SKyungwoo Lee 1419bb55568SKyungwoo Lee yaml::Output YOS(OS); 1429bb55568SKyungwoo Lee if (hasOutlinedHashTree()) 1439bb55568SKyungwoo Lee HashTreeRecord.serializeYAML(YOS); 1449bb55568SKyungwoo Lee 145*ffcf3c86SKyungwoo Lee if (hasStableFunctionMap()) 146*ffcf3c86SKyungwoo Lee FunctionMapRecord.serializeYAML(YOS); 147*ffcf3c86SKyungwoo Lee 1489bb55568SKyungwoo Lee // TODO: Write more yaml cgdata in order 1499bb55568SKyungwoo Lee 1509bb55568SKyungwoo Lee return Error::success(); 1519bb55568SKyungwoo Lee } 152