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