• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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