//===-------------------------- CodeRegion.cpp -----------------*- C++ -* -===//
//
// 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
///
/// This file implements methods from the CodeRegions interface.
///
//===----------------------------------------------------------------------===//

#include "CodeRegion.h"

namespace llvm {
namespace mca {

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())
    return false;
  return true;
}

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;
    }
  }

  ActiveRegions[Description] = Regions.size();
  Regions.emplace_back(make_unique<CodeRegion>(Description, Loc));
  return;
}

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;
  }

  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 MCInst &Instruction) {
  SMLoc Loc = Instruction.getLoc();
  for (UniqueCodeRegion &Region : Regions)
    if (Region->isLocInRange(Loc))
      Region->addInstruction(Instruction);
}

} // namespace mca
} // namespace llvm
