1//===-- SPIRVSubtarget.h - SPIR-V Subtarget Information --------*- 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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file declares the SPIR-V specific subclass of TargetSubtargetInfo.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVSUBTARGET_H
14#define LLVM_LIB_TARGET_SPIRV_SPIRVSUBTARGET_H
15
16#include "SPIRVCallLowering.h"
17#include "SPIRVFrameLowering.h"
18#include "SPIRVISelLowering.h"
19#include "SPIRVInlineAsmLowering.h"
20#include "SPIRVInstrInfo.h"
21#include "llvm/ADT/SmallSet.h"
22#include "llvm/CodeGen/GlobalISel/CallLowering.h"
23#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
24#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
25#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
26#include "llvm/CodeGen/TargetSubtargetInfo.h"
27#include "llvm/IR/DataLayout.h"
28#include "llvm/IR/Module.h"
29#include "llvm/Target/TargetMachine.h"
30#include "llvm/TargetParser/Triple.h"
31
32#define GET_SUBTARGETINFO_HEADER
33#include "SPIRVGenSubtargetInfo.inc"
34
35namespace llvm {
36class StringRef;
37class SPIRVTargetMachine;
38
39class SPIRVSubtarget : public SPIRVGenSubtargetInfo {
40public:
41 // Enum for the SPIR-V environment: Kernel, Shader or Unknown.
42 enum SPIRVEnvType { Kernel, Shader, Unknown };
43
44private:
45 const unsigned PointerSize;
46 VersionTuple SPIRVVersion;
47 VersionTuple OpenCLVersion;
48
49 SmallSet<SPIRV::Extension::Extension, 4> AvailableExtensions;
50 SmallSet<SPIRV::InstructionSet::InstructionSet, 4> AvailableExtInstSets;
51 std::unique_ptr<SPIRVGlobalRegistry> GR;
52
53 SPIRVInstrInfo InstrInfo;
54 SPIRVFrameLowering FrameLowering;
55 SPIRVTargetLowering TLInfo;
56 Triple TargetTriple;
57 SPIRVEnvType Env;
58
59 // GlobalISel related APIs.
60 std::unique_ptr<CallLowering> CallLoweringInfo;
61 std::unique_ptr<RegisterBankInfo> RegBankInfo;
62 std::unique_ptr<LegalizerInfo> Legalizer;
63 std::unique_ptr<InstructionSelector> InstSelector;
64 std::unique_ptr<InlineAsmLowering> InlineAsmInfo;
65
66 void initAvailableExtInstSets();
67 void accountForAMDShaderTrinaryMinmax();
68
69public:
70 // This constructor initializes the data members to match that
71 // of the specified triple.
72 SPIRVSubtarget(const Triple &TT, const std::string &CPU,
73 const std::string &FS, const SPIRVTargetMachine &TM);
74 SPIRVSubtarget &initSubtargetDependencies(StringRef CPU, StringRef FS);
75
76 void initAvailableExtensions(const ExtensionSet &AllowedExtIds);
77 void resolveEnvFromModule(const Module &M);
78
79 // Parses features string setting specified subtarget options.
80 // The definition of this function is auto generated by tblgen.
81 void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
82 unsigned getPointerSize() const { return PointerSize; }
83 unsigned getBound() const { return GR->getBound(); }
84 bool canDirectlyComparePointers() const;
85 void setEnv(SPIRVEnvType E);
86 SPIRVEnvType getEnv() const { return Env; }
87 bool isKernel() const { return getEnv() == Kernel; }
88 bool isShader() const { return getEnv() == Shader; }
89 bool isLogicalSPIRV() const {
90 return TargetTriple.getArch() == Triple::spirv;
91 }
92 bool isPhysicalSPIRV() const {
93 return TargetTriple.getArch() == Triple::spirv32 ||
94 TargetTriple.getArch() == Triple::spirv64;
95 }
96 const std::string &getTargetTripleAsStr() const { return TargetTriple.str(); }
97 VersionTuple getSPIRVVersion() const { return SPIRVVersion; };
98 bool isAtLeastSPIRVVer(VersionTuple VerToCompareTo) const;
99 bool isAtLeastOpenCLVer(VersionTuple VerToCompareTo) const;
100 // TODO: implement command line args or other ways to determine this.
101 bool hasOpenCLFullProfile() const { return true; }
102 bool hasOpenCLImageSupport() const { return true; }
103 const SmallSet<SPIRV::Extension::Extension, 4> &
104 getAllAvailableExtensions() const {
105 return AvailableExtensions;
106 }
107 bool canUseExtension(SPIRV::Extension::Extension E) const;
108 bool canUseExtInstSet(SPIRV::InstructionSet::InstructionSet E) const;
109 SPIRV::InstructionSet::InstructionSet getPreferredInstructionSet() const;
110
111 SPIRVGlobalRegistry *getSPIRVGlobalRegistry() const { return GR.get(); }
112
113 const CallLowering *getCallLowering() const override {
114 return CallLoweringInfo.get();
115 }
116 const RegisterBankInfo *getRegBankInfo() const override {
117 return RegBankInfo.get();
118 }
119 const LegalizerInfo *getLegalizerInfo() const override {
120 return Legalizer.get();
121 }
122 InstructionSelector *getInstructionSelector() const override {
123 return InstSelector.get();
124 }
125 const InlineAsmLowering *getInlineAsmLowering() const override {
126 return InlineAsmInfo.get();
127 }
128 const SPIRVInstrInfo *getInstrInfo() const override { return &InstrInfo; }
129 const SPIRVFrameLowering *getFrameLowering() const override {
130 return &FrameLowering;
131 }
132 const SPIRVTargetLowering *getTargetLowering() const override {
133 return &TLInfo;
134 }
135 const SPIRVRegisterInfo *getRegisterInfo() const override {
136 return &InstrInfo.getRegisterInfo();
137 }
138
139 static bool classof(const TargetSubtargetInfo *ST) {
140 return ST->getTargetTriple().isSPIRV();
141 }
142
143 static constexpr unsigned MaxLegalAddressSpace = 6;
144
145 // Adds known SPIR-V extensions to the global list of allowed extensions that
146 // SPIRVSubtarget module owns as
147 // cl::opt<ExtensionSet, ...> global variable.
148 static void addExtensionsToClOpt(const ExtensionSet &AllowList);
149};
150} // namespace llvm
151
152#endif // LLVM_LIB_TARGET_SPIRV_SPIRVSUBTARGET_H
153