xref: /llvm-project/llvm/tools/llvm-mca/CodeRegion.cpp (revision d52a542e4cb65d4fe5a5e7c5a09c1088ba58cff2)
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 ///
10 /// This file implements methods from the CodeRegions interface.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "CodeRegion.h"
15 
16 namespace llvm {
17 namespace mca {
18 
19 CodeRegions::CodeRegions(llvm::SourceMgr &S) : SM(S) {
20   // Create a default region for the input code sequence.
21   Regions.emplace_back(make_unique<CodeRegion>("", SMLoc()));
22 }
23 
24 bool CodeRegion::isLocInRange(SMLoc Loc) const {
25   if (RangeEnd.isValid() && Loc.getPointer() > RangeEnd.getPointer())
26     return false;
27   if (RangeStart.isValid() && Loc.getPointer() < RangeStart.getPointer())
28     return false;
29   return true;
30 }
31 
32 void CodeRegions::beginRegion(StringRef Description, SMLoc Loc) {
33   assert(!Regions.empty() && "Missing Default region");
34   const CodeRegion &CurrentRegion = *Regions.back();
35   if (CurrentRegion.startLoc().isValid() && !CurrentRegion.endLoc().isValid()) {
36     SM.PrintMessage(Loc, SourceMgr::DK_Warning,
37                     "Ignoring invalid region start");
38     return;
39   }
40 
41   // Remove the default region if there are user defined regions.
42   if (!CurrentRegion.startLoc().isValid())
43     Regions.erase(Regions.begin());
44   Regions.emplace_back(make_unique<CodeRegion>(Description, Loc));
45 }
46 
47 void CodeRegions::endRegion(SMLoc Loc) {
48   assert(!Regions.empty() && "Missing Default region");
49   CodeRegion &CurrentRegion = *Regions.back();
50   if (CurrentRegion.endLoc().isValid()) {
51     SM.PrintMessage(Loc, SourceMgr::DK_Warning,
52                     "Ignoring invalid region end");
53     return;
54   }
55 
56   CurrentRegion.setEndLocation(Loc);
57 }
58 
59 void CodeRegions::addInstruction(const MCInst &Instruction) {
60   const SMLoc &Loc = Instruction.getLoc();
61   const auto It =
62       std::find_if(Regions.rbegin(), Regions.rend(),
63                    [Loc](const UniqueCodeRegion &Region) {
64                      return Region->isLocInRange(Loc);
65                    });
66   if (It != Regions.rend())
67     (*It)->addInstruction(Instruction);
68 }
69 
70 } // namespace mca
71 } // namespace llvm
72