//===--- TargetID.cpp - Utilities for parsing target ID -------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/TargetID.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/TargetParser.h"
#include "llvm/TargetParser/Triple.h"
#include <map>
#include <optional>

namespace clang {

static llvm::SmallVector<llvm::StringRef, 4>
getAllPossibleAMDGPUTargetIDFeatures(const llvm::Triple &T,
                                     llvm::StringRef Proc) {
  // Entries in returned vector should be in alphabetical order.
  llvm::SmallVector<llvm::StringRef, 4> Ret;
  auto ProcKind = T.isAMDGCN() ? llvm::AMDGPU::parseArchAMDGCN(Proc)
                               : llvm::AMDGPU::parseArchR600(Proc);
  if (ProcKind == llvm::AMDGPU::GK_NONE)
    return Ret;
  auto Features = T.isAMDGCN() ? llvm::AMDGPU::getArchAttrAMDGCN(ProcKind)
                               : llvm::AMDGPU::getArchAttrR600(ProcKind);
  if (Features & llvm::AMDGPU::FEATURE_SRAMECC)
    Ret.push_back("sramecc");
  if (Features & llvm::AMDGPU::FEATURE_XNACK)
    Ret.push_back("xnack");
  return Ret;
}

llvm::SmallVector<llvm::StringRef, 4>
getAllPossibleTargetIDFeatures(const llvm::Triple &T,
                               llvm::StringRef Processor) {
  llvm::SmallVector<llvm::StringRef, 4> Ret;
  if (T.isAMDGPU())
    return getAllPossibleAMDGPUTargetIDFeatures(T, Processor);
  return Ret;
}

/// Returns canonical processor name or empty string if \p Processor is invalid.
static llvm::StringRef getCanonicalProcessorName(const llvm::Triple &T,
                                                 llvm::StringRef Processor) {
  if (T.isAMDGPU())
    return llvm::AMDGPU::getCanonicalArchName(T, Processor);
  return Processor;
}

llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T,
                                         llvm::StringRef TargetID) {
  auto Split = TargetID.split(':');
  return getCanonicalProcessorName(T, Split.first);
}

// Parse a target ID with format checking only. Do not check whether processor
// name or features are valid for the processor.
//
// A target ID is a processor name followed by a list of target features
// delimited by colon. Each target feature is a string post-fixed by a plus
// or minus sign, e.g. gfx908:sramecc+:xnack-.
static std::optional<llvm::StringRef>
parseTargetIDWithFormatCheckingOnly(llvm::StringRef TargetID,
                                    llvm::StringMap<bool> *FeatureMap) {
  llvm::StringRef Processor;

  if (TargetID.empty())
    return llvm::StringRef();

  auto Split = TargetID.split(':');
  Processor = Split.first;
  if (Processor.empty())
    return std::nullopt;

  auto Features = Split.second;
  if (Features.empty())
    return Processor;

  llvm::StringMap<bool> LocalFeatureMap;
  if (!FeatureMap)
    FeatureMap = &LocalFeatureMap;

  while (!Features.empty()) {
    auto Splits = Features.split(':');
    auto Sign = Splits.first.back();
    auto Feature = Splits.first.drop_back();
    if (Sign != '+' && Sign != '-')
      return std::nullopt;
    bool IsOn = Sign == '+';
    // Each feature can only show up at most once in target ID.
    if (!FeatureMap->try_emplace(Feature, IsOn).second)
      return std::nullopt;
    Features = Splits.second;
  }
  return Processor;
}

std::optional<llvm::StringRef>
parseTargetID(const llvm::Triple &T, llvm::StringRef TargetID,
              llvm::StringMap<bool> *FeatureMap) {
  auto OptionalProcessor =
      parseTargetIDWithFormatCheckingOnly(TargetID, FeatureMap);

  if (!OptionalProcessor)
    return std::nullopt;

  llvm::StringRef Processor = getCanonicalProcessorName(T, *OptionalProcessor);
  if (Processor.empty())
    return std::nullopt;

  llvm::SmallSet<llvm::StringRef, 4> AllFeatures(
      llvm::from_range, getAllPossibleTargetIDFeatures(T, Processor));

  for (auto &&F : *FeatureMap)
    if (!AllFeatures.count(F.first()))
      return std::nullopt;

  return Processor;
}

// A canonical target ID is a target ID containing a canonical processor name
// and features in alphabetical order.
std::string getCanonicalTargetID(llvm::StringRef Processor,
                                 const llvm::StringMap<bool> &Features) {
  std::string TargetID = Processor.str();
  std::map<const llvm::StringRef, bool> OrderedMap;
  for (const auto &F : Features)
    OrderedMap[F.first()] = F.second;
  for (const auto &F : OrderedMap)
    TargetID = TargetID + ':' + F.first.str() + (F.second ? "+" : "-");
  return TargetID;
}

// For a specific processor, a feature either shows up in all target IDs, or
// does not show up in any target IDs. Otherwise the target ID combination
// is invalid.
std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
getConflictTargetIDCombination(const std::set<llvm::StringRef> &TargetIDs) {
  struct Info {
    llvm::StringRef TargetID;
    llvm::StringMap<bool> Features;
    Info(llvm::StringRef TargetID, const llvm::StringMap<bool> &Features)
        : TargetID(TargetID), Features(Features) {}
  };
  llvm::StringMap<Info> FeatureMap;
  for (auto &&ID : TargetIDs) {
    llvm::StringMap<bool> Features;
    llvm::StringRef Proc = *parseTargetIDWithFormatCheckingOnly(ID, &Features);
    auto [Loc, Inserted] = FeatureMap.try_emplace(Proc, ID, Features);
    if (!Inserted) {
      auto &ExistingFeatures = Loc->second.Features;
      if (llvm::any_of(Features, [&](auto &F) {
            return ExistingFeatures.count(F.first()) == 0;
          }))
        return std::make_pair(Loc->second.TargetID, ID);
    }
  }
  return std::nullopt;
}

bool isCompatibleTargetID(llvm::StringRef Provided, llvm::StringRef Requested) {
  llvm::StringMap<bool> ProvidedFeatures, RequestedFeatures;
  llvm::StringRef ProvidedProc =
      *parseTargetIDWithFormatCheckingOnly(Provided, &ProvidedFeatures);
  llvm::StringRef RequestedProc =
      *parseTargetIDWithFormatCheckingOnly(Requested, &RequestedFeatures);
  if (ProvidedProc != RequestedProc)
    return false;
  for (const auto &F : ProvidedFeatures) {
    auto Loc = RequestedFeatures.find(F.first());
    // The default (unspecified) value of a feature is 'All', which can match
    // either 'On' or 'Off'.
    if (Loc == RequestedFeatures.end())
      return false;
    // If a feature is specified, it must have exact match.
    if (Loc->second != F.second)
      return false;
  }
  return true;
}

} // namespace clang
