1 //===-------------------------- CodeRegion.h -------------------*- C++ -* -===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file implements class CodeRegion and CodeRegions, InstrumentRegion,
11 /// AnalysisRegions, and InstrumentRegions.
13 /// A CodeRegion describes a region of assembly code guarded by special LLVM-MCA
14 /// comment directives.
16 /// # LLVM-MCA-BEGIN foo
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.
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).
29 /// An instruction (a MCInst) is added to a CodeRegion R only if its
30 /// location is in range [R.RangeStart, R.RangeEnd].
32 /// A InstrumentRegion describes a region of assembly code guarded by
33 /// special LLVM-MCA comment directives.
35 /// # LLVM-MCA-<INSTRUMENTATION_TYPE> <data>
38 /// where INSTRUMENTATION_TYPE is a type defined in llvm and expects to use
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.
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.
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.
53 // An instruction (a MCInst) is added to an InstrumentRegion R only
54 // if its location is in range [R.RangeStart, R.RangeEnd].
56 //===----------------------------------------------------------------------===//
58 #ifndef LLVM_TOOLS_LLVM_MCA_CODEREGION_H
59 #define LLVM_TOOLS_LLVM_MCA_CODEREGION_H
61 #include "llvm/ADT/ArrayRef.h"
62 #include "llvm/ADT/SmallVector.h"
63 #include "llvm/ADT/StringMap.h"
64 #include "llvm/ADT/StringRef.h"
65 #include "llvm/MC/MCInst.h"
66 #include "llvm/MCA/CustomBehaviour.h"
67 #include "llvm/Support/Error.h"
68 #include "llvm/Support/SMLoc.h"
69 #include "llvm/Support/SourceMgr.h"
75 /// A region of assembly code.
77 /// It identifies a sequence of machine instructions.
79 // An optional descriptor for this region.
80 llvm::StringRef Description
;
81 // Instructions that form this region.
82 llvm::SmallVector
<llvm::MCInst
, 16> Instructions
;
83 // Source location range.
84 llvm::SMLoc RangeStart
;
87 CodeRegion(const CodeRegion
&) = delete;
88 CodeRegion
&operator=(const CodeRegion
&) = delete;
91 CodeRegion(llvm::StringRef Desc
, llvm::SMLoc Start
)
92 : Description(Desc
), RangeStart(Start
) {}
94 virtual ~CodeRegion() = default;
96 void addInstruction(const llvm::MCInst
&Instruction
) {
97 Instructions
.emplace_back(Instruction
);
100 llvm::SMLoc
startLoc() const { return RangeStart
; }
101 llvm::SMLoc
endLoc() const { return RangeEnd
; }
103 void setEndLocation(llvm::SMLoc End
) { RangeEnd
= End
; }
104 bool empty() const { return Instructions
.empty(); }
105 bool isLocInRange(llvm::SMLoc Loc
) const;
107 llvm::ArrayRef
<llvm::MCInst
> getInstructions() const { return Instructions
; }
109 llvm::StringRef
getDescription() const { return Description
; }
112 /// Alias AnalysisRegion with CodeRegion since CodeRegionGenerator
113 /// is absract and AnalysisRegionGenerator operates on AnalysisRegions
114 using AnalysisRegion
= CodeRegion
;
116 /// A CodeRegion that contains instrumentation that can be used
117 /// in analysis of the region.
118 class InstrumentRegion
: public CodeRegion
{
119 /// Instrument for this region.
123 InstrumentRegion(llvm::StringRef Desc
, llvm::SMLoc Start
, UniqueInstrument I
)
124 : CodeRegion(Desc
, Start
), I(std::move(I
)) {}
127 Instrument
*getInstrument() const { return I
.get(); }
130 class CodeRegionParseError final
: public Error
{};
133 CodeRegions(const CodeRegions
&) = delete;
134 CodeRegions
&operator=(const CodeRegions
&) = delete;
137 // A source manager. Used by the tool to generate meaningful warnings.
140 using UniqueCodeRegion
= std::unique_ptr
<CodeRegion
>;
141 std::vector
<UniqueCodeRegion
> Regions
;
142 llvm::StringMap
<unsigned> ActiveRegions
;
146 CodeRegions(llvm::SourceMgr
&S
) : SM(S
), FoundErrors(false) {}
147 virtual ~CodeRegions() = default;
149 typedef std::vector
<UniqueCodeRegion
>::iterator iterator
;
150 typedef std::vector
<UniqueCodeRegion
>::const_iterator const_iterator
;
152 iterator
begin() { return Regions
.begin(); }
153 iterator
end() { return Regions
.end(); }
154 const_iterator
begin() const { return Regions
.cbegin(); }
155 const_iterator
end() const { return Regions
.cend(); }
157 void addInstruction(const llvm::MCInst
&Instruction
);
158 llvm::SourceMgr
&getSourceMgr() const { return SM
; }
160 llvm::ArrayRef
<llvm::MCInst
> getInstructionSequence(unsigned Idx
) const {
161 return Regions
[Idx
]->getInstructions();
165 return llvm::all_of(Regions
, [](const UniqueCodeRegion
&Region
) {
166 return Region
->empty();
170 bool isValid() const { return !FoundErrors
; }
172 bool isRegionActive(llvm::StringRef Description
) const {
173 return ActiveRegions
.contains(Description
);
176 virtual void beginRegion(llvm::StringRef Description
, llvm::SMLoc Loc
) = 0;
177 virtual void beginRegion(llvm::StringRef Description
, llvm::SMLoc Loc
,
178 UniqueInstrument Instrument
) = 0;
179 virtual void endRegion(llvm::StringRef Description
, llvm::SMLoc Loc
) = 0;
182 struct AnalysisRegions
: public CodeRegions
{
183 AnalysisRegions(llvm::SourceMgr
&S
);
185 void beginRegion(llvm::StringRef Description
, llvm::SMLoc Loc
) override
;
186 void beginRegion(llvm::StringRef Description
, llvm::SMLoc Loc
,
187 UniqueInstrument Instrument
) override
{}
188 void endRegion(llvm::StringRef Description
, llvm::SMLoc Loc
) override
;
191 struct InstrumentRegions
: public CodeRegions
{
193 InstrumentRegions(llvm::SourceMgr
&S
);
195 void beginRegion(llvm::StringRef Description
, llvm::SMLoc Loc
) override
{};
196 void beginRegion(llvm::StringRef Description
, llvm::SMLoc Loc
,
197 UniqueInstrument Instrument
) override
;
198 void endRegion(llvm::StringRef Description
, llvm::SMLoc Loc
) override
;
200 const SmallVector
<Instrument
*> getActiveInstruments(llvm::SMLoc Loc
) const;