llvm-project/llvm/lib/Target/SPIRV/SPIRVSubtarget.h
Vyacheslav Levytskyy bca2b6d23f
[SPIR-V] Expose an API call to initialize SPIRV target and translate input LLVM IR module to SPIR-V (#107216)
The goal of this PR is to facilitate integration of SPIRV Backend into
misc 3rd party tools and libraries by means of exposing an API call that
translate LLVM module to SPIR-V and write results into a string as
binary SPIR-V output, providing diagnostics on fail and means of
configuring translation in a style of command line options.

An example of a use case may be Khronos Translator that provides
bidirectional translation LLVM IR <=> SPIR-V, where LLVM IR => SPIR-V
step may be substituted by the call to SPIR-V Backend API, implemented
by this PR.
2024-09-10 15:51:20 +02:00

143 lines
5.4 KiB
C++

//===-- SPIRVSubtarget.h - SPIR-V Subtarget Information --------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file declares the SPIR-V specific subclass of TargetSubtargetInfo.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVSUBTARGET_H
#define LLVM_LIB_TARGET_SPIRV_SPIRVSUBTARGET_H
#include "SPIRVCallLowering.h"
#include "SPIRVFrameLowering.h"
#include "SPIRVISelLowering.h"
#include "SPIRVInlineAsmLowering.h"
#include "SPIRVInstrInfo.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/TargetParser/Triple.h"
#define GET_SUBTARGETINFO_HEADER
#include "SPIRVGenSubtargetInfo.inc"
namespace llvm {
class StringRef;
class SPIRVTargetMachine;
class SPIRVSubtarget : public SPIRVGenSubtargetInfo {
private:
const unsigned PointerSize;
VersionTuple SPIRVVersion;
VersionTuple OpenCLVersion;
SmallSet<SPIRV::Extension::Extension, 4> AvailableExtensions;
SmallSet<SPIRV::InstructionSet::InstructionSet, 4> AvailableExtInstSets;
std::unique_ptr<SPIRVGlobalRegistry> GR;
SPIRVInstrInfo InstrInfo;
SPIRVFrameLowering FrameLowering;
SPIRVTargetLowering TLInfo;
Triple TargetTriple;
// GlobalISel related APIs.
std::unique_ptr<CallLowering> CallLoweringInfo;
std::unique_ptr<RegisterBankInfo> RegBankInfo;
std::unique_ptr<LegalizerInfo> Legalizer;
std::unique_ptr<InstructionSelector> InstSelector;
std::unique_ptr<InlineAsmLowering> InlineAsmInfo;
// TODO: Initialise the available extensions, extended instruction sets
// based on the environment settings.
void initAvailableExtensions();
void initAvailableExtInstSets();
public:
// This constructor initializes the data members to match that
// of the specified triple.
SPIRVSubtarget(const Triple &TT, const std::string &CPU,
const std::string &FS, const SPIRVTargetMachine &TM);
SPIRVSubtarget &initSubtargetDependencies(StringRef CPU, StringRef FS);
// Parses features string setting specified subtarget options.
// The definition of this function is auto generated by tblgen.
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
unsigned getPointerSize() const { return PointerSize; }
unsigned getBound() const { return GR->getBound(); }
bool canDirectlyComparePointers() const;
// TODO: this environment is not implemented in Triple, we need to decide
// how to standardize its support. For now, let's assume SPIR-V with physical
// addressing is OpenCL, and Logical addressing is Vulkan.
bool isOpenCLEnv() const {
return TargetTriple.getArch() == Triple::spirv32 ||
TargetTriple.getArch() == Triple::spirv64;
}
bool isVulkanEnv() const { return TargetTriple.getArch() == Triple::spirv; }
const std::string &getTargetTripleAsStr() const { return TargetTriple.str(); }
VersionTuple getSPIRVVersion() const { return SPIRVVersion; };
bool isAtLeastSPIRVVer(VersionTuple VerToCompareTo) const;
bool isAtLeastOpenCLVer(VersionTuple VerToCompareTo) const;
// TODO: implement command line args or other ways to determine this.
bool hasOpenCLFullProfile() const { return true; }
bool hasOpenCLImageSupport() const { return true; }
const SmallSet<SPIRV::Extension::Extension, 4> &
getAllAvailableExtensions() const {
return AvailableExtensions;
}
bool canUseExtension(SPIRV::Extension::Extension E) const;
bool canUseExtInstSet(SPIRV::InstructionSet::InstructionSet E) const;
SPIRVGlobalRegistry *getSPIRVGlobalRegistry() const { return GR.get(); }
const CallLowering *getCallLowering() const override {
return CallLoweringInfo.get();
}
const RegisterBankInfo *getRegBankInfo() const override {
return RegBankInfo.get();
}
const LegalizerInfo *getLegalizerInfo() const override {
return Legalizer.get();
}
InstructionSelector *getInstructionSelector() const override {
return InstSelector.get();
}
const InlineAsmLowering *getInlineAsmLowering() const override {
return InlineAsmInfo.get();
}
const SPIRVInstrInfo *getInstrInfo() const override { return &InstrInfo; }
const SPIRVFrameLowering *getFrameLowering() const override {
return &FrameLowering;
}
const SPIRVTargetLowering *getTargetLowering() const override {
return &TLInfo;
}
const SPIRVRegisterInfo *getRegisterInfo() const override {
return &InstrInfo.getRegisterInfo();
}
static bool classof(const TargetSubtargetInfo *ST) {
return ST->getTargetTriple().isSPIRV();
}
static constexpr unsigned MaxLegalAddressSpace = 6;
// Adds known SPIR-V extensions to the global list of allowed extensions that
// SPIRVSubtarget module owns as
// cl::opt<std::set<SPIRV::Extension::Extension>, ...> global variable.
static void
addExtensionsToClOpt(const std::set<SPIRV::Extension::Extension> &AllowList);
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_SPIRV_SPIRVSUBTARGET_H