LLVM 22.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
13using namespace llvm;
14using namespace llvm::xray;
15
16static constexpr unsigned long long mask(BlockVerifier::State S) {
17 return 1uLL << static_cast<std::size_t>(S);
18}
19
20static constexpr std::size_t number(BlockVerifier::State S) {
21 return static_cast<std::size_t>(S);
22}
23
25 switch (R) {
27 return "BufferExtents";
29 return "NewBuffer";
31 return "WallClockTime";
33 return "PIDEntry";
35 return "NewCPUId";
37 return "TSCWrap";
39 return "CustomEvent";
41 return "Function";
43 return "CallArg";
45 return "EndOfBuffer";
47 return "TypedEvent";
50 return "Unknown";
51 }
52 llvm_unreachable("Unkown state!");
53}
54
55namespace {
56
57struct Transition {
59 std::bitset<number(BlockVerifier::State::StateMax)> ToStates;
60};
61
62} // namespace
63
64Error BlockVerifier::transition(State To) {
65 using ToSet = std::bitset<number(State::StateMax)>;
66 static constexpr std::array<const Transition, number(State::StateMax)>
67 TransitionTable{{{State::Unknown,
69
71
73
76
78
83
88
93
98
104
110
111 {State::EndOfBuffer, {}}}};
112
113 if (CurrentRecord >= State::StateMax)
114 return createStringError(
115 std::make_error_code(std::errc::executable_format_error),
116 "BUG (BlockVerifier): Cannot find transition table entry for %s, "
117 "transitioning to %s.",
118 recordToString(CurrentRecord).data(), recordToString(To).data());
119
120 // If we're at an EndOfBuffer record, we ignore anything that follows that
121 // isn't a NewBuffer record.
122 if (CurrentRecord == State::EndOfBuffer && To != State::NewBuffer)
123 return Error::success();
124
125 auto &Mapping = TransitionTable[number(CurrentRecord)];
126 auto &Destinations = Mapping.ToStates;
127 assert(Mapping.From == CurrentRecord &&
128 "BUG: Wrong index for record mapping.");
129 if ((Destinations & ToSet(mask(To))) == 0)
130 return createStringError(
131 std::make_error_code(std::errc::executable_format_error),
132 "BlockVerifier: Invalid transition from %s to %s.",
133 recordToString(CurrentRecord).data(), recordToString(To).data());
134
135 CurrentRecord = To;
136 return Error::success();
137}
138
142
146
150
152 return transition(State::TSCWrap);
153}
154
158
162
166
168 return transition(State::CallArg);
169}
170
172
176
180
184
186 // The known terminal conditions are the following:
187 switch (CurrentRecord) {
189 case State::NewCPUId:
192 case State::Function:
193 case State::CallArg:
194 case State::TSCWrap:
195 return Error::success();
196 default:
197 return createStringError(
198 std::make_error_code(std::errc::executable_format_error),
199 "BlockVerifier: Invalid terminal condition %s, malformed block.",
200 recordToString(CurrentRecord).data());
201 }
202}
203
204void BlockVerifier::reset() { CurrentRecord = State::Unknown; }
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static constexpr unsigned long long mask(BlockVerifier::State S)
static StringRef recordToString(BlockVerifier::State R)
static constexpr std::size_t number(BlockVerifier::State S)
static Split data
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
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.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1305