Path: blob/main/contrib/llvm-project/llvm/tools/llvm-mca/CodeRegion.cpp
35258 views
//===-------------------------- CodeRegion.cpp -----------------*- C++ -* -===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7/// \file8///9/// This file implements methods from the CodeRegions interface.10///11//===----------------------------------------------------------------------===//1213#include "CodeRegion.h"1415namespace llvm {16namespace mca {1718bool CodeRegion::isLocInRange(SMLoc Loc) const {19if (RangeEnd.isValid() && Loc.getPointer() > RangeEnd.getPointer())20return false;21if (RangeStart.isValid() && Loc.getPointer() < RangeStart.getPointer())22return false;23return true;24}2526void CodeRegions::addInstruction(const MCInst &Instruction) {27SMLoc Loc = Instruction.getLoc();28for (UniqueCodeRegion &Region : Regions)29if (Region->isLocInRange(Loc))30Region->addInstruction(Instruction);31}3233AnalysisRegions::AnalysisRegions(llvm::SourceMgr &S) : CodeRegions(S) {34// Create a default region for the input code sequence.35Regions.emplace_back(std::make_unique<CodeRegion>("", SMLoc()));36}3738void AnalysisRegions::beginRegion(StringRef Description, SMLoc Loc) {39if (ActiveRegions.empty()) {40// Remove the default region if there is at least one user defined region.41// By construction, only the default region has an invalid start location.42if (Regions.size() == 1 && !Regions[0]->startLoc().isValid() &&43!Regions[0]->endLoc().isValid()) {44ActiveRegions[Description] = 0;45Regions[0] = std::make_unique<CodeRegion>(Description, Loc);46return;47}48} else {49auto It = ActiveRegions.find(Description);50if (It != ActiveRegions.end()) {51const CodeRegion &R = *Regions[It->second];52if (Description.empty()) {53SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,54"found multiple overlapping anonymous regions");55SM.PrintMessage(R.startLoc(), llvm::SourceMgr::DK_Note,56"Previous anonymous region was defined here");57FoundErrors = true;58return;59}6061SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,62"overlapping regions cannot have the same name");63SM.PrintMessage(R.startLoc(), llvm::SourceMgr::DK_Note,64"region " + Description + " was previously defined here");65FoundErrors = true;66return;67}68}6970ActiveRegions[Description] = Regions.size();71Regions.emplace_back(std::make_unique<CodeRegion>(Description, Loc));72}7374void AnalysisRegions::endRegion(StringRef Description, SMLoc Loc) {75if (Description.empty()) {76// Special case where there is only one user defined region,77// and this LLVM-MCA-END directive doesn't provide a region name.78// In this case, we assume that the user simply wanted to just terminate79// the only active region.80if (ActiveRegions.size() == 1) {81auto It = ActiveRegions.begin();82Regions[It->second]->setEndLocation(Loc);83ActiveRegions.erase(It);84return;85}8687// Special case where the region end marker applies to the default region.88if (ActiveRegions.empty() && Regions.size() == 1 &&89!Regions[0]->startLoc().isValid() && !Regions[0]->endLoc().isValid()) {90Regions[0]->setEndLocation(Loc);91return;92}93}9495auto It = ActiveRegions.find(Description);96if (It != ActiveRegions.end()) {97Regions[It->second]->setEndLocation(Loc);98ActiveRegions.erase(It);99return;100}101102FoundErrors = true;103SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,104"found an invalid region end directive");105if (!Description.empty()) {106SM.PrintMessage(Loc, llvm::SourceMgr::DK_Note,107"unable to find an active region named " + Description);108} else {109SM.PrintMessage(Loc, llvm::SourceMgr::DK_Note,110"unable to find an active anonymous region");111}112}113114InstrumentRegions::InstrumentRegions(llvm::SourceMgr &S) : CodeRegions(S) {}115116void InstrumentRegions::beginRegion(StringRef Description, SMLoc Loc,117UniqueInstrument I) {118if (Description.empty()) {119SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,120"anonymous instrumentation regions are not permitted");121FoundErrors = true;122return;123}124125auto It = ActiveRegions.find(Description);126if (It != ActiveRegions.end()) {127const CodeRegion &R = *Regions[It->second];128SM.PrintMessage(129Loc, llvm::SourceMgr::DK_Error,130"overlapping instrumentation regions cannot be of the same kind");131SM.PrintMessage(R.startLoc(), llvm::SourceMgr::DK_Note,132"instrumentation region " + Description +133" was previously defined here");134FoundErrors = true;135return;136}137138ActiveRegions[Description] = Regions.size();139Regions.emplace_back(140std::make_unique<InstrumentRegion>(Description, Loc, std::move(I)));141}142143void InstrumentRegions::endRegion(StringRef Description, SMLoc Loc) {144auto It = ActiveRegions.find(Description);145if (It != ActiveRegions.end()) {146Regions[It->second]->setEndLocation(Loc);147ActiveRegions.erase(It);148return;149}150151FoundErrors = true;152SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,153"found an invalid instrumentation region end directive");154if (!Description.empty()) {155SM.PrintMessage(Loc, llvm::SourceMgr::DK_Note,156"unable to find an active instrumentation region named " +157Description);158}159}160161const SmallVector<Instrument *>162InstrumentRegions::getActiveInstruments(SMLoc Loc) const {163SmallVector<Instrument *> AI;164for (auto &R : Regions) {165if (R->isLocInRange(Loc)) {166InstrumentRegion *IR = static_cast<InstrumentRegion *>(R.get());167AI.push_back(IR->getInstrument());168}169}170return AI;171}172173} // namespace mca174} // namespace llvm175176177