brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.9 KiB · 9b8f62f Raw
175 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8/// \file9///10/// This file implements methods from the CodeRegions interface.11///12//===----------------------------------------------------------------------===//13 14#include "CodeRegion.h"15 16namespace llvm {17namespace mca {18 19bool CodeRegion::isLocInRange(SMLoc Loc) const {20  if (RangeEnd.isValid() && Loc.getPointer() > RangeEnd.getPointer())21    return false;22  if (RangeStart.isValid() && Loc.getPointer() < RangeStart.getPointer())23    return false;24  return true;25}26 27void CodeRegions::addInstruction(const MCInst &Instruction) {28  SMLoc Loc = Instruction.getLoc();29  for (UniqueCodeRegion &Region : Regions)30    if (Region->isLocInRange(Loc))31      Region->addInstruction(Instruction);32}33 34AnalysisRegions::AnalysisRegions(llvm::SourceMgr &S) : CodeRegions(S) {35  // Create a default region for the input code sequence.36  Regions.emplace_back(std::make_unique<CodeRegion>("", SMLoc()));37}38 39void AnalysisRegions::beginRegion(StringRef Description, SMLoc Loc) {40  if (ActiveRegions.empty()) {41    // Remove the default region if there is at least one user defined region.42    // By construction, only the default region has an invalid start location.43    if (Regions.size() == 1 && !Regions[0]->startLoc().isValid() &&44        !Regions[0]->endLoc().isValid()) {45      ActiveRegions[Description] = 0;46      Regions[0] = std::make_unique<CodeRegion>(Description, Loc);47      return;48    }49  } else {50    auto It = ActiveRegions.find(Description);51    if (It != ActiveRegions.end()) {52      const CodeRegion &R = *Regions[It->second];53      if (Description.empty()) {54        SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,55                        "found multiple overlapping anonymous regions");56        SM.PrintMessage(R.startLoc(), llvm::SourceMgr::DK_Note,57                        "Previous anonymous region was defined here");58        FoundErrors = true;59        return;60      }61 62      SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,63                      "overlapping regions cannot have the same name");64      SM.PrintMessage(R.startLoc(), llvm::SourceMgr::DK_Note,65                      "region " + Description + " was previously defined here");66      FoundErrors = true;67      return;68    }69  }70 71  ActiveRegions[Description] = Regions.size();72  Regions.emplace_back(std::make_unique<CodeRegion>(Description, Loc));73}74 75void AnalysisRegions::endRegion(StringRef Description, SMLoc Loc) {76  if (Description.empty()) {77    // Special case where there is only one user defined region,78    // and this LLVM-MCA-END directive doesn't provide a region name.79    // In this case, we assume that the user simply wanted to just terminate80    // the only active region.81    if (ActiveRegions.size() == 1) {82      auto It = ActiveRegions.begin();83      Regions[It->second]->setEndLocation(Loc);84      ActiveRegions.erase(It);85      return;86    }87 88    // Special case where the region end marker applies to the default region.89    if (ActiveRegions.empty() && Regions.size() == 1 &&90        !Regions[0]->startLoc().isValid() && !Regions[0]->endLoc().isValid()) {91      Regions[0]->setEndLocation(Loc);92      return;93    }94  }95 96  auto It = ActiveRegions.find(Description);97  if (It != ActiveRegions.end()) {98    Regions[It->second]->setEndLocation(Loc);99    ActiveRegions.erase(It);100    return;101  }102 103  FoundErrors = true;104  SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,105                  "found an invalid region end directive");106  if (!Description.empty()) {107    SM.PrintMessage(Loc, llvm::SourceMgr::DK_Note,108                    "unable to find an active region named " + Description);109  } else {110    SM.PrintMessage(Loc, llvm::SourceMgr::DK_Note,111                    "unable to find an active anonymous region");112  }113}114 115InstrumentRegions::InstrumentRegions(llvm::SourceMgr &S) : CodeRegions(S) {}116 117void InstrumentRegions::beginRegion(StringRef Description, SMLoc Loc,118                                    UniqueInstrument I) {119  if (Description.empty()) {120    SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,121                    "anonymous instrumentation regions are not permitted");122    FoundErrors = true;123    return;124  }125 126  auto [It, Inserted] = ActiveRegions.try_emplace(Description, Regions.size());127  if (!Inserted) {128    const CodeRegion &R = *Regions[It->second];129    SM.PrintMessage(130        Loc, llvm::SourceMgr::DK_Error,131        "overlapping instrumentation regions cannot be of the same kind");132    SM.PrintMessage(R.startLoc(), llvm::SourceMgr::DK_Note,133                    "instrumentation region " + Description +134                        " was previously defined here");135    FoundErrors = true;136    return;137  }138 139  Regions.emplace_back(140      std::make_unique<InstrumentRegion>(Description, Loc, std::move(I)));141}142 143void InstrumentRegions::endRegion(StringRef Description, SMLoc Loc) {144  auto It = ActiveRegions.find(Description);145  if (It != ActiveRegions.end()) {146    Regions[It->second]->setEndLocation(Loc);147    ActiveRegions.erase(It);148    return;149  }150 151  FoundErrors = true;152  SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,153                  "found an invalid instrumentation region end directive");154  if (!Description.empty()) {155    SM.PrintMessage(Loc, llvm::SourceMgr::DK_Note,156                    "unable to find an active instrumentation region named " +157                        Description);158  }159}160 161SmallVector<Instrument *>162InstrumentRegions::getActiveInstruments(SMLoc Loc) const {163  SmallVector<Instrument *> AI;164  for (auto &R : Regions) {165    if (R->isLocInRange(Loc)) {166      InstrumentRegion *IR = static_cast<InstrumentRegion *>(R.get());167      AI.push_back(IR->getInstrument());168    }169  }170  return AI;171}172 173} // namespace mca174} // namespace llvm175