Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/tools/llvm-mca/CodeRegion.h
35258 views
1
//===-------------------------- CodeRegion.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
/// \file
9
///
10
/// This file implements class CodeRegion and CodeRegions, InstrumentRegion,
11
/// AnalysisRegions, and InstrumentRegions.
12
///
13
/// A CodeRegion describes a region of assembly code guarded by special LLVM-MCA
14
/// comment directives.
15
///
16
/// # LLVM-MCA-BEGIN foo
17
/// ... ## asm
18
/// # LLVM-MCA-END
19
///
20
/// A comment starting with substring LLVM-MCA-BEGIN marks the beginning of a
21
/// new region of code.
22
/// A comment starting with substring LLVM-MCA-END marks the end of the
23
/// last-seen region of code.
24
///
25
/// Code regions are not allowed to overlap. Each region can have a optional
26
/// description; internally, regions are described by a range of source
27
/// locations (SMLoc objects).
28
///
29
/// An instruction (a MCInst) is added to a CodeRegion R only if its
30
/// location is in range [R.RangeStart, R.RangeEnd].
31
///
32
/// A InstrumentRegion describes a region of assembly code guarded by
33
/// special LLVM-MCA comment directives.
34
///
35
/// # LLVM-MCA-<INSTRUMENTATION_TYPE> <data>
36
/// ... ## asm
37
///
38
/// where INSTRUMENTATION_TYPE is a type defined in llvm and expects to use
39
/// data.
40
///
41
/// A comment starting with substring LLVM-MCA-<INSTRUMENTATION_TYPE>
42
/// brings data into scope for llvm-mca to use in its analysis for
43
/// all following instructions.
44
///
45
/// If the same INSTRUMENTATION_TYPE is found later in the instruction list,
46
/// then the original InstrumentRegion will be automatically ended,
47
/// and a new InstrumentRegion will begin.
48
///
49
/// If there are comments containing the different INSTRUMENTATION_TYPEs,
50
/// then both data sets remain available. In contrast with a CodeRegion,
51
/// an InstrumentRegion does not need a comment to end the region.
52
//
53
// An instruction (a MCInst) is added to an InstrumentRegion R only
54
// if its location is in range [R.RangeStart, R.RangeEnd].
55
//
56
//===----------------------------------------------------------------------===//
57
58
#ifndef LLVM_TOOLS_LLVM_MCA_CODEREGION_H
59
#define LLVM_TOOLS_LLVM_MCA_CODEREGION_H
60
61
#include "llvm/ADT/ArrayRef.h"
62
#include "llvm/ADT/SmallPtrSet.h"
63
#include "llvm/ADT/SmallVector.h"
64
#include "llvm/ADT/StringMap.h"
65
#include "llvm/ADT/StringRef.h"
66
#include "llvm/MC/MCInst.h"
67
#include "llvm/MCA/CustomBehaviour.h"
68
#include "llvm/Support/Error.h"
69
#include "llvm/Support/SMLoc.h"
70
#include "llvm/Support/SourceMgr.h"
71
#include <vector>
72
73
namespace llvm {
74
namespace mca {
75
76
/// A region of assembly code.
77
///
78
/// It identifies a sequence of machine instructions.
79
class CodeRegion {
80
// An optional descriptor for this region.
81
llvm::StringRef Description;
82
// Instructions that form this region.
83
llvm::SmallVector<llvm::MCInst, 16> Instructions;
84
// Source location range.
85
llvm::SMLoc RangeStart;
86
llvm::SMLoc RangeEnd;
87
88
CodeRegion(const CodeRegion &) = delete;
89
CodeRegion &operator=(const CodeRegion &) = delete;
90
91
public:
92
CodeRegion(llvm::StringRef Desc, llvm::SMLoc Start)
93
: Description(Desc), RangeStart(Start) {}
94
95
virtual ~CodeRegion() = default;
96
97
void addInstruction(const llvm::MCInst &Instruction) {
98
Instructions.emplace_back(Instruction);
99
}
100
101
// Remove the given instructions from the set, for unsupported instructions
102
// being skipped. Returns an ArrayRef for the updated vector of Instructions.
103
[[nodiscard]] llvm::ArrayRef<llvm::MCInst>
104
dropInstructions(const llvm::SmallPtrSetImpl<const llvm::MCInst *> &Insts) {
105
if (Insts.empty())
106
return Instructions;
107
llvm::erase_if(Instructions, [&Insts](const llvm::MCInst &Inst) {
108
return Insts.contains(&Inst);
109
});
110
return Instructions;
111
}
112
113
llvm::SMLoc startLoc() const { return RangeStart; }
114
llvm::SMLoc endLoc() const { return RangeEnd; }
115
116
void setEndLocation(llvm::SMLoc End) { RangeEnd = End; }
117
bool empty() const { return Instructions.empty(); }
118
bool isLocInRange(llvm::SMLoc Loc) const;
119
120
llvm::ArrayRef<llvm::MCInst> getInstructions() const { return Instructions; }
121
122
llvm::StringRef getDescription() const { return Description; }
123
};
124
125
/// Alias AnalysisRegion with CodeRegion since CodeRegionGenerator
126
/// is absract and AnalysisRegionGenerator operates on AnalysisRegions
127
using AnalysisRegion = CodeRegion;
128
129
/// A CodeRegion that contains instrumentation that can be used
130
/// in analysis of the region.
131
class InstrumentRegion : public CodeRegion {
132
/// Instrument for this region.
133
UniqueInstrument I;
134
135
public:
136
InstrumentRegion(llvm::StringRef Desc, llvm::SMLoc Start, UniqueInstrument I)
137
: CodeRegion(Desc, Start), I(std::move(I)) {}
138
139
public:
140
Instrument *getInstrument() const { return I.get(); }
141
};
142
143
class CodeRegionParseError final : public Error {};
144
145
class CodeRegions {
146
CodeRegions(const CodeRegions &) = delete;
147
CodeRegions &operator=(const CodeRegions &) = delete;
148
149
protected:
150
// A source manager. Used by the tool to generate meaningful warnings.
151
llvm::SourceMgr &SM;
152
153
using UniqueCodeRegion = std::unique_ptr<CodeRegion>;
154
std::vector<UniqueCodeRegion> Regions;
155
llvm::StringMap<unsigned> ActiveRegions;
156
bool FoundErrors;
157
158
public:
159
CodeRegions(llvm::SourceMgr &S) : SM(S), FoundErrors(false) {}
160
virtual ~CodeRegions() = default;
161
162
typedef std::vector<UniqueCodeRegion>::iterator iterator;
163
typedef std::vector<UniqueCodeRegion>::const_iterator const_iterator;
164
165
iterator begin() { return Regions.begin(); }
166
iterator end() { return Regions.end(); }
167
const_iterator begin() const { return Regions.cbegin(); }
168
const_iterator end() const { return Regions.cend(); }
169
170
void addInstruction(const llvm::MCInst &Instruction);
171
llvm::SourceMgr &getSourceMgr() const { return SM; }
172
173
llvm::ArrayRef<llvm::MCInst> getInstructionSequence(unsigned Idx) const {
174
return Regions[Idx]->getInstructions();
175
}
176
177
bool empty() const {
178
return llvm::all_of(Regions, [](const UniqueCodeRegion &Region) {
179
return Region->empty();
180
});
181
}
182
183
bool isValid() const { return !FoundErrors; }
184
185
bool isRegionActive(llvm::StringRef Description) const {
186
return ActiveRegions.contains(Description);
187
}
188
189
virtual void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc) = 0;
190
virtual void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc,
191
UniqueInstrument Instrument) = 0;
192
virtual void endRegion(llvm::StringRef Description, llvm::SMLoc Loc) = 0;
193
};
194
195
struct AnalysisRegions : public CodeRegions {
196
AnalysisRegions(llvm::SourceMgr &S);
197
198
void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc) override;
199
void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc,
200
UniqueInstrument Instrument) override {}
201
void endRegion(llvm::StringRef Description, llvm::SMLoc Loc) override;
202
};
203
204
struct InstrumentRegions : public CodeRegions {
205
206
InstrumentRegions(llvm::SourceMgr &S);
207
208
void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc) override{};
209
void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc,
210
UniqueInstrument Instrument) override;
211
void endRegion(llvm::StringRef Description, llvm::SMLoc Loc) override;
212
213
const SmallVector<Instrument *> getActiveInstruments(llvm::SMLoc Loc) const;
214
};
215
216
} // namespace mca
217
} // namespace llvm
218
219
#endif
220
221