1 //===-------------------------- CodeRegion.cpp -----------------*- 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 methods from the CodeRegions interface.
12 //===----------------------------------------------------------------------===//
14 #include "CodeRegion.h"
19 bool CodeRegion::isLocInRange(SMLoc Loc
) const {
20 if (RangeEnd
.isValid() && Loc
.getPointer() > RangeEnd
.getPointer())
22 if (RangeStart
.isValid() && Loc
.getPointer() < RangeStart
.getPointer())
27 void CodeRegions::addInstruction(const MCInst
&Instruction
) {
28 SMLoc Loc
= Instruction
.getLoc();
29 for (UniqueCodeRegion
&Region
: Regions
)
30 if (Region
->isLocInRange(Loc
))
31 Region
->addInstruction(Instruction
);
34 AnalysisRegions::AnalysisRegions(llvm::SourceMgr
&S
) : CodeRegions(S
) {
35 // Create a default region for the input code sequence.
36 Regions
.emplace_back(std::make_unique
<CodeRegion
>("", SMLoc()));
39 void AnalysisRegions::beginRegion(StringRef Description
, SMLoc Loc
) {
40 if (ActiveRegions
.empty()) {
41 // Remove the default region if there is at least one user defined region.
42 // By construction, only the default region has an invalid start location.
43 if (Regions
.size() == 1 && !Regions
[0]->startLoc().isValid() &&
44 !Regions
[0]->endLoc().isValid()) {
45 ActiveRegions
[Description
] = 0;
46 Regions
[0] = std::make_unique
<CodeRegion
>(Description
, Loc
);
50 auto It
= ActiveRegions
.find(Description
);
51 if (It
!= ActiveRegions
.end()) {
52 const CodeRegion
&R
= *Regions
[It
->second
];
53 if (Description
.empty()) {
54 SM
.PrintMessage(Loc
, llvm::SourceMgr::DK_Error
,
55 "found multiple overlapping anonymous regions");
56 SM
.PrintMessage(R
.startLoc(), llvm::SourceMgr::DK_Note
,
57 "Previous anonymous region was defined here");
62 SM
.PrintMessage(Loc
, llvm::SourceMgr::DK_Error
,
63 "overlapping regions cannot have the same name");
64 SM
.PrintMessage(R
.startLoc(), llvm::SourceMgr::DK_Note
,
65 "region " + Description
+ " was previously defined here");
71 ActiveRegions
[Description
] = Regions
.size();
72 Regions
.emplace_back(std::make_unique
<CodeRegion
>(Description
, Loc
));
75 void AnalysisRegions::endRegion(StringRef Description
, SMLoc Loc
) {
76 if (Description
.empty()) {
77 // Special case where there is only one user defined region,
78 // and this LLVM-MCA-END directive doesn't provide a region name.
79 // In this case, we assume that the user simply wanted to just terminate
80 // the only active region.
81 if (ActiveRegions
.size() == 1) {
82 auto It
= ActiveRegions
.begin();
83 Regions
[It
->second
]->setEndLocation(Loc
);
84 ActiveRegions
.erase(It
);
88 // Special case where the region end marker applies to the default region.
89 if (ActiveRegions
.empty() && Regions
.size() == 1 &&
90 !Regions
[0]->startLoc().isValid() && !Regions
[0]->endLoc().isValid()) {
91 Regions
[0]->setEndLocation(Loc
);
96 auto It
= ActiveRegions
.find(Description
);
97 if (It
!= ActiveRegions
.end()) {
98 Regions
[It
->second
]->setEndLocation(Loc
);
99 ActiveRegions
.erase(It
);
104 SM
.PrintMessage(Loc
, llvm::SourceMgr::DK_Error
,
105 "found an invalid region end directive");
106 if (!Description
.empty()) {
107 SM
.PrintMessage(Loc
, llvm::SourceMgr::DK_Note
,
108 "unable to find an active region named " + Description
);
110 SM
.PrintMessage(Loc
, llvm::SourceMgr::DK_Note
,
111 "unable to find an active anonymous region");
115 InstrumentRegions::InstrumentRegions(llvm::SourceMgr
&S
) : CodeRegions(S
) {}
117 void InstrumentRegions::beginRegion(StringRef Description
, SMLoc Loc
,
118 UniqueInstrument I
) {
119 if (Description
.empty()) {
120 SM
.PrintMessage(Loc
, llvm::SourceMgr::DK_Error
,
121 "anonymous instrumentation regions are not permitted");
126 auto It
= ActiveRegions
.find(Description
);
127 if (It
!= ActiveRegions
.end()) {
128 const CodeRegion
&R
= *Regions
[It
->second
];
130 Loc
, llvm::SourceMgr::DK_Error
,
131 "overlapping instrumentation regions cannot be of the same kind");
132 SM
.PrintMessage(R
.startLoc(), llvm::SourceMgr::DK_Note
,
133 "instrumentation region " + Description
+
134 " was previously defined here");
139 ActiveRegions
[Description
] = Regions
.size();
140 Regions
.emplace_back(
141 std::make_unique
<InstrumentRegion
>(Description
, Loc
, std::move(I
)));
144 void InstrumentRegions::endRegion(StringRef Description
, SMLoc Loc
) {
145 auto It
= ActiveRegions
.find(Description
);
146 if (It
!= ActiveRegions
.end()) {
147 Regions
[It
->second
]->setEndLocation(Loc
);
148 ActiveRegions
.erase(It
);
153 SM
.PrintMessage(Loc
, llvm::SourceMgr::DK_Error
,
154 "found an invalid instrumentation region end directive");
155 if (!Description
.empty()) {
156 SM
.PrintMessage(Loc
, llvm::SourceMgr::DK_Note
,
157 "unable to find an active instrumentation region named " +
162 const SmallVector
<Instrument
*>
163 InstrumentRegions::getActiveInstruments(SMLoc Loc
) const {
164 SmallVector
<Instrument
*> AI
;
165 for (auto &R
: Regions
) {
166 if (R
->isLocInRange(Loc
)) {
167 InstrumentRegion
*IR
= static_cast<InstrumentRegion
*>(R
.get());
168 AI
.push_back(IR
->getInstrument());