aboutsummaryrefslogtreecommitdiff
path: root/tools/llvm-mca/CodeRegion.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
commite6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch)
tree599ab169a01f1c86eda9adc774edaedde2f2db5b /tools/llvm-mca/CodeRegion.cpp
parent1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff)
Diffstat (limited to 'tools/llvm-mca/CodeRegion.cpp')
-rw-r--r--tools/llvm-mca/CodeRegion.cpp114
1 files changed, 82 insertions, 32 deletions
diff --git a/tools/llvm-mca/CodeRegion.cpp b/tools/llvm-mca/CodeRegion.cpp
index 29a27c50c171..bf592f67245e 100644
--- a/tools/llvm-mca/CodeRegion.cpp
+++ b/tools/llvm-mca/CodeRegion.cpp
@@ -1,9 +1,8 @@
//===-------------------------- CodeRegion.cpp -----------------*- C++ -* -===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
@@ -17,7 +16,12 @@
namespace llvm {
namespace mca {
-bool CodeRegion::isLocInRange(llvm::SMLoc Loc) const {
+CodeRegions::CodeRegions(llvm::SourceMgr &S) : SM(S), FoundErrors(false) {
+ // Create a default region for the input code sequence.
+ Regions.emplace_back(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())
@@ -25,42 +29,88 @@ bool CodeRegion::isLocInRange(llvm::SMLoc Loc) const {
return true;
}
-void CodeRegions::beginRegion(llvm::StringRef Description, llvm::SMLoc Loc) {
- assert(!Regions.empty() && "Missing Default region");
- const CodeRegion &CurrentRegion = *Regions.back();
- if (CurrentRegion.startLoc().isValid() && !CurrentRegion.endLoc().isValid()) {
- SM.PrintMessage(Loc, llvm::SourceMgr::DK_Warning,
- "Ignoring invalid region start");
- return;
+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] = 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;
+ }
}
- // Remove the default region if there are user defined regions.
- if (!CurrentRegion.startLoc().isValid())
- Regions.erase(Regions.begin());
- addRegion(Description, Loc);
+ ActiveRegions[Description] = Regions.size();
+ Regions.emplace_back(make_unique<CodeRegion>(Description, Loc));
+ return;
}
-void CodeRegions::endRegion(llvm::SMLoc Loc) {
- assert(!Regions.empty() && "Missing Default region");
- CodeRegion &CurrentRegion = *Regions.back();
- if (CurrentRegion.endLoc().isValid()) {
- SM.PrintMessage(Loc, llvm::SourceMgr::DK_Warning,
- "Ignoring invalid region end");
+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;
}
- CurrentRegion.setEndLocation(Loc);
+ 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 llvm::MCInst &Instruction) {
- const llvm::SMLoc &Loc = Instruction.getLoc();
- const auto It =
- std::find_if(Regions.rbegin(), Regions.rend(),
- [Loc](const std::unique_ptr<CodeRegion> &Region) {
- return Region->isLocInRange(Loc);
- });
- if (It != Regions.rend())
- (*It)->addInstruction(Instruction);
+void CodeRegions::addInstruction(const MCInst &Instruction) {
+ SMLoc Loc = Instruction.getLoc();
+ for (UniqueCodeRegion &Region : Regions)
+ if (Region->isLocInRange(Loc))
+ Region->addInstruction(Instruction);
}
} // namespace mca