1336809Sdim//===-------------------------- CodeRegion.cpp -----------------*- C++ -* -===// 2336809Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6336809Sdim// 7336809Sdim//===----------------------------------------------------------------------===// 8336809Sdim/// \file 9336809Sdim/// 10336809Sdim/// This file implements methods from the CodeRegions interface. 11336809Sdim/// 12336809Sdim//===----------------------------------------------------------------------===// 13336809Sdim 14336809Sdim#include "CodeRegion.h" 15336809Sdim 16344779Sdimnamespace llvm { 17336809Sdimnamespace mca { 18336809Sdim 19353358SdimCodeRegions::CodeRegions(llvm::SourceMgr &S) : SM(S), FoundErrors(false) { 20353358Sdim // Create a default region for the input code sequence. 21360784Sdim Regions.emplace_back(std::make_unique<CodeRegion>("", SMLoc())); 22353358Sdim} 23353358Sdim 24353358Sdimbool CodeRegion::isLocInRange(SMLoc Loc) const { 25336809Sdim if (RangeEnd.isValid() && Loc.getPointer() > RangeEnd.getPointer()) 26336809Sdim return false; 27336809Sdim if (RangeStart.isValid() && Loc.getPointer() < RangeStart.getPointer()) 28336809Sdim return false; 29336809Sdim return true; 30336809Sdim} 31336809Sdim 32353358Sdimvoid CodeRegions::beginRegion(StringRef Description, SMLoc Loc) { 33353358Sdim if (ActiveRegions.empty()) { 34353358Sdim // Remove the default region if there is at least one user defined region. 35353358Sdim // By construction, only the default region has an invalid start location. 36353358Sdim if (Regions.size() == 1 && !Regions[0]->startLoc().isValid() && 37353358Sdim !Regions[0]->endLoc().isValid()) { 38353358Sdim ActiveRegions[Description] = 0; 39360784Sdim Regions[0] = std::make_unique<CodeRegion>(Description, Loc); 40353358Sdim return; 41353358Sdim } 42353358Sdim } else { 43353358Sdim auto It = ActiveRegions.find(Description); 44353358Sdim if (It != ActiveRegions.end()) { 45353358Sdim const CodeRegion &R = *Regions[It->second]; 46353358Sdim if (Description.empty()) { 47353358Sdim SM.PrintMessage(Loc, SourceMgr::DK_Error, 48353358Sdim "found multiple overlapping anonymous regions"); 49353358Sdim SM.PrintMessage(R.startLoc(), SourceMgr::DK_Note, 50353358Sdim "Previous anonymous region was defined here"); 51353358Sdim FoundErrors = true; 52353358Sdim return; 53353358Sdim } 54353358Sdim 55353358Sdim SM.PrintMessage(Loc, SourceMgr::DK_Error, 56353358Sdim "overlapping regions cannot have the same name"); 57353358Sdim SM.PrintMessage(R.startLoc(), SourceMgr::DK_Note, 58353358Sdim "region " + Description + " was previously defined here"); 59353358Sdim FoundErrors = true; 60353358Sdim return; 61353358Sdim } 62336809Sdim } 63336809Sdim 64353358Sdim ActiveRegions[Description] = Regions.size(); 65360784Sdim Regions.emplace_back(std::make_unique<CodeRegion>(Description, Loc)); 66353358Sdim return; 67336809Sdim} 68336809Sdim 69353358Sdimvoid CodeRegions::endRegion(StringRef Description, SMLoc Loc) { 70353358Sdim if (Description.empty()) { 71353358Sdim // Special case where there is only one user defined region, 72353358Sdim // and this LLVM-MCA-END directive doesn't provide a region name. 73353358Sdim // In this case, we assume that the user simply wanted to just terminate 74353358Sdim // the only active region. 75353358Sdim if (ActiveRegions.size() == 1) { 76353358Sdim auto It = ActiveRegions.begin(); 77353358Sdim Regions[It->second]->setEndLocation(Loc); 78353358Sdim ActiveRegions.erase(It); 79353358Sdim return; 80353358Sdim } 81353358Sdim 82353358Sdim // Special case where the region end marker applies to the default region. 83353358Sdim if (ActiveRegions.empty() && Regions.size() == 1 && 84353358Sdim !Regions[0]->startLoc().isValid() && !Regions[0]->endLoc().isValid()) { 85353358Sdim Regions[0]->setEndLocation(Loc); 86353358Sdim return; 87353358Sdim } 88353358Sdim } 89353358Sdim 90353358Sdim auto It = ActiveRegions.find(Description); 91353358Sdim if (It != ActiveRegions.end()) { 92353358Sdim Regions[It->second]->setEndLocation(Loc); 93353358Sdim ActiveRegions.erase(It); 94336809Sdim return; 95336809Sdim } 96336809Sdim 97353358Sdim FoundErrors = true; 98353358Sdim SM.PrintMessage(Loc, SourceMgr::DK_Error, 99353358Sdim "found an invalid region end directive"); 100353358Sdim if (!Description.empty()) { 101353358Sdim SM.PrintMessage(Loc, SourceMgr::DK_Note, 102353358Sdim "unable to find an active region named " + Description); 103353358Sdim } else { 104353358Sdim SM.PrintMessage(Loc, SourceMgr::DK_Note, 105353358Sdim "unable to find an active anonymous region"); 106353358Sdim } 107336809Sdim} 108336809Sdim 109353358Sdimvoid CodeRegions::addInstruction(const MCInst &Instruction) { 110353358Sdim SMLoc Loc = Instruction.getLoc(); 111353358Sdim for (UniqueCodeRegion &Region : Regions) 112353358Sdim if (Region->isLocInRange(Loc)) 113353358Sdim Region->addInstruction(Instruction); 114336809Sdim} 115336809Sdim 116336809Sdim} // namespace mca 117344779Sdim} // namespace llvm 118