//===--- 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/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
