LLVM 20.0.0git
CodeGenData.cpp
Go to the documentation of this file.
1//===-- CodeGenData.cpp ---------------------------------------------------===//
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 codegen data that has stable summary which
10// can be used to optimize the code in the subsequent codegen.
11//
12//===----------------------------------------------------------------------===//
13
21
22#define DEBUG_TYPE "cg-data"
23
24using namespace llvm;
25using namespace cgdata;
26
27static std::string getCGDataErrString(cgdata_error Err,
28 const std::string &ErrMsg = "") {
29 std::string Msg;
31
32 switch (Err) {
33 case cgdata_error::success:
34 OS << "success";
35 break;
36 case cgdata_error::eof:
37 OS << "end of File";
38 break;
39 case cgdata_error::bad_magic:
40 OS << "invalid codegen data (bad magic)";
41 break;
42 case cgdata_error::bad_header:
43 OS << "invalid codegen data (file header is corrupt)";
44 break;
45 case cgdata_error::empty_cgdata:
46 OS << "empty codegen data";
47 break;
48 case cgdata_error::malformed:
49 OS << "malformed codegen data";
50 break;
51 case cgdata_error::unsupported_version:
52 OS << "unsupported codegen data version";
53 break;
54 }
55
56 // If optional error message is not empty, append it to the message.
57 if (!ErrMsg.empty())
58 OS << ": " << ErrMsg;
59
60 return OS.str();
61}
62
63namespace {
64
65// FIXME: This class is only here to support the transition to llvm::Error. It
66// will be removed once this transition is complete. Clients should prefer to
67// deal with the Error value directly, rather than converting to error_code.
68class CGDataErrorCategoryType : public std::error_category {
69 const char *name() const noexcept override { return "llvm.cgdata"; }
70
71 std::string message(int IE) const override {
72 return getCGDataErrString(static_cast<cgdata_error>(IE));
73 }
74};
75
76} // end anonymous namespace
77
78const std::error_category &llvm::cgdata_category() {
79 static CGDataErrorCategoryType ErrorCategory;
80 return ErrorCategory;
81}
82
83std::string CGDataError::message() const {
84 return getCGDataErrString(Err, Msg);
85}
86
87char CGDataError::ID = 0;
88
89namespace {
90
91const char *CodeGenDataSectNameCommon[] = {
92#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \
93 SectNameCommon,
95};
96
97const char *CodeGenDataSectNameCoff[] = {
98#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \
99 SectNameCoff,
101};
102
103const char *CodeGenDataSectNamePrefix[] = {
104#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) Prefix,
106};
107
108} // namespace
109
110namespace llvm {
111
114 bool AddSegmentInfo) {
115 std::string SectName;
116
117 if (OF == Triple::MachO && AddSegmentInfo)
118 SectName = CodeGenDataSectNamePrefix[CGSK];
119
120 if (OF == Triple::COFF)
121 SectName += CodeGenDataSectNameCoff[CGSK];
122 else
123 SectName += CodeGenDataSectNameCommon[CGSK];
124
125 return SectName;
126}
127
128std::unique_ptr<CodeGenData> CodeGenData::Instance = nullptr;
129std::once_flag CodeGenData::OnceFlag;
130
132 std::call_once(CodeGenData::OnceFlag, []() {
133 Instance = std::unique_ptr<CodeGenData>(new CodeGenData());
134
135 // TODO: Initialize writer or reader mode for the client optimization.
136 });
137 return *(Instance.get());
138}
139
140namespace IndexedCGData {
141
142Expected<Header> Header::readFromBuffer(const unsigned char *Curr) {
143 using namespace support;
144
145 static_assert(std::is_standard_layout_v<llvm::IndexedCGData::Header>,
146 "The header should be standard layout type since we use offset "
147 "of fields to read.");
148 Header H;
149 H.Magic = endian::readNext<uint64_t, endianness::little, unaligned>(Curr);
150 if (H.Magic != IndexedCGData::Magic)
151 return make_error<CGDataError>(cgdata_error::bad_magic);
152 H.Version = endian::readNext<uint32_t, endianness::little, unaligned>(Curr);
154 return make_error<CGDataError>(cgdata_error::unsupported_version);
155 H.DataKind = endian::readNext<uint32_t, endianness::little, unaligned>(Curr);
156
157 switch (H.Version) {
158 // When a new field is added to the header add a case statement here to
159 // compute the size as offset of the new field + size of the new field. This
160 // relies on the field being added to the end of the list.
162 "Please update the size computation below if a new field has "
163 "been added to the header, if not add a case statement to "
164 "fall through to the latest version.");
165 case 1ull:
166 H.OutlinedHashTreeOffset =
167 endian::readNext<uint64_t, endianness::little, unaligned>(Curr);
168 }
169
170 return H;
171}
172
173} // end namespace IndexedCGData
174
175namespace cgdata {
176
177void warn(Twine Message, std::string Whence, std::string Hint) {
179 if (!Whence.empty())
180 errs() << Whence << ": ";
181 errs() << Message << "\n";
182 if (!Hint.empty())
183 WithColor::note() << Hint << "\n";
184}
185
186void warn(Error E, StringRef Whence) {
187 if (E.isA<CGDataError>()) {
188 handleAllErrors(std::move(E), [&](const CGDataError &IPE) {
189 warn(IPE.message(), Whence.str(), "");
190 });
191 }
192}
193
194} // end namespace cgdata
195
196} // end namespace llvm
aarch64 promote const
static std::string getCGDataErrString(cgdata_error Err, const std::string &ErrMsg="")
Definition: CodeGenData.cpp:27
#define H(x, y, z)
Definition: MD5.cpp:57
static const char * name
Definition: SMEABIPass.cpp:50
raw_pwrite_stream & OS
static char ID
Definition: CodeGenData.h:93
std::string message() const override
Return the error message as a string.
Definition: CodeGenData.cpp:83
static CodeGenData & getInstance()
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
bool isA() const
Check whether one error is a subclass of another.
Definition: Error.h:247
Tagged union holding either a T or a Error.
Definition: Error.h:481
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:215
ObjectFormatType
Definition: Triple.h:297
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
static raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
Definition: WithColor.cpp:85
static raw_ostream & note()
Convenience method for printing "note: " to stderr.
Definition: WithColor.cpp:87
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
const uint64_t Magic
Definition: CodeGenData.h:176
void warn(Error E, StringRef Whence="")
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:977
cgdata_error
Definition: CodeGenData.h:47
const std::error_category & cgdata_category()
Definition: CodeGenData.cpp:78
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
CGDataSectKind
Definition: CodeGenData.h:29
std::string getCodeGenDataSectionName(CGDataSectKind CGSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
static Expected< Header > readFromBuffer(const unsigned char *Curr)