1c6590128SAndrea Di Biagio //===-------------------------- CodeRegion.cpp -----------------*- C++ -* -===//
2c6590128SAndrea Di Biagio //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c6590128SAndrea Di Biagio //
7c6590128SAndrea Di Biagio //===----------------------------------------------------------------------===//
8c6590128SAndrea Di Biagio /// \file
9c6590128SAndrea Di Biagio ///
10c6590128SAndrea Di Biagio /// This file implements methods from the CodeRegions interface.
11c6590128SAndrea Di Biagio ///
12c6590128SAndrea Di Biagio //===----------------------------------------------------------------------===//
13c6590128SAndrea Di Biagio
14c6590128SAndrea Di Biagio #include "CodeRegion.h"
15c6590128SAndrea Di Biagio
165a8fd657SFangrui Song namespace llvm {
17c6590128SAndrea Di Biagio namespace mca {
18c6590128SAndrea Di Biagio
isLocInRange(SMLoc Loc) const1986654dd8SAndrea Di Biagio bool CodeRegion::isLocInRange(SMLoc Loc) const {
20c6590128SAndrea Di Biagio if (RangeEnd.isValid() && Loc.getPointer() > RangeEnd.getPointer())
21c6590128SAndrea Di Biagio return false;
22c6590128SAndrea Di Biagio if (RangeStart.isValid() && Loc.getPointer() < RangeStart.getPointer())
23c6590128SAndrea Di Biagio return false;
24c6590128SAndrea Di Biagio return true;
25c6590128SAndrea Di Biagio }
26c6590128SAndrea Di Biagio
addInstruction(const MCInst & Instruction)2798e342dcSMichael Maitland void CodeRegions::addInstruction(const MCInst &Instruction) {
2898e342dcSMichael Maitland SMLoc Loc = Instruction.getLoc();
2998e342dcSMichael Maitland for (UniqueCodeRegion &Region : Regions)
3098e342dcSMichael Maitland if (Region->isLocInRange(Loc))
3198e342dcSMichael Maitland Region->addInstruction(Instruction);
3298e342dcSMichael Maitland }
3398e342dcSMichael Maitland
AnalysisRegions(llvm::SourceMgr & S)3498e342dcSMichael Maitland AnalysisRegions::AnalysisRegions(llvm::SourceMgr &S) : CodeRegions(S) {
3598e342dcSMichael Maitland // Create a default region for the input code sequence.
3698e342dcSMichael Maitland Regions.emplace_back(std::make_unique<CodeRegion>("", SMLoc()));
3798e342dcSMichael Maitland }
3898e342dcSMichael Maitland
beginRegion(StringRef Description,SMLoc Loc)3998e342dcSMichael Maitland void AnalysisRegions::beginRegion(StringRef Description, SMLoc Loc) {
404e62554bSAndrea Di Biagio if (ActiveRegions.empty()) {
414e62554bSAndrea Di Biagio // Remove the default region if there is at least one user defined region.
424e62554bSAndrea Di Biagio // By construction, only the default region has an invalid start location.
434e62554bSAndrea Di Biagio if (Regions.size() == 1 && !Regions[0]->startLoc().isValid() &&
444e62554bSAndrea Di Biagio !Regions[0]->endLoc().isValid()) {
454e62554bSAndrea Di Biagio ActiveRegions[Description] = 0;
460eaee545SJonas Devlieghere Regions[0] = std::make_unique<CodeRegion>(Description, Loc);
474e62554bSAndrea Di Biagio return;
484e62554bSAndrea Di Biagio }
494e62554bSAndrea Di Biagio } else {
504e62554bSAndrea Di Biagio auto It = ActiveRegions.find(Description);
514e62554bSAndrea Di Biagio if (It != ActiveRegions.end()) {
524e62554bSAndrea Di Biagio const CodeRegion &R = *Regions[It->second];
534e62554bSAndrea Di Biagio if (Description.empty()) {
5498e342dcSMichael Maitland SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,
554e62554bSAndrea Di Biagio "found multiple overlapping anonymous regions");
5698e342dcSMichael Maitland SM.PrintMessage(R.startLoc(), llvm::SourceMgr::DK_Note,
574e62554bSAndrea Di Biagio "Previous anonymous region was defined here");
584e62554bSAndrea Di Biagio FoundErrors = true;
59c6590128SAndrea Di Biagio return;
60c6590128SAndrea Di Biagio }
61c6590128SAndrea Di Biagio
6298e342dcSMichael Maitland SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,
634e62554bSAndrea Di Biagio "overlapping regions cannot have the same name");
6498e342dcSMichael Maitland SM.PrintMessage(R.startLoc(), llvm::SourceMgr::DK_Note,
654e62554bSAndrea Di Biagio "region " + Description + " was previously defined here");
664e62554bSAndrea Di Biagio FoundErrors = true;
674e62554bSAndrea Di Biagio return;
684e62554bSAndrea Di Biagio }
694e62554bSAndrea Di Biagio }
704e62554bSAndrea Di Biagio
714e62554bSAndrea Di Biagio ActiveRegions[Description] = Regions.size();
720eaee545SJonas Devlieghere Regions.emplace_back(std::make_unique<CodeRegion>(Description, Loc));
73c6590128SAndrea Di Biagio }
74c6590128SAndrea Di Biagio
endRegion(StringRef Description,SMLoc Loc)7598e342dcSMichael Maitland void AnalysisRegions::endRegion(StringRef Description, SMLoc Loc) {
764e62554bSAndrea Di Biagio if (Description.empty()) {
774e62554bSAndrea Di Biagio // Special case where there is only one user defined region,
784e62554bSAndrea Di Biagio // and this LLVM-MCA-END directive doesn't provide a region name.
794e62554bSAndrea Di Biagio // In this case, we assume that the user simply wanted to just terminate
804e62554bSAndrea Di Biagio // the only active region.
814e62554bSAndrea Di Biagio if (ActiveRegions.size() == 1) {
824e62554bSAndrea Di Biagio auto It = ActiveRegions.begin();
834e62554bSAndrea Di Biagio Regions[It->second]->setEndLocation(Loc);
844e62554bSAndrea Di Biagio ActiveRegions.erase(It);
854e62554bSAndrea Di Biagio return;
864e62554bSAndrea Di Biagio }
874e62554bSAndrea Di Biagio
884e62554bSAndrea Di Biagio // Special case where the region end marker applies to the default region.
894e62554bSAndrea Di Biagio if (ActiveRegions.empty() && Regions.size() == 1 &&
904e62554bSAndrea Di Biagio !Regions[0]->startLoc().isValid() && !Regions[0]->endLoc().isValid()) {
914e62554bSAndrea Di Biagio Regions[0]->setEndLocation(Loc);
924e62554bSAndrea Di Biagio return;
934e62554bSAndrea Di Biagio }
944e62554bSAndrea Di Biagio }
954e62554bSAndrea Di Biagio
964e62554bSAndrea Di Biagio auto It = ActiveRegions.find(Description);
974e62554bSAndrea Di Biagio if (It != ActiveRegions.end()) {
984e62554bSAndrea Di Biagio Regions[It->second]->setEndLocation(Loc);
994e62554bSAndrea Di Biagio ActiveRegions.erase(It);
1004e62554bSAndrea Di Biagio return;
1014e62554bSAndrea Di Biagio }
1024e62554bSAndrea Di Biagio
1034e62554bSAndrea Di Biagio FoundErrors = true;
10498e342dcSMichael Maitland SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,
1054e62554bSAndrea Di Biagio "found an invalid region end directive");
1064e62554bSAndrea Di Biagio if (!Description.empty()) {
10798e342dcSMichael Maitland SM.PrintMessage(Loc, llvm::SourceMgr::DK_Note,
1084e62554bSAndrea Di Biagio "unable to find an active region named " + Description);
1094e62554bSAndrea Di Biagio } else {
11098e342dcSMichael Maitland SM.PrintMessage(Loc, llvm::SourceMgr::DK_Note,
1114e62554bSAndrea Di Biagio "unable to find an active anonymous region");
1124e62554bSAndrea Di Biagio }
113c6590128SAndrea Di Biagio }
114c6590128SAndrea Di Biagio
InstrumentRegions(llvm::SourceMgr & S)11598e342dcSMichael Maitland InstrumentRegions::InstrumentRegions(llvm::SourceMgr &S) : CodeRegions(S) {}
11698e342dcSMichael Maitland
beginRegion(StringRef Description,SMLoc Loc,UniqueInstrument I)11798e342dcSMichael Maitland void InstrumentRegions::beginRegion(StringRef Description, SMLoc Loc,
118*56674e8eSMichael Maitland UniqueInstrument I) {
11998e342dcSMichael Maitland if (Description.empty()) {
12098e342dcSMichael Maitland SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,
12198e342dcSMichael Maitland "anonymous instrumentation regions are not permitted");
12298e342dcSMichael Maitland FoundErrors = true;
12398e342dcSMichael Maitland return;
12498e342dcSMichael Maitland }
12598e342dcSMichael Maitland
12698e342dcSMichael Maitland auto It = ActiveRegions.find(Description);
12798e342dcSMichael Maitland if (It != ActiveRegions.end()) {
12898e342dcSMichael Maitland const CodeRegion &R = *Regions[It->second];
12998e342dcSMichael Maitland SM.PrintMessage(
13098e342dcSMichael Maitland Loc, llvm::SourceMgr::DK_Error,
13198e342dcSMichael Maitland "overlapping instrumentation regions cannot be of the same kind");
13298e342dcSMichael Maitland SM.PrintMessage(R.startLoc(), llvm::SourceMgr::DK_Note,
13398e342dcSMichael Maitland "instrumentation region " + Description +
13498e342dcSMichael Maitland " was previously defined here");
13598e342dcSMichael Maitland FoundErrors = true;
13698e342dcSMichael Maitland return;
13798e342dcSMichael Maitland }
13898e342dcSMichael Maitland
13998e342dcSMichael Maitland ActiveRegions[Description] = Regions.size();
140*56674e8eSMichael Maitland Regions.emplace_back(
141*56674e8eSMichael Maitland std::make_unique<InstrumentRegion>(Description, Loc, std::move(I)));
14298e342dcSMichael Maitland }
14398e342dcSMichael Maitland
endRegion(StringRef Description,SMLoc Loc)14498e342dcSMichael Maitland void InstrumentRegions::endRegion(StringRef Description, SMLoc Loc) {
14598e342dcSMichael Maitland auto It = ActiveRegions.find(Description);
14698e342dcSMichael Maitland if (It != ActiveRegions.end()) {
14798e342dcSMichael Maitland Regions[It->second]->setEndLocation(Loc);
14898e342dcSMichael Maitland ActiveRegions.erase(It);
14998e342dcSMichael Maitland return;
15098e342dcSMichael Maitland }
15198e342dcSMichael Maitland
15298e342dcSMichael Maitland FoundErrors = true;
15398e342dcSMichael Maitland SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,
15498e342dcSMichael Maitland "found an invalid instrumentation region end directive");
15598e342dcSMichael Maitland if (!Description.empty()) {
15698e342dcSMichael Maitland SM.PrintMessage(Loc, llvm::SourceMgr::DK_Note,
15798e342dcSMichael Maitland "unable to find an active instrumentation region named " +
15898e342dcSMichael Maitland Description);
15998e342dcSMichael Maitland }
16098e342dcSMichael Maitland }
16198e342dcSMichael Maitland
162*56674e8eSMichael Maitland const SmallVector<Instrument *>
getActiveInstruments(SMLoc Loc) const16398e342dcSMichael Maitland InstrumentRegions::getActiveInstruments(SMLoc Loc) const {
164*56674e8eSMichael Maitland SmallVector<Instrument *> AI;
16598e342dcSMichael Maitland for (auto &R : Regions) {
16698e342dcSMichael Maitland if (R->isLocInRange(Loc)) {
16798e342dcSMichael Maitland InstrumentRegion *IR = static_cast<InstrumentRegion *>(R.get());
168*56674e8eSMichael Maitland AI.push_back(IR->getInstrument());
16998e342dcSMichael Maitland }
17098e342dcSMichael Maitland }
17198e342dcSMichael Maitland return AI;
172c6590128SAndrea Di Biagio }
173c6590128SAndrea Di Biagio
174c6590128SAndrea Di Biagio } // namespace mca
1755a8fd657SFangrui Song } // namespace llvm
176