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 CodeRegions::CodeRegions(llvm::SourceMgr
&S
) : SM(S
), FoundErrors(false) {
20 // Create a default region for the input code sequence.
21 Regions
.emplace_back(std::make_unique
<CodeRegion
>("", SMLoc()));
24 bool CodeRegion::isLocInRange(SMLoc Loc
) const {
25 if (RangeEnd
.isValid() && Loc
.getPointer() > RangeEnd
.getPointer())
27 if (RangeStart
.isValid() && Loc
.getPointer() < RangeStart
.getPointer())
32 void CodeRegions::beginRegion(StringRef Description
, SMLoc Loc
) {
33 if (ActiveRegions
.empty()) {
34 // Remove the default region if there is at least one user defined region.
35 // By construction, only the default region has an invalid start location.
36 if (Regions
.size() == 1 && !Regions
[0]->startLoc().isValid() &&
37 !Regions
[0]->endLoc().isValid()) {
38 ActiveRegions
[Description
] = 0;
39 Regions
[0] = std::make_unique
<CodeRegion
>(Description
, Loc
);
43 auto It
= ActiveRegions
.find(Description
);
44 if (It
!= ActiveRegions
.end()) {
45 const CodeRegion
&R
= *Regions
[It
->second
];
46 if (Description
.empty()) {
47 SM
.PrintMessage(Loc
, SourceMgr::DK_Error
,
48 "found multiple overlapping anonymous regions");
49 SM
.PrintMessage(R
.startLoc(), SourceMgr::DK_Note
,
50 "Previous anonymous region was defined here");
55 SM
.PrintMessage(Loc
, SourceMgr::DK_Error
,
56 "overlapping regions cannot have the same name");
57 SM
.PrintMessage(R
.startLoc(), SourceMgr::DK_Note
,
58 "region " + Description
+ " was previously defined here");
64 ActiveRegions
[Description
] = Regions
.size();
65 Regions
.emplace_back(std::make_unique
<CodeRegion
>(Description
, Loc
));
68 void CodeRegions::endRegion(StringRef Description
, SMLoc Loc
) {
69 if (Description
.empty()) {
70 // Special case where there is only one user defined region,
71 // and this LLVM-MCA-END directive doesn't provide a region name.
72 // In this case, we assume that the user simply wanted to just terminate
73 // the only active region.
74 if (ActiveRegions
.size() == 1) {
75 auto It
= ActiveRegions
.begin();
76 Regions
[It
->second
]->setEndLocation(Loc
);
77 ActiveRegions
.erase(It
);
81 // Special case where the region end marker applies to the default region.
82 if (ActiveRegions
.empty() && Regions
.size() == 1 &&
83 !Regions
[0]->startLoc().isValid() && !Regions
[0]->endLoc().isValid()) {
84 Regions
[0]->setEndLocation(Loc
);
89 auto It
= ActiveRegions
.find(Description
);
90 if (It
!= ActiveRegions
.end()) {
91 Regions
[It
->second
]->setEndLocation(Loc
);
92 ActiveRegions
.erase(It
);
97 SM
.PrintMessage(Loc
, SourceMgr::DK_Error
,
98 "found an invalid region end directive");
99 if (!Description
.empty()) {
100 SM
.PrintMessage(Loc
, SourceMgr::DK_Note
,
101 "unable to find an active region named " + Description
);
103 SM
.PrintMessage(Loc
, SourceMgr::DK_Note
,
104 "unable to find an active anonymous region");
108 void CodeRegions::addInstruction(const MCInst
&Instruction
) {
109 SMLoc Loc
= Instruction
.getLoc();
110 for (UniqueCodeRegion
&Region
: Regions
)
111 if (Region
->isLocInRange(Loc
))
112 Region
->addInstruction(Instruction
);