xref: /freebsd/contrib/llvm-project/llvm/include/llvm/CGData/CodeGenDataReader.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- CodeGenDataReader.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 reading codegen data.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CGDATA_CODEGENDATAREADER_H
14 #define LLVM_CGDATA_CODEGENDATAREADER_H
15 
16 #include "llvm/CGData/CodeGenData.h"
17 #include "llvm/CGData/OutlinedHashTreeRecord.h"
18 #include "llvm/CGData/StableFunctionMapRecord.h"
19 #include "llvm/Support/Compiler.h"
20 #include "llvm/Support/LineIterator.h"
21 #include "llvm/Support/VirtualFileSystem.h"
22 
23 namespace llvm {
24 
25 class CodeGenDataReader {
26   cgdata_error LastError = cgdata_error::success;
27   std::string LastErrorMsg;
28 
29 public:
30   CodeGenDataReader() = default;
31   virtual ~CodeGenDataReader() = default;
32 
33   /// Read the header.  Required before reading first record.
34   virtual Error read() = 0;
35   /// Return the codegen data version.
36   virtual uint32_t getVersion() const = 0;
37   /// Return the codegen data kind.
38   virtual CGDataKind getDataKind() const = 0;
39   /// Return true if the data has an outlined hash tree.
40   virtual bool hasOutlinedHashTree() const = 0;
41   /// Return true if the data has a stable function map.
42   virtual bool hasStableFunctionMap() const = 0;
43   /// Return the outlined hash tree that is released from the reader.
releaseOutlinedHashTree()44   std::unique_ptr<OutlinedHashTree> releaseOutlinedHashTree() {
45     return std::move(HashTreeRecord.HashTree);
46   }
releaseStableFunctionMap()47   std::unique_ptr<StableFunctionMap> releaseStableFunctionMap() {
48     return std::move(FunctionMapRecord.FunctionMap);
49   }
50 
51   /// Factory method to create an appropriately typed reader for the given
52   /// codegen data file path and file system.
53   LLVM_ABI static Expected<std::unique_ptr<CodeGenDataReader>>
54   create(const Twine &Path, vfs::FileSystem &FS);
55 
56   /// Factory method to create an appropriately typed reader for the given
57   /// memory buffer.
58   LLVM_ABI static Expected<std::unique_ptr<CodeGenDataReader>>
59   create(std::unique_ptr<MemoryBuffer> Buffer);
60 
61   /// Extract the cgdata embedded in sections from the given object file and
62   /// merge them into the GlobalOutlineRecord. This is a static helper that
63   /// is used by `llvm-cgdata --merge` or ThinLTO's two-codegen rounds.
64   /// Optionally, \p CombinedHash can be used to compuate the combined hash of
65   /// the merged data.
66   LLVM_ABI static Error
67   mergeFromObjectFile(const object::ObjectFile *Obj,
68                       OutlinedHashTreeRecord &GlobalOutlineRecord,
69                       StableFunctionMapRecord &GlobalFunctionMapRecord,
70                       stable_hash *CombinedHash = nullptr);
71 
72 protected:
73   /// The outlined hash tree that has been read. When it's released by
74   /// releaseOutlinedHashTree(), it's no longer valid.
75   OutlinedHashTreeRecord HashTreeRecord;
76 
77   /// The stable function map that has been read. When it's released by
78   // releaseStableFunctionMap(), it's no longer valid.
79   StableFunctionMapRecord FunctionMapRecord;
80 
81   /// Set the current error and return same.
82   Error error(cgdata_error Err, const std::string &ErrMsg = "") {
83     LastError = Err;
84     LastErrorMsg = ErrMsg;
85     if (Err == cgdata_error::success)
86       return Error::success();
87     return make_error<CGDataError>(Err, ErrMsg);
88   }
89 
error(Error && E)90   Error error(Error &&E) {
91     handleAllErrors(std::move(E), [&](const CGDataError &IPE) {
92       LastError = IPE.get();
93       LastErrorMsg = IPE.getMessage();
94     });
95     return make_error<CGDataError>(LastError, LastErrorMsg);
96   }
97 
98   /// Clear the current error and return a successful one.
success()99   Error success() { return error(cgdata_error::success); }
100 };
101 
102 class LLVM_ABI IndexedCodeGenDataReader : public CodeGenDataReader {
103   /// The codegen data file contents.
104   std::unique_ptr<MemoryBuffer> DataBuffer;
105   /// The header
106   IndexedCGData::Header Header;
107 
108 public:
IndexedCodeGenDataReader(std::unique_ptr<MemoryBuffer> DataBuffer)109   IndexedCodeGenDataReader(std::unique_ptr<MemoryBuffer> DataBuffer)
110       : DataBuffer(std::move(DataBuffer)) {}
111   IndexedCodeGenDataReader(const IndexedCodeGenDataReader &) = delete;
112   IndexedCodeGenDataReader &
113   operator=(const IndexedCodeGenDataReader &) = delete;
114 
115   /// Return true if the given buffer is in binary codegen data format.
116   static bool hasFormat(const MemoryBuffer &Buffer);
117   /// Read the contents including the header.
118   Error read() override;
119   /// Return the codegen data version.
getVersion()120   uint32_t getVersion() const override { return Header.Version; }
121   /// Return the codegen data kind.
getDataKind()122   CGDataKind getDataKind() const override {
123     return static_cast<CGDataKind>(Header.DataKind);
124   }
125   /// Return true if the header indicates the data has an outlined hash tree.
126   /// This does not mean that the data is still available.
hasOutlinedHashTree()127   bool hasOutlinedHashTree() const override {
128     return Header.DataKind &
129            static_cast<uint32_t>(CGDataKind::FunctionOutlinedHashTree);
130   }
131   /// Return true if the header indicates the data has a stable function map.
hasStableFunctionMap()132   bool hasStableFunctionMap() const override {
133     return Header.DataKind &
134            static_cast<uint32_t>(CGDataKind::StableFunctionMergingMap);
135   }
136 };
137 
138 /// This format is a simple text format that's suitable for test data.
139 /// The header is a custom format starting with `:` per line to indicate which
140 /// codegen data is recorded. `#` is used to indicate a comment.
141 /// The subsequent data is a YAML format per each codegen data in order.
142 /// Currently, it only has a function outlined hash tree.
143 class LLVM_ABI TextCodeGenDataReader : public CodeGenDataReader {
144   /// The codegen data file contents.
145   std::unique_ptr<MemoryBuffer> DataBuffer;
146   /// Iterator over the profile data.
147   line_iterator Line;
148   /// Describe the kind of the codegen data.
149   CGDataKind DataKind = CGDataKind::Unknown;
150 
151 public:
TextCodeGenDataReader(std::unique_ptr<MemoryBuffer> DataBuffer_)152   TextCodeGenDataReader(std::unique_ptr<MemoryBuffer> DataBuffer_)
153       : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, true, '#') {}
154   TextCodeGenDataReader(const TextCodeGenDataReader &) = delete;
155   TextCodeGenDataReader &operator=(const TextCodeGenDataReader &) = delete;
156 
157   /// Return true if the given buffer is in text codegen data format.
158   static bool hasFormat(const MemoryBuffer &Buffer);
159   /// Read the contents including the header.
160   Error read() override;
161   /// Text format does not have version, so return 0.
getVersion()162   uint32_t getVersion() const override { return 0; }
163   /// Return the codegen data kind.
getDataKind()164   CGDataKind getDataKind() const override { return DataKind; }
165   /// Return true if the header indicates the data has an outlined hash tree.
166   /// This does not mean that the data is still available.
hasOutlinedHashTree()167   bool hasOutlinedHashTree() const override {
168     return static_cast<uint32_t>(DataKind) &
169            static_cast<uint32_t>(CGDataKind::FunctionOutlinedHashTree);
170   }
171   /// Return true if the header indicates the data has a stable function map.
172   /// This does not mean that the data is still available.
hasStableFunctionMap()173   bool hasStableFunctionMap() const override {
174     return static_cast<uint32_t>(DataKind) &
175            static_cast<uint32_t>(CGDataKind::StableFunctionMergingMap);
176   }
177 };
178 
179 } // end namespace llvm
180 
181 #endif // LLVM_CGDATA_CODEGENDATAREADER_H
182