LLVM 20.0.0git
BlockVerifier.cpp
Go to the documentation of this file.
1//===- BlockVerifier.cpp - FDR Block Verifier -----------------------------===//
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//===----------------------------------------------------------------------===//
10
11#include <bitset>
12
13namespace llvm {
14namespace xray {
15namespace {
16
17constexpr unsigned long long mask(BlockVerifier::State S) {
18 return 1uLL << static_cast<std::size_t>(S);
19}
20
21constexpr std::size_t number(BlockVerifier::State S) {
22 return static_cast<std::size_t>(S);
23}
24
25StringRef recordToString(BlockVerifier::State R) {
26 switch (R) {
28 return "BufferExtents";
30 return "NewBuffer";
32 return "WallClockTime";
34 return "PIDEntry";
36 return "NewCPUId";
38 return "TSCWrap";
40 return "CustomEvent";
42 return "Function";
44 return "CallArg";
46 return "EndOfBuffer";
48 return "TypedEvent";
51 return "Unknown";
52 }
53 llvm_unreachable("Unkown state!");
54}
55
56struct Transition {
59};
60
61} // namespace
62
63Error BlockVerifier::transition(State To) {
64 using ToSet = std::bitset<number(State::StateMax)>;
65 static constexpr std::array<const Transition, number(State::StateMax)>
66 TransitionTable{{{State::Unknown,
68
70
72
75
77
82
87
92
97
103
109
110 {State::EndOfBuffer, {}}}};
111
112 if (CurrentRecord >= State::StateMax)
113 return createStringError(
114 std::make_error_code(std::errc::executable_format_error),
115 "BUG (BlockVerifier): Cannot find transition table entry for %s, "
116 "transitioning to %s.",
117 recordToString(CurrentRecord).data(), recordToString(To).data());
118
119 // If we're at an EndOfBuffer record, we ignore anything that follows that
120 // isn't a NewBuffer record.
121 if (CurrentRecord == State::EndOfBuffer && To != State::NewBuffer)
122 return Error::success();
123
124 auto &Mapping = TransitionTable[number(CurrentRecord)];
125 auto &Destinations = Mapping.ToStates;
126 assert(Mapping.From == CurrentRecord &&
127 "BUG: Wrong index for record mapping.");
128 if ((Destinations & ToSet(mask(To))) == 0)
129 return createStringError(
130 std::make_error_code(std::errc::executable_format_error),
131 "BlockVerifier: Invalid transition from %s to %s.",
132 recordToString(CurrentRecord).data(), recordToString(To).data());
133
134 CurrentRecord = To;
135 return Error::success();
136} // namespace xray
137
139 return transition(State::BufferExtents);
140}
141
143 return transition(State::WallClockTime);
144}
145
147 return transition(State::NewCPUId);
148}
149
151 return transition(State::TSCWrap);
152}
153
155 return transition(State::CustomEvent);
156}
157
159 return transition(State::CustomEvent);
160}
161
163 return transition(State::TypedEvent);
164}
165
167 return transition(State::CallArg);
168}
169
171
173 return transition(State::NewBuffer);
174}
175
177 return transition(State::EndOfBuffer);
178}
179
181 return transition(State::Function);
182}
183
185 // The known terminal conditions are the following:
186 switch (CurrentRecord) {
188 case State::NewCPUId:
191 case State::Function:
192 case State::CallArg:
193 case State::TSCWrap:
194 return Error::success();
195 default:
196 return createStringError(
197 std::make_error_code(std::errc::executable_format_error),
198 "BlockVerifier: Invalid terminal condition %s, malformed block.",
199 recordToString(CurrentRecord).data());
200 }
201}
202
203void BlockVerifier::reset() { CurrentRecord = State::Unknown; }
204
205} // namespace xray
206} // namespace llvm
std::bitset< number(BlockVerifier::State::StateMax)> ToStates
BlockVerifier::State From
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Error visit(BufferExtents &) override
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1286
auto mask(ShuffFunc S, unsigned Length, OptArgs... args) -> MaskT