brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.6 KiB · d6b6079 Raw
266 lines · cpp
1//===-- SPIRVBaseInfo.cpp - Top level SPIRV definitions ---------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the implementation for helper mnemonic lookup functions,10// versioning/capabilities/extensions getters for symbolic/named operands used11// in various SPIR-V instructions.12//13//===----------------------------------------------------------------------===//14 15#include "SPIRVBaseInfo.h"16#include "llvm/ADT/ArrayRef.h"17#include "llvm/ADT/StringRef.h"18 19namespace llvm {20namespace SPIRV {21struct SymbolicOperand {22  OperandCategory::OperandCategory Category;23  uint32_t Value;24  StringRef Mnemonic;25  uint32_t MinVersion;26  uint32_t MaxVersion;27};28 29struct ExtensionEntry {30  OperandCategory::OperandCategory Category;31  uint32_t Value;32  Extension::Extension ReqExtension;33};34 35struct CapabilityEntry {36  OperandCategory::OperandCategory Category;37  uint32_t Value;38  Capability::Capability ReqCapability;39};40 41struct EnvironmentEntry {42  OperandCategory::OperandCategory Category;43  uint32_t Value;44  Environment::Environment AllowedEnvironment;45};46 47using namespace OperandCategory;48using namespace Extension;49using namespace Environment;50using namespace Capability;51using namespace InstructionSet;52#define GET_SymbolicOperands_DECL53#define GET_SymbolicOperands_IMPL54#define GET_ExtensionEntries_DECL55#define GET_ExtensionEntries_IMPL56#define GET_CapabilityEntries_DECL57#define GET_CapabilityEntries_IMPL58#define GET_EnvironmentEntries_DECL59#define GET_EnvironmentEntries_IMPL60#define GET_ExtendedBuiltins_DECL61#define GET_ExtendedBuiltins_IMPL62#include "SPIRVGenTables.inc"63} // namespace SPIRV64 65std::string66getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category,67                           int32_t Value) {68  const SPIRV::SymbolicOperand *Lookup =69      SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);70  // Value that encodes just one enum value.71  if (Lookup)72    return Lookup->Mnemonic.str();73  if (Category != SPIRV::OperandCategory::ImageOperandOperand &&74      Category != SPIRV::OperandCategory::FPFastMathModeOperand &&75      Category != SPIRV::OperandCategory::SelectionControlOperand &&76      Category != SPIRV::OperandCategory::LoopControlOperand &&77      Category != SPIRV::OperandCategory::FunctionControlOperand &&78      Category != SPIRV::OperandCategory::MemorySemanticsOperand &&79      Category != SPIRV::OperandCategory::MemoryOperandOperand &&80      Category != SPIRV::OperandCategory::KernelProfilingInfoOperand &&81      Category != SPIRV::OperandCategory::SpecConstantOpOperandsOperand)82    return "UNKNOWN";83  // Value that encodes many enum values (one bit per enum value).84  std::string Name;85  std::string Separator;86  const SPIRV::SymbolicOperand *EnumValueInCategory =87      SPIRV::lookupSymbolicOperandByCategory(Category);88 89  auto TableEnd = ArrayRef(SPIRV::SymbolicOperands).end();90  while (EnumValueInCategory && EnumValueInCategory->Category == Category) {91    if ((EnumValueInCategory->Value != 0) &&92        (Value & EnumValueInCategory->Value)) {93      Name += Separator + EnumValueInCategory->Mnemonic.str();94      Separator = "|";95    }96    if (++EnumValueInCategory == TableEnd)97      break;98  }99 100  return Name;101}102 103VersionTuple104getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category,105                             uint32_t Value) {106  const SPIRV::SymbolicOperand *Lookup =107      SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);108 109  if (Lookup)110    return VersionTuple(Lookup->MinVersion / 10, Lookup->MinVersion % 10);111 112  return VersionTuple(0);113}114 115VersionTuple116getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category,117                             uint32_t Value) {118  const SPIRV::SymbolicOperand *Lookup =119      SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);120 121  if (Lookup)122    return VersionTuple(Lookup->MaxVersion / 10, Lookup->MaxVersion % 10);123 124  return VersionTuple();125}126 127CapabilityList128getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category,129                               uint32_t Value) {130  CapabilityList Capabilities;131  const SPIRV::CapabilityEntry *Capability =132      SPIRV::lookupCapabilityByCategoryAndValue(Category, Value);133  auto TableEnd = ArrayRef(SPIRV::CapabilityEntries).end();134  while (Capability && Capability->Category == Category &&135         Capability->Value == Value) {136    Capabilities.push_back(137        static_cast<SPIRV::Capability::Capability>(Capability->ReqCapability));138    if (++Capability == TableEnd)139      break;140  }141 142  return Capabilities;143}144 145EnvironmentList getSymbolicOperandAllowedEnvironments(146    SPIRV::OperandCategory::OperandCategory Category, uint32_t Value) {147  EnvironmentList Environments;148  const SPIRV::EnvironmentEntry *Environment =149      SPIRV::lookupEnvironmentByCategoryAndValue(Category, Value);150  auto TableEnd = ArrayRef(SPIRV::EnvironmentEntries).end();151  while (Environment && Environment->Category == Category &&152         Environment->Value == Value) {153    Environments.push_back(static_cast<SPIRV::Environment::Environment>(154        Environment->AllowedEnvironment));155    if (++Environment == TableEnd)156      break;157  }158 159  return Environments;160}161 162CapabilityList163getCapabilitiesEnabledByExtension(SPIRV::Extension::Extension Extension) {164  const SPIRV::ExtensionEntry *Entry =165      SPIRV::lookupSymbolicOperandsEnabledByExtension(166          Extension, SPIRV::OperandCategory::CapabilityOperand);167 168  CapabilityList Capabilities;169  auto TableEnd = ArrayRef(SPIRV::ExtensionEntries).end();170  while (Entry &&171         Entry->Category == SPIRV::OperandCategory::CapabilityOperand) {172    // Some capabilities' codes might go not in order.173    if (Entry->ReqExtension == Extension)174      Capabilities.push_back(175          static_cast<SPIRV::Capability::Capability>(Entry->Value));176    if (++Entry == TableEnd)177      break;178  }179 180  return Capabilities;181}182 183ExtensionList184getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category,185                             uint32_t Value) {186  const SPIRV::ExtensionEntry *Extension =187      SPIRV::lookupExtensionByCategoryAndValue(Category, Value);188 189  ExtensionList Extensions;190  auto TableEnd = ArrayRef(SPIRV::ExtensionEntries).end();191  while (Extension && Extension->Category == Category &&192         Extension->Value == Value) {193    Extensions.push_back(194        static_cast<SPIRV::Extension::Extension>(Extension->ReqExtension));195    if (++Extension == TableEnd)196      break;197  }198 199  return Extensions;200}201 202std::string getLinkStringForBuiltIn(SPIRV::BuiltIn::BuiltIn BuiltInValue) {203  const SPIRV::SymbolicOperand *Lookup =204      SPIRV::lookupSymbolicOperandByCategoryAndValue(205          SPIRV::OperandCategory::BuiltInOperand, BuiltInValue);206 207  if (Lookup)208    return "__spirv_BuiltIn" + Lookup->Mnemonic.str();209  return "UNKNOWN_BUILTIN";210}211 212bool getSpirvBuiltInIdByName(llvm::StringRef Name,213                             SPIRV::BuiltIn::BuiltIn &BI) {214  const std::string Prefix = "__spirv_BuiltIn";215  if (!Name.starts_with(Prefix))216    return false;217 218  const SPIRV::SymbolicOperand *Lookup =219      SPIRV::lookupSymbolicOperandByCategoryAndMnemonic(220          SPIRV::OperandCategory::BuiltInOperand,221          Name.drop_front(Prefix.length()));222 223  if (!Lookup)224    return false;225 226  BI = static_cast<SPIRV::BuiltIn::BuiltIn>(Lookup->Value);227  return true;228}229 230std::string getExtInstSetName(SPIRV::InstructionSet::InstructionSet Set) {231  switch (Set) {232  case SPIRV::InstructionSet::OpenCL_std:233    return "OpenCL.std";234  case SPIRV::InstructionSet::GLSL_std_450:235    return "GLSL.std.450";236  case SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100:237    return "NonSemantic.Shader.DebugInfo.100";238  case SPIRV::InstructionSet::SPV_AMD_shader_trinary_minmax:239    return "SPV_AMD_shader_trinary_minmax";240  }241  return "UNKNOWN_EXT_INST_SET";242}243 244SPIRV::InstructionSet::InstructionSet245getExtInstSetFromString(std::string SetName) {246  for (auto Set :247       {SPIRV::InstructionSet::GLSL_std_450, SPIRV::InstructionSet::OpenCL_std,248        SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100}) {249    if (SetName == getExtInstSetName(Set))250      return Set;251  }252  llvm_unreachable("UNKNOWN_EXT_INST_SET");253}254 255std::string getExtInstName(SPIRV::InstructionSet::InstructionSet Set,256                           uint32_t InstructionNumber) {257  const SPIRV::ExtendedBuiltin *Lookup =258      SPIRV::lookupExtendedBuiltinBySetAndNumber(Set, InstructionNumber);259 260  if (!Lookup)261    return "UNKNOWN_EXT_INST";262 263  return Lookup->Name.str();264}265} // namespace llvm266