[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / tools / llvm-mca / CodeRegion.cpp
blob7662538e3b68aa327639db63eb15e81ed4769d75
1 //===-------------------------- CodeRegion.cpp -----------------*- 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 methods from the CodeRegions interface.
11 ///
12 //===----------------------------------------------------------------------===//
14 #include "CodeRegion.h"
16 namespace llvm {
17 namespace mca {
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())
26 return false;
27 if (RangeStart.isValid() && Loc.getPointer() < RangeStart.getPointer())
28 return false;
29 return true;
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);
40 return;
42 } else {
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");
51 FoundErrors = true;
52 return;
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");
59 FoundErrors = true;
60 return;
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);
78 return;
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);
85 return;
89 auto It = ActiveRegions.find(Description);
90 if (It != ActiveRegions.end()) {
91 Regions[It->second]->setEndLocation(Loc);
92 ActiveRegions.erase(It);
93 return;
96 FoundErrors = true;
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);
102 } else {
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);
115 } // namespace mca
116 } // namespace llvm