Skip to content

Commit 721651b

Browse files
python3kgaellvm-beanz
authored andcommitted
[HLSL][clang][Driver] Support target profile command line option.
The target profile option(/T) decide the shader model when compile hlsl. The format is shaderKind_major_minor like ps_6_1. The shader model is saved as llvm::Triple is clang/llvm like dxil-unknown-shadermodel6.1-hull. The main job to support the option is translating ps_6_1 into shadermodel6.1-pixel. That is done inside tryParseProfile at HLSL.cpp. To integrate the option into clang Driver, a new DriverMode DxcMode is created. When DxcMode is enabled, OSType for TargetTriple will be forced into Triple::ShaderModel. And new ToolChain HLSLToolChain will be created when OSType is Triple::ShaderModel. In HLSLToolChain, ComputeEffectiveClangTriple is overridden to call tryParseProfile when targetProfile option is set. To make test work, Fo option is added and .hlsl is added for active -xhlsl. Reviewed By: beanz Differential Revision: https://reviews.llvm.org/D122865 Patch by: Xiang Li <python3kgae@outlook.com>
1 parent 69c1a35 commit 721651b

File tree

12 files changed

+381
-3
lines changed

12 files changed

+381
-3
lines changed

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,4 +657,7 @@ def warn_drv_fjmc_for_elf_only : Warning<
657657
def err_drv_target_variant_invalid : Error<
658658
"unsupported '%0' value '%1'; use 'ios-macabi' instead">;
659659

660+
def err_drv_invalid_directx_shader_module : Error<
661+
"invalid profile : %0">;
662+
660663
}

clang/include/clang/Driver/Driver.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ class Driver {
6868
GXXMode,
6969
CPPMode,
7070
CLMode,
71-
FlangMode
71+
FlangMode,
72+
DXCMode
7273
} Mode;
7374

7475
enum SaveTempsMode {
@@ -195,6 +196,9 @@ class Driver {
195196
/// Other modes fall back to calling gcc which in turn calls gfortran.
196197
bool IsFlangMode() const { return Mode == FlangMode; }
197198

199+
/// Whether the driver should follow dxc.exe like behavior.
200+
bool IsDXCMode() const { return Mode == DXCMode; }
201+
198202
/// Only print tool bindings, don't build any jobs.
199203
unsigned CCCPrintBindings : 1;
200204

clang/include/clang/Driver/Options.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ enum ClangFlags {
3535
FlangOption = (1 << 14),
3636
FC1Option = (1 << 15),
3737
FlangOnlyOption = (1 << 16),
38-
Ignored = (1 << 17),
38+
DXCOption = (1 << 17),
39+
Ignored = (1 << 18),
3940
};
4041

4142
enum ID {

clang/include/clang/Driver/Options.td

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ def CC1Option : OptionFlag;
4949
// CC1AsOption - This option should be accepted by clang -cc1as.
5050
def CC1AsOption : OptionFlag;
5151

52+
// DXCOption - This is a dxc.exe compatibility option. Options with this flag
53+
// are made available when the driver is running in DXC compatibility mode.
54+
def DXCOption : OptionFlag;
55+
5256
// NoDriverOption - This option should not be accepted by the driver.
5357
def NoDriverOption : OptionFlag;
5458

@@ -6686,3 +6690,33 @@ def _SLASH_Ze : CLFlag<"Ze">;
66866690
def _SLASH_Zg : CLFlag<"Zg">;
66876691
def _SLASH_ZI : CLFlag<"ZI">;
66886692
def _SLASH_ZW : CLJoined<"ZW">;
6693+
6694+
//===----------------------------------------------------------------------===//
6695+
// clang-dxc Options
6696+
//===----------------------------------------------------------------------===//
6697+
6698+
def dxc_Group : OptionGroup<"<clang-dxc options>">, Flags<[DXCOption]>,
6699+
HelpText<"dxc compatibility options">;
6700+
6701+
class DXCJoinedOrSeparate<string name> : Option<["/", "-"], name,
6702+
KIND_JOINED_OR_SEPARATE>, Group<dxc_Group>, Flags<[DXCOption, NoXarchOption]>;
6703+
6704+
def dxc_help : Option<["/", "-", "--"], "help", KIND_JOINED>,
6705+
Group<dxc_Group>, Flags<[DXCOption, NoXarchOption]>, Alias<help>,
6706+
HelpText<"Display available options">;
6707+
6708+
6709+
def Fo : DXCJoinedOrSeparate<"Fo">, Alias<o>,
6710+
HelpText<"Output object file.">;
6711+
6712+
def target_profile : DXCJoinedOrSeparate<"T">, MetaVarName<"<profile>">,
6713+
HelpText<"Set target profile.">,
6714+
Values<"ps_6_0, ps_6_1, ps_6_2, ps_6_3, ps_6_4, ps_6_5, ps_6_6, ps_6_7,"
6715+
"vs_6_0, vs_6_1, vs_6_2, vs_6_3, vs_6_4, vs_6_5, vs_6_6, vs_6_7,"
6716+
"gs_6_0, gs_6_1, gs_6_2, gs_6_3, gs_6_4, gs_6_5, gs_6_6, gs_6_7,"
6717+
"hs_6_0, hs_6_1, hs_6_2, hs_6_3, hs_6_4, hs_6_5, hs_6_6, hs_6_7,"
6718+
"ds_6_0, ds_6_1, ds_6_2, ds_6_3, ds_6_4, ds_6_5, ds_6_6, ds_6_7,"
6719+
"cs_6_0, cs_6_1, cs_6_2, cs_6_3, cs_6_4, cs_6_5, cs_6_6, cs_6_7,"
6720+
"lib_6_3, lib_6_4, lib_6_5, lib_6_6, lib_6_7, lib_6_x,"
6721+
"ms_6_5, ms_6_6, ms_6_7,"
6722+
"as_6_5, as_6_6, as_6_7">;

clang/lib/Driver/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ add_clang_library(clangDriver
6060
ToolChains/HIPAMD.cpp
6161
ToolChains/HIPSPV.cpp
6262
ToolChains/Hexagon.cpp
63+
ToolChains/HLSL.cpp
6364
ToolChains/Hurd.cpp
6465
ToolChains/Linux.cpp
6566
ToolChains/MipsLinux.cpp

clang/lib/Driver/Driver.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "ToolChains/Gnu.h"
2727
#include "ToolChains/HIPAMD.h"
2828
#include "ToolChains/HIPSPV.h"
29+
#include "ToolChains/HLSL.h"
2930
#include "ToolChains/Haiku.h"
3031
#include "ToolChains/Hexagon.h"
3132
#include "ToolChains/Hurd.h"
@@ -232,6 +233,7 @@ void Driver::setDriverMode(StringRef Value) {
232233
.Case("cpp", CPPMode)
233234
.Case("cl", CLMode)
234235
.Case("flang", FlangMode)
236+
.Case("dxc", DXCMode)
235237
.Default(None))
236238
Mode = *M;
237239
else
@@ -1190,7 +1192,14 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
11901192
T.setEnvironment(llvm::Triple::MSVC);
11911193
T.setObjectFormat(llvm::Triple::COFF);
11921194
TargetTriple = T.str();
1195+
} else if (IsDXCMode()) {
1196+
// clang-dxc target is build from target_profile option.
1197+
// Just set OS to shader model to select HLSLToolChain.
1198+
llvm::Triple T(TargetTriple);
1199+
T.setOS(llvm::Triple::ShaderModel);
1200+
TargetTriple = T.str();
11931201
}
1202+
11941203
if (const Arg *A = Args.getLastArg(options::OPT_target))
11951204
TargetTriple = A->getValue();
11961205
if (const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
@@ -5684,6 +5693,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
56845693
case llvm::Triple::ZOS:
56855694
TC = std::make_unique<toolchains::ZOS>(*this, Target, Args);
56865695
break;
5696+
case llvm::Triple::ShaderModel:
5697+
TC = std::make_unique<toolchains::HLSLToolChain>(*this, Target, Args);
5698+
break;
56875699
default:
56885700
// Of these targets, Hexagon is the only one that might have
56895701
// an OS of Linux, in which case it got handled above already.
@@ -5902,7 +5914,13 @@ Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const {
59025914
} else {
59035915
ExcludedFlagsBitmask |= options::CLOption;
59045916
}
5905-
5917+
if (IsDXCMode()) {
5918+
// Include DXC and Core options.
5919+
IncludedFlagsBitmask |= options::DXCOption;
5920+
IncludedFlagsBitmask |= options::CoreOption;
5921+
} else {
5922+
ExcludedFlagsBitmask |= options::DXCOption;
5923+
}
59065924
return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask);
59075925
}
59085926

clang/lib/Driver/ToolChain.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {
153153
{"cl", "--driver-mode=cl"},
154154
{"++", "--driver-mode=g++"},
155155
{"flang", "--driver-mode=flang"},
156+
{"clang-dxc", "--driver-mode=dxc"},
156157
};
157158

158159
for (size_t i = 0; i < llvm::array_lengthof(DriverSuffixes); ++i) {

clang/lib/Driver/ToolChains/HLSL.cpp

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
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"
11+
#include "clang/Driver/DriverDiagnostic.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+
std::string tryParseProfile(StringRef Profile) {
68+
// [ps|vs|gs|hs|ds|cs|ms|as]_[major]_[minor]
69+
SmallVector<StringRef, 3> Parts;
70+
Profile.split(Parts, "_");
71+
if (Parts.size() != 3)
72+
return "";
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 "";
88+
89+
unsigned long long Major = 0;
90+
if (llvm::getAsUnsignedInteger(Parts[1], 0, Major))
91+
return "";
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 "";
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 "";
109+
}
110+
111+
} // namespace
112+
113+
/// DirectX Toolchain
114+
HLSLToolChain::HLSLToolChain(const Driver &D, const llvm::Triple &Triple,
115+
const ArgList &Args)
116+
: ToolChain(D, Triple, Args) {}
117+
118+
std::string
119+
HLSLToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
120+
types::ID InputType) const {
121+
if (Arg *A = Args.getLastArg(options::OPT_target_profile)) {
122+
StringRef Profile = A->getValue();
123+
std::string Triple = tryParseProfile(Profile);
124+
if (Triple == "") {
125+
getDriver().Diag(diag::err_drv_invalid_directx_shader_module) << Profile;
126+
Triple = ToolChain::ComputeEffectiveClangTriple(Args, InputType);
127+
}
128+
A->claim();
129+
return Triple;
130+
} else {
131+
return ToolChain::ComputeEffectiveClangTriple(Args, InputType);
132+
}
133+
}

clang/lib/Driver/ToolChains/HLSL.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===--- HLSL.h - 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+
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HLSL_H
10+
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HLSL_H
11+
12+
#include "clang/Driver/ToolChain.h"
13+
14+
namespace clang {
15+
namespace driver {
16+
17+
namespace toolchains {
18+
19+
class LLVM_LIBRARY_VISIBILITY HLSLToolChain : public ToolChain {
20+
public:
21+
HLSLToolChain(const Driver &D, const llvm::Triple &Triple,
22+
const llvm::opt::ArgList &Args);
23+
bool isPICDefault() const override { return false; }
24+
bool isPIEDefault(const llvm::opt::ArgList &Args) const override {
25+
return false;
26+
}
27+
bool isPICDefaultForced() const override { return false; }
28+
29+
std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
30+
types::ID InputType) const override;
31+
};
32+
33+
} // end namespace toolchains
34+
} // end namespace driver
35+
} // end namespace clang
36+
37+
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HLSL_H

clang/lib/Driver/Types.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) {
332332
.Case("c++m", TY_CXXModule)
333333
.Case("cppm", TY_CXXModule)
334334
.Case("cxxm", TY_CXXModule)
335+
.Case("hlsl", TY_HLSL)
335336
.Default(TY_INVALID);
336337
}
337338

0 commit comments

Comments
 (0)