1 //===- CodeGenDataWriter.h --------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains support for writing codegen data. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CGDATA_CODEGENDATAWRITER_H 14 #define LLVM_CGDATA_CODEGENDATAWRITER_H 15 16 #include "llvm/CGData/CodeGenData.h" 17 #include "llvm/CGData/OutlinedHashTreeRecord.h" 18 #include "llvm/Support/EndianStream.h" 19 #include "llvm/Support/Error.h" 20 21 namespace llvm { 22 23 /// A struct to define how the data stream should be patched. 24 struct CGDataPatchItem { 25 uint64_t Pos; // Where to patch. 26 uint64_t *D; // Pointer to an array of source data. 27 int N; // Number of elements in \c D array. 28 }; 29 30 /// A wrapper class to abstract writer stream with support of bytes 31 /// back patching. 32 class CGDataOStream { 33 public: CGDataOStream(raw_fd_ostream & FD)34 CGDataOStream(raw_fd_ostream &FD) 35 : IsFDOStream(true), OS(FD), LE(FD, llvm::endianness::little) {} CGDataOStream(raw_string_ostream & STR)36 CGDataOStream(raw_string_ostream &STR) 37 : IsFDOStream(false), OS(STR), LE(STR, llvm::endianness::little) {} 38 tell()39 uint64_t tell() { return OS.tell(); } write(uint64_t V)40 void write(uint64_t V) { LE.write<uint64_t>(V); } write32(uint32_t V)41 void write32(uint32_t V) { LE.write<uint32_t>(V); } write8(uint8_t V)42 void write8(uint8_t V) { LE.write<uint8_t>(V); } 43 44 // \c patch can only be called when all data is written and flushed. 45 // For raw_string_ostream, the patch is done on the target string 46 // directly and it won't be reflected in the stream's internal buffer. 47 void patch(ArrayRef<CGDataPatchItem> P); 48 49 // If \c OS is an instance of \c raw_fd_ostream, this field will be 50 // true. Otherwise, \c OS will be an raw_string_ostream. 51 bool IsFDOStream; 52 raw_ostream &OS; 53 support::endian::Writer LE; 54 }; 55 56 class CodeGenDataWriter { 57 /// The outlined hash tree to be written. 58 OutlinedHashTreeRecord HashTreeRecord; 59 60 /// A bit mask describing the kind of the codegen data. 61 CGDataKind DataKind = CGDataKind::Unknown; 62 63 public: 64 CodeGenDataWriter() = default; 65 ~CodeGenDataWriter() = default; 66 67 /// Add the outlined hash tree record. The input Record is released. 68 void addRecord(OutlinedHashTreeRecord &Record); 69 70 /// Write the codegen data to \c OS 71 Error write(raw_fd_ostream &OS); 72 73 /// Write the codegen data in text format to \c OS 74 Error writeText(raw_fd_ostream &OS); 75 76 /// Return the attributes of the current CGData. getCGDataKind()77 CGDataKind getCGDataKind() const { return DataKind; } 78 79 /// Return true if the header indicates the data has an outlined hash tree. hasOutlinedHashTree()80 bool hasOutlinedHashTree() const { 81 return static_cast<uint32_t>(DataKind) & 82 static_cast<uint32_t>(CGDataKind::FunctionOutlinedHashTree); 83 } 84 85 private: 86 /// The offset of the outlined hash tree in the file. 87 uint64_t OutlinedHashTreeOffset; 88 89 /// Write the codegen data header to \c COS 90 Error writeHeader(CGDataOStream &COS); 91 92 /// Write the codegen data header in text to \c OS 93 Error writeHeaderText(raw_fd_ostream &OS); 94 95 Error writeImpl(CGDataOStream &COS); 96 }; 97 98 } // end namespace llvm 99 100 #endif // LLVM_CGDATA_CODEGENDATAWRITER_H 101