123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- //===-------------------------- CodeRegion.cpp -----------------*- C++ -* -===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- /// \file
- ///
- /// This file implements methods from the CodeRegions interface.
- ///
- //===----------------------------------------------------------------------===//
- #include "CodeRegion.h"
- namespace llvm {
- namespace mca {
- bool CodeRegion::isLocInRange(SMLoc Loc) const {
- if (RangeEnd.isValid() && Loc.getPointer() > RangeEnd.getPointer())
- return false;
- if (RangeStart.isValid() && Loc.getPointer() < RangeStart.getPointer())
- return false;
- return true;
- }
- void CodeRegions::addInstruction(const MCInst &Instruction) {
- SMLoc Loc = Instruction.getLoc();
- for (UniqueCodeRegion &Region : Regions)
- if (Region->isLocInRange(Loc))
- Region->addInstruction(Instruction);
- }
- AnalysisRegions::AnalysisRegions(llvm::SourceMgr &S) : CodeRegions(S) {
- // Create a default region for the input code sequence.
- Regions.emplace_back(std::make_unique<CodeRegion>("", SMLoc()));
- }
- void AnalysisRegions::beginRegion(StringRef Description, SMLoc Loc) {
- if (ActiveRegions.empty()) {
- // Remove the default region if there is at least one user defined region.
- // By construction, only the default region has an invalid start location.
- if (Regions.size() == 1 && !Regions[0]->startLoc().isValid() &&
- !Regions[0]->endLoc().isValid()) {
- ActiveRegions[Description] = 0;
- Regions[0] = std::make_unique<CodeRegion>(Description, Loc);
- return;
- }
- } else {
- auto It = ActiveRegions.find(Description);
- if (It != ActiveRegions.end()) {
- const CodeRegion &R = *Regions[It->second];
- if (Description.empty()) {
- SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,
- "found multiple overlapping anonymous regions");
- SM.PrintMessage(R.startLoc(), llvm::SourceMgr::DK_Note,
- "Previous anonymous region was defined here");
- FoundErrors = true;
- return;
- }
- SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,
- "overlapping regions cannot have the same name");
- SM.PrintMessage(R.startLoc(), llvm::SourceMgr::DK_Note,
- "region " + Description + " was previously defined here");
- FoundErrors = true;
- return;
- }
- }
- ActiveRegions[Description] = Regions.size();
- Regions.emplace_back(std::make_unique<CodeRegion>(Description, Loc));
- }
- void AnalysisRegions::endRegion(StringRef Description, SMLoc Loc) {
- if (Description.empty()) {
- // Special case where there is only one user defined region,
- // and this LLVM-MCA-END directive doesn't provide a region name.
- // In this case, we assume that the user simply wanted to just terminate
- // the only active region.
- if (ActiveRegions.size() == 1) {
- auto It = ActiveRegions.begin();
- Regions[It->second]->setEndLocation(Loc);
- ActiveRegions.erase(It);
- return;
- }
- // Special case where the region end marker applies to the default region.
- if (ActiveRegions.empty() && Regions.size() == 1 &&
- !Regions[0]->startLoc().isValid() && !Regions[0]->endLoc().isValid()) {
- Regions[0]->setEndLocation(Loc);
- return;
- }
- }
- auto It = ActiveRegions.find(Description);
- if (It != ActiveRegions.end()) {
- Regions[It->second]->setEndLocation(Loc);
- ActiveRegions.erase(It);
- return;
- }
- FoundErrors = true;
- SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,
- "found an invalid region end directive");
- if (!Description.empty()) {
- SM.PrintMessage(Loc, llvm::SourceMgr::DK_Note,
- "unable to find an active region named " + Description);
- } else {
- SM.PrintMessage(Loc, llvm::SourceMgr::DK_Note,
- "unable to find an active anonymous region");
- }
- }
- InstrumentRegions::InstrumentRegions(llvm::SourceMgr &S) : CodeRegions(S) {}
- void InstrumentRegions::beginRegion(StringRef Description, SMLoc Loc,
- SharedInstrument I) {
- if (Description.empty()) {
- SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,
- "anonymous instrumentation regions are not permitted");
- FoundErrors = true;
- return;
- }
- auto It = ActiveRegions.find(Description);
- if (It != ActiveRegions.end()) {
- const CodeRegion &R = *Regions[It->second];
- SM.PrintMessage(
- Loc, llvm::SourceMgr::DK_Error,
- "overlapping instrumentation regions cannot be of the same kind");
- SM.PrintMessage(R.startLoc(), llvm::SourceMgr::DK_Note,
- "instrumentation region " + Description +
- " was previously defined here");
- FoundErrors = true;
- return;
- }
- ActiveRegions[Description] = Regions.size();
- Regions.emplace_back(std::make_unique<InstrumentRegion>(Description, Loc, I));
- }
- void InstrumentRegions::endRegion(StringRef Description, SMLoc Loc) {
- auto It = ActiveRegions.find(Description);
- if (It != ActiveRegions.end()) {
- Regions[It->second]->setEndLocation(Loc);
- ActiveRegions.erase(It);
- return;
- }
- FoundErrors = true;
- SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,
- "found an invalid instrumentation region end directive");
- if (!Description.empty()) {
- SM.PrintMessage(Loc, llvm::SourceMgr::DK_Note,
- "unable to find an active instrumentation region named " +
- Description);
- }
- }
- const SmallVector<SharedInstrument>
- InstrumentRegions::getActiveInstruments(SMLoc Loc) const {
- SmallVector<SharedInstrument> AI;
- for (auto &R : Regions) {
- if (R->isLocInRange(Loc)) {
- InstrumentRegion *IR = static_cast<InstrumentRegion *>(R.get());
- AI.emplace_back(IR->getInstrument());
- }
- }
- return AI;
- }
- } // namespace mca
- } // namespace llvm
|