clang  16.0.0git
HLSL.cpp
Go to the documentation of this file.
1 //===--- HLSL.cpp - HLSL ToolChain Implementations --------------*- 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 #include "HLSL.h"
10 #include "CommonArgs.h"
12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/ADT/Triple.h"
14 
15 using namespace clang::driver;
16 using namespace clang::driver::tools;
17 using namespace clang::driver::toolchains;
18 using namespace clang;
19 using namespace llvm::opt;
20 using namespace llvm;
21 
22 namespace {
23 
24 const unsigned OfflineLibMinor = 0xF;
25 
26 bool isLegalShaderModel(Triple &T) {
27  if (T.getOS() != Triple::OSType::ShaderModel)
28  return false;
29 
30  auto Version = T.getOSVersion();
31  if (Version.getBuild())
32  return false;
33  if (Version.getSubminor())
34  return false;
35 
36  auto Kind = T.getEnvironment();
37 
38  switch (Kind) {
39  default:
40  return false;
41  case Triple::EnvironmentType::Vertex:
42  case Triple::EnvironmentType::Hull:
43  case Triple::EnvironmentType::Domain:
44  case Triple::EnvironmentType::Geometry:
45  case Triple::EnvironmentType::Pixel:
46  case Triple::EnvironmentType::Compute: {
47  VersionTuple MinVer(4, 0);
48  return MinVer <= Version;
49  } break;
50  case Triple::EnvironmentType::Library: {
51  VersionTuple SM6x(6, OfflineLibMinor);
52  if (Version == SM6x)
53  return true;
54 
55  VersionTuple MinVer(6, 3);
56  return MinVer <= Version;
57  } break;
58  case Triple::EnvironmentType::Amplification:
59  case Triple::EnvironmentType::Mesh: {
60  VersionTuple MinVer(6, 5);
61  return MinVer <= Version;
62  } break;
63  }
64  return false;
65 }
66 
67 llvm::Optional<std::string> tryParseProfile(StringRef Profile) {
68  // [ps|vs|gs|hs|ds|cs|ms|as]_[major]_[minor]
70  Profile.split(Parts, "_");
71  if (Parts.size() != 3)
72  return NoneType();
73 
74  Triple::EnvironmentType Kind =
75  StringSwitch<Triple::EnvironmentType>(Parts[0])
76  .Case("ps", Triple::EnvironmentType::Pixel)
77  .Case("vs", Triple::EnvironmentType::Vertex)
78  .Case("gs", Triple::EnvironmentType::Geometry)
79  .Case("hs", Triple::EnvironmentType::Hull)
80  .Case("ds", Triple::EnvironmentType::Domain)
81  .Case("cs", Triple::EnvironmentType::Compute)
82  .Case("lib", Triple::EnvironmentType::Library)
83  .Case("ms", Triple::EnvironmentType::Mesh)
84  .Case("as", Triple::EnvironmentType::Amplification)
85  .Default(Triple::EnvironmentType::UnknownEnvironment);
86  if (Kind == Triple::EnvironmentType::UnknownEnvironment)
87  return NoneType();
88 
89  unsigned long long Major = 0;
90  if (llvm::getAsUnsignedInteger(Parts[1], 0, Major))
91  return NoneType();
92 
93  unsigned long long Minor = 0;
94  if (Parts[2] == "x" && Kind == Triple::EnvironmentType::Library)
95  Minor = OfflineLibMinor;
96  else if (llvm::getAsUnsignedInteger(Parts[2], 0, Minor))
97  return NoneType();
98 
99  // dxil-unknown-shadermodel-hull
100  llvm::Triple T;
101  T.setArch(Triple::ArchType::dxil);
102  T.setOSName(Triple::getOSTypeName(Triple::OSType::ShaderModel).str() +
103  VersionTuple(Major, Minor).getAsString());
104  T.setEnvironment(Kind);
105  if (isLegalShaderModel(T))
106  return T.getTriple();
107  else
108  return NoneType();
109 }
110 
111 bool isLegalValidatorVersion(StringRef ValVersionStr, const Driver &D) {
112  VersionTuple Version;
113  if (Version.tryParse(ValVersionStr) || Version.getBuild() ||
114  Version.getSubminor() || !Version.getMinor()) {
115  D.Diag(diag::err_drv_invalid_format_dxil_validator_version)
116  << ValVersionStr;
117  return false;
118  }
119 
120  uint64_t Major = Version.getMajor();
121  uint64_t Minor = *Version.getMinor();
122  if (Major == 0 && Minor != 0) {
123  D.Diag(diag::err_drv_invalid_empty_dxil_validator_version) << ValVersionStr;
124  return false;
125  }
126  VersionTuple MinVer(1, 0);
127  if (Version < MinVer) {
128  D.Diag(diag::err_drv_invalid_range_dxil_validator_version) << ValVersionStr;
129  return false;
130  }
131  return true;
132 }
133 
134 } // namespace
135 
136 /// DirectX Toolchain
137 HLSLToolChain::HLSLToolChain(const Driver &D, const llvm::Triple &Triple,
138  const ArgList &Args)
139  : ToolChain(D, Triple, Args) {}
140 
143  StringRef TargetProfile) {
144  return tryParseProfile(TargetProfile);
145 }
146 
147 DerivedArgList *
148 HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
149  Action::OffloadKind DeviceOffloadKind) const {
150  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
151 
152  const OptTable &Opts = getDriver().getOpts();
153 
154  for (Arg *A : Args) {
155  if (A->getOption().getID() == options::OPT_dxil_validator_version) {
156  StringRef ValVerStr = A->getValue();
157  std::string ErrorMsg;
158  if (!isLegalValidatorVersion(ValVerStr, getDriver()))
159  continue;
160  }
161  if (A->getOption().getID() == options::OPT_dxc_entrypoint) {
162  DAL->AddSeparateArg(nullptr, Opts.getOption(options::OPT_hlsl_entrypoint),
163  A->getValue());
164  A->claim();
165  continue;
166  }
167  if (A->getOption().getID() == options::OPT__SLASH_O) {
168  StringRef OStr = A->getValue();
169  if (OStr == "d") {
170  DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_O0));
171  A->claim();
172  continue;
173  } else {
174  DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_O), OStr);
175  A->claim();
176  continue;
177  }
178  }
179  if (A->getOption().getID() == options::OPT_emit_pristine_llvm) {
180  // Translate fcgl into -S -emit-llvm and -disable-llvm-passes.
181  DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_S));
182  DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_emit_llvm));
183  DAL->AddFlagArg(nullptr,
184  Opts.getOption(options::OPT_disable_llvm_passes));
185  A->claim();
186  continue;
187  }
188  DAL->append(A);
189  }
190 
191  if (DAL->hasArg(options::OPT_o)) {
192  // When run the whole pipeline.
193  if (!DAL->hasArg(options::OPT_emit_llvm))
194  // Emit obj if write to file.
195  DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_emit_obj));
196  } else
197  DAL->AddSeparateArg(nullptr, Opts.getOption(options::OPT_o), "-");
198 
199  // Add default validator version if not set.
200  // TODO: remove this once read validator version from validator.
201  if (!DAL->hasArg(options::OPT_dxil_validator_version)) {
202  const StringRef DefaultValidatorVer = "1.7";
203  DAL->AddSeparateArg(nullptr,
204  Opts.getOption(options::OPT_dxil_validator_version),
205  DefaultValidatorVer);
206  }
207  if (!DAL->hasArg(options::OPT_O_Group)) {
208  DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_O), "3");
209  }
210  // FIXME: add validation for enable_16bit_types should be after HLSL 2018 and
211  // shader model 6.2.
212  return DAL;
213 }
clang::driver::toolchains
Definition: AIX.h:55
llvm
YAML serialization mapping.
Definition: Dominators.h:30
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
llvm::SmallVector
Definition: LLVM.h:38
HLSL.h
clang::driver::tools
Definition: AIX.h:17
clang::driver::ToolChain::getDriver
const Driver & getDriver() const
Definition: ToolChain.h:232
llvm::Optional< std::string >
clang::driver::Driver::getOpts
const llvm::opt::OptTable & getOpts() const
Definition: Driver.h:358
uint64_t
unsigned long uint64_t
Definition: hlsl_basic_types.h:24
clang::driver::toolchains::HLSLToolChain::parseTargetProfile
static llvm::Optional< std::string > parseTargetProfile(StringRef TargetProfile)
Definition: HLSL.cpp:142
clang::getAsString
llvm::StringRef getAsString(SyncScope S)
Definition: SyncScope.h:55
clang::driver::Driver::Diag
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:137
llvm::opt
Definition: DiagnosticOptions.h:19
DriverDiagnostic.h
clang::driver::ToolChain
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:91
clang::ObjCPropertyAttribute::Kind
Kind
Definition: DeclObjCCommon.h:22
CommonArgs.h
clang
Definition: CalledOnceCheck.h:17
clang::driver::Driver
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:70
clang::driver::Action::OffloadKind
OffloadKind
Definition: Action.h:87
clang::driver
Definition: Action.h:31
clang::driver::toolchains::HLSLToolChain::TranslateArgs
llvm::opt::DerivedArgList * TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, Action::OffloadKind DeviceOffloadKind) const override
TranslateArgs - Create a new derived argument list for any argument translations this ToolChain may w...
Definition: HLSL.cpp:148