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(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] = 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(make_unique
<CodeRegion
>(Description
, Loc
));
69 void CodeRegions::endRegion(StringRef Description
, SMLoc Loc
) {
70 if (Description
.empty()) {
71 // Special case where there is only one user defined region,
72 // and this LLVM-MCA-END directive doesn't provide a region name.
73 // In this case, we assume that the user simply wanted to just terminate
74 // the only active region.
75 if (ActiveRegions
.size() == 1) {
76 auto It
= ActiveRegions
.begin();
77 Regions
[It
->second
]->setEndLocation(Loc
);
78 ActiveRegions
.erase(It
);
82 // Special case where the region end marker applies to the default region.
83 if (ActiveRegions
.empty() && Regions
.size() == 1 &&
84 !Regions
[0]->startLoc().isValid() && !Regions
[0]->endLoc().isValid()) {
85 Regions
[0]->setEndLocation(Loc
);
90 auto It
= ActiveRegions
.find(Description
);
91 if (It
!= ActiveRegions
.end()) {
92 Regions
[It
->second
]->setEndLocation(Loc
);
93 ActiveRegions
.erase(It
);
98 SM
.PrintMessage(Loc
, SourceMgr::DK_Error
,
99 "found an invalid region end directive");
100 if (!Description
.empty()) {
101 SM
.PrintMessage(Loc
, SourceMgr::DK_Note
,
102 "unable to find an active region named " + Description
);
104 SM
.PrintMessage(Loc
, SourceMgr::DK_Note
,
105 "unable to find an active anonymous region");
109 void CodeRegions::addInstruction(const MCInst
&Instruction
) {
110 SMLoc Loc
= Instruction
.getLoc();
111 for (UniqueCodeRegion
&Region
: Regions
)
112 if (Region
->isLocInRange(Loc
))
113 Region
->addInstruction(Instruction
);