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(
77 const std::set<SPIRV::Extension::Extension> &AllowedExtIds);
78 void resolveEnvFromModule(const Module &M);
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 SPIRVEnvType getEnv() const { return Env; }
88 bool isKernel() const { return getEnv() == Kernel; }
89 bool isShader() const { return getEnv() == Shader; }
90 bool isLogicalSPIRV() const {
91 return TargetTriple.getArch() == Triple::spirv;
92 }
93 bool isPhysicalSPIRV() const {
94 return TargetTriple.getArch() == Triple::spirv32 ||
95 TargetTriple.getArch() == Triple::spirv64;
96 }
97 const std::string &getTargetTripleAsStr() const { return TargetTriple.str(); }
98 VersionTuple getSPIRVVersion() const { return SPIRVVersion; };
99 bool isAtLeastSPIRVVer(VersionTuple VerToCompareTo) const;
100 bool isAtLeastOpenCLVer(VersionTuple VerToCompareTo) const;
101 // TODO: implement command line args or other ways to determine this.
102 bool hasOpenCLFullProfile() const { return true; }
103 bool hasOpenCLImageSupport() const { return true; }
104 const SmallSet<SPIRV::Extension::Extension, 4> &
105 getAllAvailableExtensions() const {
106 return AvailableExtensions;
107 }
108 bool canUseExtension(SPIRV::Extension::Extension E) const;
109 bool canUseExtInstSet(SPIRV::InstructionSet::InstructionSet E) const;
110 SPIRV::InstructionSet::InstructionSet getPreferredInstructionSet() const;
111
112 SPIRVGlobalRegistry *getSPIRVGlobalRegistry() const { return GR.get(); }
113
114 const CallLowering *getCallLowering() const override {
115 return CallLoweringInfo.get();
116 }
117 const RegisterBankInfo *getRegBankInfo() const override {
118 return RegBankInfo.get();
119 }
120 const LegalizerInfo *getLegalizerInfo() const override {
121 return Legalizer.get();
122 }
123 InstructionSelector *getInstructionSelector() const override {
124 return InstSelector.get();
125 }
126 const InlineAsmLowering *getInlineAsmLowering() const override {
127 return InlineAsmInfo.get();
128 }
129 const SPIRVInstrInfo *getInstrInfo() const override { return &InstrInfo; }
130 const SPIRVFrameLowering *getFrameLowering() const override {
131 return &FrameLowering;
132 }
133 const SPIRVTargetLowering *getTargetLowering() const override {
134 return &TLInfo;
135 }
136 const SPIRVRegisterInfo *getRegisterInfo() const override {
137 return &InstrInfo.getRegisterInfo();
138 }
139
140 static bool classof(const TargetSubtargetInfo *ST) {
141 return ST->getTargetTriple().isSPIRV();
142 }
143
144 static constexpr unsigned MaxLegalAddressSpace = 6;
145
146 // Adds known SPIR-V extensions to the global list of allowed extensions that
147 // SPIRVSubtarget module owns as
148 // cl::opt<std::set<SPIRV::Extension::Extension>, ...> global variable.
149 static void
150 addExtensionsToClOpt(const std::set<SPIRV::Extension::Extension> &AllowList);
151};
152} // namespace llvm
153
154#endif // LLVM_LIB_TARGET_SPIRV_SPIRVSUBTARGET_H
155