123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- //===-------------------------- 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 {
- CodeRegions::CodeRegions(llvm::SourceMgr &S) : SM(S), FoundErrors(false) {
- // Create a default region for the input code sequence.
- Regions.emplace_back(std::make_unique<CodeRegion>("", SMLoc()));
- }
- 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::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, SourceMgr::DK_Error,
- "found multiple overlapping anonymous regions");
- SM.PrintMessage(R.startLoc(), SourceMgr::DK_Note,
- "Previous anonymous region was defined here");
- FoundErrors = true;
- return;
- }
- SM.PrintMessage(Loc, SourceMgr::DK_Error,
- "overlapping regions cannot have the same name");
- SM.PrintMessage(R.startLoc(), 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 CodeRegions::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, SourceMgr::DK_Error,
- "found an invalid region end directive");
- if (!Description.empty()) {
- SM.PrintMessage(Loc, SourceMgr::DK_Note,
- "unable to find an active region named " + Description);
- } else {
- SM.PrintMessage(Loc, SourceMgr::DK_Note,
- "unable to find an active anonymous region");
- }
- }
- void CodeRegions::addInstruction(const MCInst &Instruction) {
- SMLoc Loc = Instruction.getLoc();
- for (UniqueCodeRegion &Region : Regions)
- if (Region->isLocInRange(Loc))
- Region->addInstruction(Instruction);
- }
- } // namespace mca
- } // namespace llvm
|