diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
commit | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch) | |
tree | 599ab169a01f1c86eda9adc774edaedde2f2db5b /tools/llvm-mca/CodeRegion.cpp | |
parent | 1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff) |
Diffstat (limited to 'tools/llvm-mca/CodeRegion.cpp')
-rw-r--r-- | tools/llvm-mca/CodeRegion.cpp | 114 |
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 |