Path: blob/main/contrib/llvm-project/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
35269 views
//===-- SPIRVSubtarget.cpp - SPIR-V Subtarget Information ------*- C++ -*--===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the SPIR-V specific subclass of TargetSubtargetInfo.9//10//===----------------------------------------------------------------------===//1112#include "SPIRVSubtarget.h"13#include "SPIRV.h"14#include "SPIRVCommandLine.h"15#include "SPIRVGlobalRegistry.h"16#include "SPIRVLegalizerInfo.h"17#include "SPIRVRegisterBankInfo.h"18#include "SPIRVTargetMachine.h"19#include "llvm/MC/TargetRegistry.h"20#include "llvm/TargetParser/Host.h"2122using namespace llvm;2324#define DEBUG_TYPE "spirv-subtarget"2526#define GET_SUBTARGETINFO_TARGET_DESC27#define GET_SUBTARGETINFO_CTOR28#include "SPIRVGenSubtargetInfo.inc"2930static cl::opt<bool>31SPVTranslatorCompat("translator-compatibility-mode",32cl::desc("SPIR-V Translator compatibility mode"),33cl::Optional, cl::init(false));3435static cl::opt<std::set<SPIRV::Extension::Extension>, false,36SPIRVExtensionsParser>37Extensions("spirv-ext",38cl::desc("Specify list of enabled SPIR-V extensions"));3940// Compare version numbers, but allow 0 to mean unspecified.41static bool isAtLeastVer(VersionTuple Target, VersionTuple VerToCompareTo) {42return Target.empty() || Target >= VerToCompareTo;43}4445SPIRVSubtarget::SPIRVSubtarget(const Triple &TT, const std::string &CPU,46const std::string &FS,47const SPIRVTargetMachine &TM)48: SPIRVGenSubtargetInfo(TT, CPU, /*TuneCPU=*/CPU, FS),49PointerSize(TM.getPointerSizeInBits(/* AS= */ 0)), InstrInfo(),50FrameLowering(initSubtargetDependencies(CPU, FS)), TLInfo(TM, *this),51TargetTriple(TT) {52switch (TT.getSubArch()) {53case Triple::SPIRVSubArch_v10:54SPIRVVersion = VersionTuple(1, 0);55break;56case Triple::SPIRVSubArch_v11:57SPIRVVersion = VersionTuple(1, 1);58break;59case Triple::SPIRVSubArch_v12:60SPIRVVersion = VersionTuple(1, 2);61break;62case Triple::SPIRVSubArch_v13:63SPIRVVersion = VersionTuple(1, 3);64break;65case Triple::SPIRVSubArch_v14:66default:67SPIRVVersion = VersionTuple(1, 4);68break;69case Triple::SPIRVSubArch_v15:70SPIRVVersion = VersionTuple(1, 5);71break;72case Triple::SPIRVSubArch_v16:73SPIRVVersion = VersionTuple(1, 6);74break;75}76OpenCLVersion = VersionTuple(2, 2);7778// The order of initialization is important.79initAvailableExtensions();80initAvailableExtInstSets();8182GR = std::make_unique<SPIRVGlobalRegistry>(PointerSize);83CallLoweringInfo = std::make_unique<SPIRVCallLowering>(TLInfo, GR.get());84InlineAsmInfo = std::make_unique<SPIRVInlineAsmLowering>(TLInfo);85Legalizer = std::make_unique<SPIRVLegalizerInfo>(*this);86RegBankInfo = std::make_unique<SPIRVRegisterBankInfo>();87InstSelector.reset(88createSPIRVInstructionSelector(TM, *this, *RegBankInfo.get()));89}9091SPIRVSubtarget &SPIRVSubtarget::initSubtargetDependencies(StringRef CPU,92StringRef FS) {93ParseSubtargetFeatures(CPU, /*TuneCPU=*/CPU, FS);94return *this;95}9697bool SPIRVSubtarget::canUseExtension(SPIRV::Extension::Extension E) const {98return AvailableExtensions.contains(E);99}100101bool SPIRVSubtarget::canUseExtInstSet(102SPIRV::InstructionSet::InstructionSet E) const {103return AvailableExtInstSets.contains(E);104}105106bool SPIRVSubtarget::isAtLeastSPIRVVer(VersionTuple VerToCompareTo) const {107return isAtLeastVer(SPIRVVersion, VerToCompareTo);108}109110bool SPIRVSubtarget::isAtLeastOpenCLVer(VersionTuple VerToCompareTo) const {111if (!isOpenCLEnv())112return false;113return isAtLeastVer(OpenCLVersion, VerToCompareTo);114}115116// If the SPIR-V version is >= 1.4 we can call OpPtrEqual and OpPtrNotEqual.117// In SPIR-V Translator compatibility mode this feature is not available.118bool SPIRVSubtarget::canDirectlyComparePointers() const {119return !SPVTranslatorCompat && isAtLeastVer(SPIRVVersion, VersionTuple(1, 4));120}121122void SPIRVSubtarget::initAvailableExtensions() {123AvailableExtensions.clear();124if (!isOpenCLEnv())125return;126127AvailableExtensions.insert(Extensions.begin(), Extensions.end());128}129130// TODO: use command line args for this rather than just defaults.131// Must have called initAvailableExtensions first.132void SPIRVSubtarget::initAvailableExtInstSets() {133AvailableExtInstSets.clear();134if (!isOpenCLEnv())135AvailableExtInstSets.insert(SPIRV::InstructionSet::GLSL_std_450);136else137AvailableExtInstSets.insert(SPIRV::InstructionSet::OpenCL_std);138139// Handle extended instruction sets from extensions.140if (canUseExtension(141SPIRV::Extension::SPV_AMD_shader_trinary_minmax_extension)) {142AvailableExtInstSets.insert(143SPIRV::InstructionSet::SPV_AMD_shader_trinary_minmax);144}145}146147148