LLVM: lib/XRay/BlockVerifier.cpp Source File

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//===----------------------------------------------------------------------===//
8#include "llvm/XRay/BlockVerifier.h"
9#include "llvm/Support/Error.h"
10
11#include <bitset>
12
13using namespace llvm;
14using namespace llvm::xray;
15
16 static constexpr unsigned long long mask(BlockVerifier::State S) {
17 return 1uLL << static_cast<std::size_t>(S);
18}
19
20 static 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 {
58 BlockVerifier::State From;
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,
68 {mask(State::BufferExtents) | mask(State::NewBuffer)}},
69
70 {State::BufferExtents, {mask(State::NewBuffer)}},
71
72 {State::NewBuffer, {mask(State::WallClockTime)}},
73
74 {State::WallClockTime,
75 {mask(State::PIDEntry) | mask(State::NewCPUId)}},
76
77 {State::PIDEntry, {mask(State::NewCPUId)}},
78
79 {State::NewCPUId,
80 {mask(State::NewCPUId) | mask(State::TSCWrap) |
81 mask(State::CustomEvent) | mask(State::Function) |
82 mask(State::EndOfBuffer) | mask(State::TypedEvent)}},
83
84 {State::TSCWrap,
85 {mask(State::TSCWrap) | mask(State::NewCPUId) |
86 mask(State::CustomEvent) | mask(State::Function) |
87 mask(State::EndOfBuffer) | mask(State::TypedEvent)}},
88
89 {State::CustomEvent,
90 {mask(State::CustomEvent) | mask(State::TSCWrap) |
91 mask(State::NewCPUId) | mask(State::Function) |
92 mask(State::EndOfBuffer) | mask(State::TypedEvent)}},
93
94 {State::TypedEvent,
95 {mask(State::TypedEvent) | mask(State::TSCWrap) |
96 mask(State::NewCPUId) | mask(State::Function) |
97 mask(State::EndOfBuffer) | mask(State::CustomEvent)}},
98
99 {State::Function,
100 {mask(State::Function) | mask(State::TSCWrap) |
101 mask(State::NewCPUId) | mask(State::CustomEvent) |
102 mask(State::CallArg) | mask(State::EndOfBuffer) |
103 mask(State::TypedEvent)}},
104
105 {State::CallArg,
106 {mask(State::CallArg) | mask(State::Function) |
107 mask(State::TSCWrap) | mask(State::NewCPUId) |
108 mask(State::CustomEvent) | mask(State::EndOfBuffer) |
109 mask(State::TypedEvent)}},
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
148 return transition(State::NewCPUId);
149}
150
152 return transition(State::TSCWrap);
153}
154
158
162
166
168 return transition(State::CallArg);
169}
170
171 Error BlockVerifier::visit(PIDRecord &) { return transition(State::PIDEntry); }
172
176
180
182 return transition(State::Function);
183}
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
204 void 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.
Definition AddressRanges.h:18
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1305

Generated on for LLVM by doxygen 1.14.0

AltStyle によって変換されたページ (->オリジナル) /