Skip to content

Commit 6510acb

Browse files
author
Xiang Li
committed
Add -T for hlsl compiler.
1 parent 3e8c436 commit 6510acb

File tree

12 files changed

+290
-2
lines changed

12 files changed

+290
-2
lines changed

clang/include/clang/Basic/DiagnosticDriverKinds.td

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

657+
def err_drv_invalid_directx_shader_module : Error<
658+
"invalid profile : %0">;
659+
657660
}

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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ enum ClangFlags {
3636
FC1Option = (1 << 15),
3737
FlangOnlyOption = (1 << 16),
3838
Ignored = (1 << 17),
39+
DXCOption = (1 << 18),
3940
};
4041

4142
enum ID {

clang/include/clang/Driver/Options.td

Lines changed: 21 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

@@ -6641,3 +6645,20 @@ def _SLASH_Ze : CLFlag<"Ze">;
66416645
def _SLASH_Zg : CLFlag<"Zg">;
66426646
def _SLASH_ZI : CLFlag<"ZI">;
66436647
def _SLASH_ZW : CLJoined<"ZW">;
6648+
6649+
//===----------------------------------------------------------------------===//
6650+
// clang-dxc Options
6651+
//===----------------------------------------------------------------------===//
6652+
6653+
def dxc_Group : OptionGroup<"<clang-dxc options>">, Flags<[DXCOption]>,
6654+
HelpText<"DXC.EXE COMPATIBILITY OPTIONS">;
6655+
6656+
class DXCJoinedOrSeparate<string name> : Option<["/", "-"], name,
6657+
KIND_JOINED_OR_SEPARATE>, Group<dxc_Group>, Flags<[DXCOption, NoXarchOption]>;
6658+
6659+
def dxc_help : Option<["/", "-", "--"], "help", KIND_JOINED>,
6660+
Group<dxc_Group>, Flags<[DXCOption, NoXarchOption]>, Alias<help>,
6661+
HelpText<"Display available options">;
6662+
6663+
def target_profile : DXCJoinedOrSeparate<"T">, MetaVarName<"<profile>">,
6664+
HelpText<"Set target profile. \n\t<profile>: ps_6_0, ps_6_1, ps_6_2, ps_6_3, ps_6_4, ps_6_5, ps_6_6, ps_6_7, \n\t\t vs_6_0, vs_6_1, vs_6_2, vs_6_3, vs_6_4, vs_6_5, vs_6_6, vs_6_7, \n\t\t gs_6_0, gs_6_1, gs_6_2, gs_6_3, gs_6_4, gs_6_5, gs_6_6, gs_6_7, \n\t\t hs_6_0, hs_6_1, hs_6_2, hs_6_3, hs_6_4, hs_6_5, hs_6_6, hs_6_7, \n\t\t ds_6_0, ds_6_1, ds_6_2, ds_6_3, ds_6_4, ds_6_5, ds_6_6, ds_6_7, \n\t\t cs_6_0, cs_6_1, cs_6_2, cs_6_3, cs_6_4, cs_6_5, cs_6_6, cs_6_7, \n\t\t lib_6_1, lib_6_2, lib_6_3, lib_6_4, lib_6_5, lib_6_6, lib_6_7, \n\t\t ms_6_5, ms_6_6, ms_6_7, \n\t\t as_6_5, as_6_6, as_6_7, \n\t\t ">;

clang/lib/Driver/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ add_clang_library(clangDriver
4949
ToolChains/Cuda.cpp
5050
ToolChains/Darwin.cpp
5151
ToolChains/DragonFly.cpp
52+
ToolChains/DirectX.cpp
5253
ToolChains/Flang.cpp
5354
ToolChains/FreeBSD.cpp
5455
ToolChains/Fuchsia.cpp

clang/lib/Driver/Driver.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "ToolChains/Cuda.h"
2121
#include "ToolChains/Darwin.h"
2222
#include "ToolChains/DragonFly.h"
23+
#include "ToolChains/DirectX.h"
2324
#include "ToolChains/FreeBSD.h"
2425
#include "ToolChains/Fuchsia.h"
2526
#include "ToolChains/Gnu.h"
@@ -231,6 +232,7 @@ void Driver::setDriverMode(StringRef Value) {
231232
.Case("cpp", CPPMode)
232233
.Case("cl", CLMode)
233234
.Case("flang", FlangMode)
235+
.Case("dxc", DXCMode)
234236
.Default(None))
235237
Mode = *M;
236238
else
@@ -5726,6 +5728,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
57265728
case llvm::Triple::spirv64:
57275729
TC = std::make_unique<toolchains::SPIRVToolChain>(*this, Target, Args);
57285730
break;
5731+
case llvm::Triple::dxil:
5732+
TC = std::make_unique<toolchains::DirectXToolChain>(*this, Target, Args);
5733+
break;
57295734
default:
57305735
if (Target.getVendor() == llvm::Triple::Myriad)
57315736
TC = std::make_unique<toolchains::MyriadToolChain>(*this, Target,
@@ -5895,7 +5900,11 @@ Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const {
58955900
} else {
58965901
ExcludedFlagsBitmask |= options::CLOption;
58975902
}
5898-
5903+
if (IsDXCMode()) {
5904+
// TODO: Include DXC and Core options.
5905+
} else {
5906+
ExcludedFlagsBitmask |= options::DXCOption;
5907+
}
58995908
return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask);
59005909
}
59015910

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) {
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
//===--- DirectX.cpp - DirectX 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 "DirectX.h"
10+
#include "llvm/ADT/Triple.h"
11+
#include "CommonArgs.h"
12+
#include "clang/Driver/DriverDiagnostic.h"
13+
14+
using namespace clang::driver;
15+
using namespace clang::driver::tools;
16+
using namespace clang::driver::toolchains;
17+
using namespace clang;
18+
using namespace llvm::opt;
19+
using namespace llvm;
20+
21+
namespace {
22+
std::string tryParseProfile(StringRef profile) {
23+
// [ps|vs|gs|hs|ds|cs|ms|as]_[major]_[minor]
24+
Triple::EnvironmentType kind;
25+
switch (profile[0]) {
26+
case 'p':
27+
kind = Triple::EnvironmentType::Pixel;
28+
break;
29+
case 'v':
30+
kind = Triple::EnvironmentType::Vertex;
31+
break;
32+
case 'g':
33+
kind = Triple::EnvironmentType::Geometry;
34+
break;
35+
case 'h':
36+
kind = Triple::EnvironmentType::Hull;
37+
break;
38+
case 'd':
39+
kind = Triple::EnvironmentType::Domain;
40+
break;
41+
case 'c':
42+
kind = Triple::EnvironmentType::Compute;
43+
break;
44+
case 'l':
45+
kind = Triple::EnvironmentType::Library;
46+
break;
47+
case 'm':
48+
kind = Triple::EnvironmentType::Mesh;
49+
break;
50+
case 'a':
51+
kind = Triple::EnvironmentType::Amplification;
52+
break;
53+
default:
54+
return "";
55+
}
56+
unsigned Idx = 3;
57+
if (kind != Triple::EnvironmentType::Library) {
58+
if (profile[1] != 's' || profile[2] != '_')
59+
return "";
60+
} else {
61+
if (profile[1] != 'i' || profile[2] != 'b' || profile[3] != '_')
62+
return "";
63+
Idx = 4;
64+
}
65+
Triple::OSType::ShaderModel;
66+
unsigned Major;
67+
switch (profile[Idx++]) {
68+
case '4':
69+
Major = 4;
70+
break;
71+
case '5':
72+
Major = 5;
73+
break;
74+
case '6':
75+
Major = 6;
76+
break;
77+
default:
78+
return "";
79+
}
80+
if (profile[Idx++] != '_')
81+
return "";
82+
83+
static const unsigned kOfflineMinor = 0xF;
84+
unsigned Minor;
85+
switch (profile[Idx++]) {
86+
case '0':
87+
Minor = 0;
88+
break;
89+
case '1':
90+
Minor = 1;
91+
break;
92+
case '2':
93+
if (Major == 6) {
94+
Minor = 2;
95+
break;
96+
} else
97+
return "";
98+
case '3':
99+
if (Major == 6) {
100+
Minor = 3;
101+
break;
102+
} else
103+
return "";
104+
case '4':
105+
if (Major == 6) {
106+
Minor = 4;
107+
break;
108+
} else
109+
return "";
110+
case '5':
111+
if (Major == 6) {
112+
Minor = 5;
113+
break;
114+
} else
115+
"";
116+
case '6':
117+
if (Major == 6) {
118+
Minor = 6;
119+
break;
120+
} else
121+
return "";
122+
case '7':
123+
if (Major == 6) {
124+
Minor = 7;
125+
break;
126+
} else
127+
return "";
128+
case 'x':
129+
if (kind == Triple::EnvironmentType::Library && Major == 6) {
130+
Minor = kOfflineMinor;
131+
break;
132+
} else
133+
return "";
134+
default:
135+
return "";
136+
}
137+
if (profile.size() != Idx && profile[Idx++] != 0)
138+
return "";
139+
// dxil-unknown-shadermodel-hull
140+
llvm::Triple T(Twine("dxil"), Twine("unknown"),
141+
Twine("shadermodel")
142+
.concat(Twine(Major))
143+
.concat(".")
144+
.concat(Twine(Minor)),
145+
Triple::getEnvironmentTypeName(kind));
146+
return T.getTriple();
147+
}
148+
149+
} // namespace
150+
151+
/// DirectX Toolchain
152+
DirectXToolChain::DirectXToolChain(const Driver &D, const llvm::Triple &Triple,
153+
const ArgList &Args)
154+
: ToolChain(D, Triple, Args) {}
155+
156+
std::string
157+
DirectXToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
158+
types::ID InputType) const {
159+
if (Arg *A = Args.getLastArg(options::OPT_target_profile)) {
160+
StringRef profile = A->getValue();
161+
std::string triple = tryParseProfile(profile);
162+
if (triple == "") {
163+
getDriver().Diag(diag::err_drv_invalid_directx_shader_module) << profile;
164+
triple = ToolChain::ComputeEffectiveClangTriple(Args, InputType);
165+
}
166+
return triple;
167+
} else {
168+
return ToolChain::ComputeEffectiveClangTriple(Args, InputType);
169+
}
170+
}
171+
172+
llvm::opt::DerivedArgList *
173+
DirectXToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
174+
StringRef BoundArch,
175+
Action::OffloadKind OFK) const {
176+
DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
177+
const OptTable &Opts = getDriver().getOpts();
178+
179+
for (Arg *A : Args) {
180+
if (A->getOption().matches(options::OPT_T)) {
181+
// Convert OPT_T to OPT_target_profile for dxc.
182+
StringRef ProfileStr = A->getValue();
183+
DAL->AddJoinedArg(A, Opts.getOption(options::OPT_target_profile),
184+
ProfileStr);
185+
} else {
186+
// HIP Toolchain translates input args by itself.
187+
DAL->append(A);
188+
}
189+
}
190+
191+
return DAL;
192+
}

clang/lib/Driver/ToolChains/DirectX.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===--- DirectX.h - DirectX 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+
#pragma once
10+
11+
#include "clang/Driver/ToolChain.h"
12+
13+
namespace clang {
14+
namespace driver {
15+
16+
namespace toolchains {
17+
18+
class LLVM_LIBRARY_VISIBILITY DirectXToolChain : public ToolChain {
19+
public:
20+
DirectXToolChain(const Driver &D, const llvm::Triple &Triple,
21+
const llvm::opt::ArgList &Args);
22+
bool isPICDefault() const override { return false; }
23+
bool isPIEDefault(const llvm::opt::ArgList &Args) const override {
24+
return false;
25+
}
26+
bool isPICDefaultForced() const override { return false; }
27+
llvm::opt::DerivedArgList *
28+
TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
29+
Action::OffloadKind DeviceOffloadKind) const override;
30+
std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
31+
types::ID InputType) const override;
32+
};
33+
34+
} // end namespace toolchains
35+
} // end namespace driver
36+
} // end namespace clang
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_dxc -Tvs_6_0 -xhlsl --target=dxil -o - %s 2>&1 | FileCheck %s --check-prefix=VS60
2+
// VS60:target triple = "dxil-unknown-shadermodel6.0-vertex"
3+
// RUN: %clang_dxc -Ths_6_1 -xhlsl --target=dxil -o - %s 2>&1 | FileCheck %s --check-prefix=HS61
4+
// HS61:target triple = "dxil-unknown-shadermodel6.1-hull"
5+
6+
// RUN: %clang_dxc -Tps_6_1 -xhlsl --target=dxil -o - %s 2>&1 | FileCheck %s --check-prefix=PS61
7+
// PS61:target triple = "dxil-unknown-shadermodel6.1-pixel"
8+
// RUN: %clang_dxc -Tlib_6_3 -xhlsl --target=dxil -o - %s 2>&1 | FileCheck %s --check-prefix=LIB63
9+
// LIB63:target triple = "dxil-unknown-shadermodel6.3-library"
10+
11+
// RUN: %clang_dxc -### -Tps_3_1 -xhlsl --target=dxil -o - %s 2>&1 | FileCheck %s --check-prefix=INVALID
12+
// INVALID:invalid profile : ps_3_1

0 commit comments

Comments
 (0)