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