CodeRegion.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. #include "CodeRegion.h"
  14. namespace llvm {
  15. namespace mca {
  16. CodeRegions::CodeRegions(llvm::SourceMgr &S) : SM(S), FoundErrors(false) {
  17. // Create a default region for the input code sequence.
  18. Regions.emplace_back(std::make_unique<CodeRegion>("", SMLoc()));
  19. }
  20. bool CodeRegion::isLocInRange(SMLoc Loc) const {
  21. if (RangeEnd.isValid() && Loc.getPointer() > RangeEnd.getPointer())
  22. return false;
  23. if (RangeStart.isValid() && Loc.getPointer() < RangeStart.getPointer())
  24. return false;
  25. return true;
  26. }
  27. void CodeRegions::beginRegion(StringRef Description, SMLoc Loc) {
  28. if (ActiveRegions.empty()) {
  29. // Remove the default region if there is at least one user defined region.
  30. // By construction, only the default region has an invalid start location.
  31. if (Regions.size() == 1 && !Regions[0]->startLoc().isValid() &&
  32. !Regions[0]->endLoc().isValid()) {
  33. ActiveRegions[Description] = 0;
  34. Regions[0] = std::make_unique<CodeRegion>(Description, Loc);
  35. return;
  36. }
  37. } else {
  38. auto It = ActiveRegions.find(Description);
  39. if (It != ActiveRegions.end()) {
  40. const CodeRegion &R = *Regions[It->second];
  41. if (Description.empty()) {
  42. SM.PrintMessage(Loc, SourceMgr::DK_Error,
  43. "found multiple overlapping anonymous regions");
  44. SM.PrintMessage(R.startLoc(), SourceMgr::DK_Note,
  45. "Previous anonymous region was defined here");
  46. FoundErrors = true;
  47. return;
  48. }
  49. SM.PrintMessage(Loc, SourceMgr::DK_Error,
  50. "overlapping regions cannot have the same name");
  51. SM.PrintMessage(R.startLoc(), SourceMgr::DK_Note,
  52. "region " + Description + " was previously defined here");
  53. FoundErrors = true;
  54. return;
  55. }
  56. }
  57. ActiveRegions[Description] = Regions.size();
  58. Regions.emplace_back(std::make_unique<CodeRegion>(Description, Loc));
  59. }
  60. void CodeRegions::endRegion(StringRef Description, SMLoc Loc) {
  61. if (Description.empty()) {
  62. // Special case where there is only one user defined region,
  63. // and this LLVM-MCA-END directive doesn't provide a region name.
  64. // In this case, we assume that the user simply wanted to just terminate
  65. // the only active region.
  66. if (ActiveRegions.size() == 1) {
  67. auto It = ActiveRegions.begin();
  68. Regions[It->second]->setEndLocation(Loc);
  69. ActiveRegions.erase(It);
  70. return;
  71. }
  72. // Special case where the region end marker applies to the default region.
  73. if (ActiveRegions.empty() && Regions.size() == 1 &&
  74. !Regions[0]->startLoc().isValid() && !Regions[0]->endLoc().isValid()) {
  75. Regions[0]->setEndLocation(Loc);
  76. return;
  77. }
  78. }
  79. auto It = ActiveRegions.find(Description);
  80. if (It != ActiveRegions.end()) {
  81. Regions[It->second]->setEndLocation(Loc);
  82. ActiveRegions.erase(It);
  83. return;
  84. }
  85. FoundErrors = true;
  86. SM.PrintMessage(Loc, SourceMgr::DK_Error,
  87. "found an invalid region end directive");
  88. if (!Description.empty()) {
  89. SM.PrintMessage(Loc, SourceMgr::DK_Note,
  90. "unable to find an active region named " + Description);
  91. } else {
  92. SM.PrintMessage(Loc, SourceMgr::DK_Note,
  93. "unable to find an active anonymous region");
  94. }
  95. }
  96. void CodeRegions::addInstruction(const MCInst &Instruction) {
  97. SMLoc Loc = Instruction.getLoc();
  98. for (UniqueCodeRegion &Region : Regions)
  99. if (Region->isLocInRange(Loc))
  100. Region->addInstruction(Instruction);
  101. }
  102. } // namespace mca
  103. } // namespace llvm