[clang] d394f9f - Add HLSL Language Option and Preprocessor
Chris Bieneman via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 28 14:16:35 PDT 2022
Author: Chris Bieneman
Date: 2022-03-28T16:16:17-05:00
New Revision: d394f9f8970d758cb39151328dd3040ba7f414ae
URL: https://github.com/llvm/llvm-project/commit/d394f9f8970d758cb39151328dd3040ba7f414ae
DIFF: https://github.com/llvm/llvm-project/commit/d394f9f8970d758cb39151328dd3040ba7f414ae.diff
LOG: Add HLSL Language Option and Preprocessor
Bringing in HLSL as a language as well as language options for each of
the HLSL language standards.
While the HLSL language is unimplemented, this patch adds the
HLSL-specific preprocessor defines which enables testing of the command
line options through the driver.
Reviewed By: pete, rnk
Differential Revision: https://reviews.llvm.org/D122087
Added:
clang/test/Preprocessor/predefined-macros-hlsl.c
Modified:
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Basic/LangStandard.h
clang/include/clang/Basic/LangStandards.def
clang/include/clang/Driver/Types.def
clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/lib/Frontend/FrontendActions.cpp
clang/lib/Frontend/InitPreprocessor.cpp
clang/test/Driver/lit.local.cfg
clang/test/lit.cfg.py
llvm/lib/Support/Triple.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 05b9691142998..d5f8dd9ab5c04 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -251,6 +251,9 @@ LANGOPT(OpenMPNoThreadState , 1, 0, "Assume that no thread in a parallel region
LANGOPT(OpenMPOffloadMandatory , 1, 0, "Assert that offloading is mandatory and do not create a host fallback.")
LANGOPT(RenderScript , 1, 0, "RenderScript")
+LANGOPT(HLSL, 1, 0, "HLSL")
+ENUM_LANGOPT(HLSLVersion, HLSLLangStd, 16, HLSL_Unset, "HLSL Version")
+
LANGOPT(CUDAIsDevice , 1, 0, "compiling for CUDA device")
LANGOPT(CUDAAllowVariadicFunctions, 1, 0, "allowing variadic functions in CUDA device code")
LANGOPT(CUDAHostDeviceConstexpr, 1, 1, "treating unattributed constexpr functions as __host__ __device__")
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 96fd6049efeca..f5a2fd8461674 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -53,6 +53,26 @@ class LangOptionsBase {
/// members used to implement virtual inheritance.
enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable };
+/// Shader programs run in specific pipeline stages.
+enum class ShaderStage {
+ Pixel = 0,
+ Vertex,
+ Geometry,
+ Hull,
+ Domain,
+ Compute,
+ Library,
+ RayGeneration,
+ Intersection,
+ AnyHit,
+ ClosestHit,
+ Miss,
+ Callable,
+ Mesh,
+ Amplification,
+ Invalid,
+};
+
/// Keeps track of the various options that can be
/// enabled, which controls the dialect of C or C++ that is accepted.
class LangOptions : public LangOptionsBase {
@@ -140,6 +160,16 @@ class LangOptions : public LangOptionsBase {
SYCL_Default = SYCL_2020
};
+ enum HLSLLangStd {
+ HLSL_Unset = 0,
+ HLSL_2015 = 2015,
+ HLSL_2016 = 2016,
+ HLSL_2017 = 2017,
+ HLSL_2018 = 2018,
+ HLSL_2021 = 2021,
+ HLSL_202x = 2029,
+ };
+
/// Clang versions with
diff erent platform ABI conformance.
enum class ClangABI {
/// Attempt to be ABI-compatible with code generated by Clang 3.8.x
diff --git a/clang/include/clang/Basic/LangStandard.h b/clang/include/clang/Basic/LangStandard.h
index b0785409628c4..fdfd2e7773a87 100644
--- a/clang/include/clang/Basic/LangStandard.h
+++ b/clang/include/clang/Basic/LangStandard.h
@@ -36,6 +36,7 @@ enum class Language : uint8_t {
CUDA,
RenderScript,
HIP,
+ HLSL,
///@}
};
@@ -55,7 +56,8 @@ enum LangFeatures {
GNUMode = (1 << 12),
HexFloat = (1 << 13),
ImplicitInt = (1 << 14),
- OpenCL = (1 << 15)
+ OpenCL = (1 << 15),
+ HLSL = (1 << 16)
};
/// LangStandard - Information about the properties of a particular language
diff --git a/clang/include/clang/Basic/LangStandards.def b/clang/include/clang/Basic/LangStandards.def
index 6056cfd65bbbf..d0e777b23b94f 100644
--- a/clang/include/clang/Basic/LangStandards.def
+++ b/clang/include/clang/Basic/LangStandards.def
@@ -209,6 +209,36 @@ LANGSTANDARD(cuda, "cuda", CUDA, "NVIDIA CUDA(tm)",
LANGSTANDARD(hip, "hip", HIP, "HIP",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs)
+// HLSL
+LANGSTANDARD(hlsl, "hlsl",
+ HLSL, "High Level Shader Language",
+ LineComment | HLSL | CPlusPlus )
+
+LANGSTANDARD(hlsl2015, "hlsl2015",
+ HLSL, "High Level Shader Language 2015",
+ LineComment | HLSL | CPlusPlus )
+
+LANGSTANDARD(hlsl2016, "hlsl2016",
+ HLSL, "High Level Shader Language 2016",
+ LineComment | HLSL | CPlusPlus )
+
+LANGSTANDARD(hlsl2017, "hlsl2017",
+ HLSL, "High Level Shader Language 2017",
+ LineComment | HLSL | CPlusPlus )
+
+LANGSTANDARD(hlsl2018, "hlsl2018",
+ HLSL, "High Level Shader Language 2018",
+ LineComment | HLSL | CPlusPlus )
+
+LANGSTANDARD(hlsl2021, "hlsl2021",
+ HLSL, "High Level Shader Language 2021",
+ LineComment | HLSL | CPlusPlus )
+
+LANGSTANDARD(hlsl202x, "hlsl202x",
+ HLSL, "High Level Shader Language 202x",
+ LineComment | HLSL | CPlusPlus | CPlusPlus11)
+
+
#undef LANGSTANDARD
#undef LANGSTANDARD_ALIAS
#undef LANGSTANDARD_ALIAS_DEPR
diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def
index 7e38417a84a66..94041b183add2 100644
--- a/clang/include/clang/Driver/Types.def
+++ b/clang/include/clang/Driver/Types.def
@@ -54,6 +54,7 @@ TYPE("objective-c++-cpp-output", PP_ObjCXX, INVALID, "mii", phases
TYPE("objc++-cpp-output", PP_ObjCXX_Alias, INVALID, "mii", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("objective-c++", ObjCXX, PP_ObjCXX, "mm", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("renderscript", RenderScript, PP_C, "rs", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("hlsl", HLSL, PP_CXX, "hlsl", phases::Preprocess, phases::Compile, phases::Backend)
// C family input files to precompile.
TYPE("c-header-cpp-output", PP_CHeader, INVALID, "i", phases::Precompile)
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index af44fce0cbc97..54276f6cf1de1 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -169,6 +169,7 @@ StringRef getLanguageName(const LangOptions &LangOpts) {
case Language::CUDA:
case Language::RenderScript:
case Language::HIP:
+ case Language::HLSL:
// Languages that the frontend cannot parse and compile
case Language::Unknown:
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index b222119889522..f8fd3a2900237 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2623,6 +2623,9 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts,
case Language::LLVM_IR:
Lang = "ir";
break;
+ case Language::HLSL:
+ Lang = "hlsl";
+ break;
}
GenerateArg(Args, OPT_x,
@@ -2809,6 +2812,7 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
.Case("objective-c", Language::ObjC)
.Case("objective-c++", Language::ObjCXX)
.Case("renderscript", Language::RenderScript)
+ .Case("hlsl", Language::HLSL)
.Default(Language::Unknown);
// "objc[++]-cpp-output" is an acceptable synonym for
@@ -3220,6 +3224,9 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
case Language::HIP:
LangStd = LangStandard::lang_hip;
break;
+ case Language::HLSL:
+ LangStd = LangStandard::lang_hlsl2021;
+ break;
}
}
@@ -3241,6 +3248,8 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
Opts.HexFloats = Std.hasHexFloats();
Opts.ImplicitInt = Std.hasImplicitInt();
+ Opts.HLSL = IK.getLanguage() == Language::HLSL;
+
// Set OpenCL Version.
Opts.OpenCL = Std.isOpenCL();
if (LangStd == LangStandard::lang_opencl10)
@@ -3257,6 +3266,18 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
Opts.OpenCLCPlusPlusVersion = 100;
else if (LangStd == LangStandard::lang_openclcpp2021)
Opts.OpenCLCPlusPlusVersion = 202100;
+ else if (LangStd == LangStandard::lang_hlsl2015)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2015;
+ else if (LangStd == LangStandard::lang_hlsl2016)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2016;
+ else if (LangStd == LangStandard::lang_hlsl2017)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2017;
+ else if (LangStd == LangStandard::lang_hlsl2018)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2018;
+ else if (LangStd == LangStandard::lang_hlsl2021)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2021;
+ else if (LangStd == LangStandard::lang_hlsl202x)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_202x;
// OpenCL has some additional defaults.
if (Opts.OpenCL) {
@@ -3341,6 +3362,9 @@ static bool IsInputCompatibleWithStandard(InputKind IK,
// FIXME: The -std= value is not ignored; it affects the tokenization
// and preprocessing rules if we're preprocessing this asm input.
return true;
+
+ case Language::HLSL:
+ return S.getLanguage() == Language::HLSL;
}
llvm_unreachable("unexpected input language");
@@ -3373,6 +3397,9 @@ static StringRef GetInputKindName(InputKind IK) {
case Language::LLVM_IR:
return "LLVM IR";
+ case Language::HLSL:
+ return "HLSL";
+
case Language::Unknown:
break;
}
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 2cd209640aaf4..e219be35cfea8 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -1078,6 +1078,7 @@ void PrintPreambleAction::ExecuteAction() {
case Language::OpenCLCXX:
case Language::CUDA:
case Language::HIP:
+ case Language::HLSL:
break;
case Language::Unknown:
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 9d7a429bda184..89e9cb0250043 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -371,6 +371,52 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
const LangOptions &LangOpts,
const FrontendOptions &FEOpts,
MacroBuilder &Builder) {
+ if (LangOpts.HLSL) {
+ Builder.defineMacro("__hlsl_clang");
+ // HLSL Version
+ Builder.defineMacro("__HLSL_VERSION",
+ Twine((unsigned)LangOpts.getHLSLVersion()));
+
+ // Shader target information
+ // "enums" for shader stages
+ Builder.defineMacro("__SHADER_STAGE_VERTEX",
+ Twine((uint32_t)ShaderStage::Vertex));
+ Builder.defineMacro("__SHADER_STAGE_PIXEL",
+ Twine((uint32_t)ShaderStage::Pixel));
+ Builder.defineMacro("__SHADER_STAGE_GEOMETRY",
+ Twine((uint32_t)ShaderStage::Geometry));
+ Builder.defineMacro("__SHADER_STAGE_HULL",
+ Twine((uint32_t)ShaderStage::Hull));
+ Builder.defineMacro("__SHADER_STAGE_DOMAIN",
+ Twine((uint32_t)ShaderStage::Domain));
+ Builder.defineMacro("__SHADER_STAGE_COMPUTE",
+ Twine((uint32_t)ShaderStage::Compute));
+ Builder.defineMacro("__SHADER_STAGE_AMPLIFICATION",
+ Twine((uint32_t)ShaderStage::Amplification));
+ Builder.defineMacro("__SHADER_STAGE_MESH",
+ Twine((uint32_t)ShaderStage::Mesh));
+ Builder.defineMacro("__SHADER_STAGE_LIBRARY",
+ Twine((uint32_t)ShaderStage::Library));
+ // The current shader stage itself
+ uint32_t StageInteger = StageInteger =
+ (uint32_t)TI.getTriple().getEnvironment() -
+ (uint32_t)llvm::Triple::Pixel;
+ // TODO: When we add raytracing support we can clean this up
+ if (TI.getTriple().getEnvironment() == llvm::Triple::Mesh)
+ StageInteger = (uint32_t)ShaderStage::Mesh;
+ else if (TI.getTriple().getEnvironment() == llvm::Triple::Amplification)
+ StageInteger = (uint32_t)ShaderStage::Amplification;
+
+ Builder.defineMacro("__SHADER_TARGET_STAGE", Twine(StageInteger));
+ // Add target versions
+ if (TI.getTriple().getOS() == llvm::Triple::ShaderModel) {
+ VersionTuple Version = TI.getTriple().getOSVersion();
+ Builder.defineMacro("__SHADER_TARGET_MAJOR", Twine(Version.getMajor()));
+ unsigned Minor = Version.getMinor() ? *Version.getMinor() : 0;
+ Builder.defineMacro("__SHADER_TARGET_MINOR", Twine(Minor));
+ }
+ return;
+ }
// C++ [cpp.predefined]p1:
// The following macro names shall be defined by the implementation:
diff --git a/clang/test/Driver/lit.local.cfg b/clang/test/Driver/lit.local.cfg
index fe5d67a0f45bf..671d9a4b18735 100644
--- a/clang/test/Driver/lit.local.cfg
+++ b/clang/test/Driver/lit.local.cfg
@@ -1,5 +1,5 @@
config.suffixes = ['.c', '.cpp', '.h', '.m', '.mm', '.S', '.s', '.f90', '.F90', '.f95',
- '.cu', '.rs', '.cl', '.clcpp', '.hip']
+ '.cu', '.rs', '.cl', '.clcpp', '.hip', '.hlsl']
config.substitutions = list(config.substitutions)
config.substitutions.insert(0,
('%clang_cc1',
diff --git a/clang/test/Preprocessor/predefined-macros-hlsl.c b/clang/test/Preprocessor/predefined-macros-hlsl.c
new file mode 100644
index 0000000000000..2e2d928f54110
--- /dev/null
+++ b/clang/test/Preprocessor/predefined-macros-hlsl.c
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -triple dxil-pc-shadermodel6.0-amplification | FileCheck -match-full-lines %s --check-prefixes=CHECK,AMPLIFICATION
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -triple dxil-pc-shadermodel6.0-compute | FileCheck -match-full-lines %s --check-prefixes=CHECK,COMPUTE
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -triple dxil-pc-shadermodel6.0-domain | FileCheck -match-full-lines %s --check-prefixes=CHECK,DOMAIN
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -triple dxil-pc-shadermodel6.0-geometry | FileCheck -match-full-lines %s --check-prefixes=CHECK,GEOMETRY
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -triple dxil-pc-shadermodel6.0-hull | FileCheck -match-full-lines %s --check-prefixes=CHECK,HULL
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -triple dxil-pc-shadermodel6.0-library | FileCheck -match-full-lines %s --check-prefixes=CHECK,LIBRARY
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -triple dxil-pc-shadermodel6.0-mesh | FileCheck -match-full-lines %s --check-prefixes=CHECK,MESH
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -triple dxil-pc-shadermodel6.0-pixel | FileCheck -match-full-lines %s --check-prefixes=CHECK,PIXEL
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -triple dxil-pc-shadermodel6.0-vertex | FileCheck -match-full-lines %s --check-prefixes=CHECK,VERTEX
+
+// CHECK: #define __HLSL_VERSION 2021
+// CHECK: #define __SHADER_STAGE_AMPLIFICATION 14
+// CHECK: #define __SHADER_STAGE_COMPUTE 5
+// CHECK: #define __SHADER_STAGE_DOMAIN 4
+// CHECK: #define __SHADER_STAGE_GEOMETRY 2
+// CHECK: #define __SHADER_STAGE_HULL 3
+// CHECK: #define __SHADER_STAGE_LIBRARY 6
+// CHECK: #define __SHADER_STAGE_MESH 13
+// CHECK: #define __SHADER_STAGE_PIXEL 0
+// CHECK: #define __SHADER_STAGE_VERTEX 1
+
+// AMPLIFICATION: #define __SHADER_TARGET_STAGE 14
+// COMPUTE: #define __SHADER_TARGET_STAGE 5
+// DOMAIN: #define __SHADER_TARGET_STAGE 4
+// GEOMETRY: #define __SHADER_TARGET_STAGE 2
+// HULL: #define __SHADER_TARGET_STAGE 3
+// LIBRARY: #define __SHADER_TARGET_STAGE 6
+// MESH: #define __SHADER_TARGET_STAGE 13
+// PIXEL: #define __SHADER_TARGET_STAGE 0
+// VERTEX: #define __SHADER_TARGET_STAGE 1
+
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -std=hlsl2015 | FileCheck -match-full-lines %s --check-prefixes=STD2015
+// STD2015: #define __HLSL_VERSION 2015
+
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -std=hlsl2016 | FileCheck -match-full-lines %s --check-prefixes=STD2016
+// STD2016: #define __HLSL_VERSION 2016
+
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -std=hlsl2017 | FileCheck -match-full-lines %s --check-prefixes=STD2017
+// STD2017: #define __HLSL_VERSION 2017
+
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -std=hlsl2018 | FileCheck -match-full-lines %s --check-prefixes=STD2018
+// STD2018: #define __HLSL_VERSION 2018
+
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -std=hlsl2021 | FileCheck -match-full-lines %s --check-prefixes=STD2021
+// STD2021: #define __HLSL_VERSION 2021
+
+// RUN: %clang_cc1 %s -E -dM -o - -x hlsl -std=hlsl202x | FileCheck -match-full-lines %s --check-prefixes=STD202x
+// STD202x: #define __HLSL_VERSION 2029
diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py
index 27d8bbad99521..1e6165caaedc4 100644
--- a/clang/test/lit.cfg.py
+++ b/clang/test/lit.cfg.py
@@ -25,7 +25,7 @@
config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
# suffixes: A list of file extensions to treat as test files.
-config.suffixes = ['.c', '.cpp', '.i', '.cppm', '.m', '.mm', '.cu', '.hip',
+config.suffixes = ['.c', '.cpp', '.i', '.cppm', '.m', '.mm', '.cu', '.hip', '.hlsl',
'.ll', '.cl', '.clcpp', '.s', '.S', '.modulemap', '.test', '.rs', '.ifs', '.rc']
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp
index 6d954da2461d3..2cde1c69b2f41 100644
--- a/llvm/lib/Support/Triple.cpp
+++ b/llvm/lib/Support/Triple.cpp
@@ -1888,3 +1888,17 @@ VersionTuple Triple::getCanonicalVersionForOS(OSType OSKind,
return Version;
}
}
+
+// HLSL triple environment orders are relied on in the front end
+static_assert(Triple::Vertex - Triple::Pixel == 1,
+ "incorrect HLSL stage order");
+static_assert(Triple::Geometry - Triple::Pixel == 2,
+ "incorrect HLSL stage order");
+static_assert(Triple::Hull - Triple::Pixel == 3,
+ "incorrect HLSL stage order");
+static_assert(Triple::Domain - Triple::Pixel == 4,
+ "incorrect HLSL stage order");
+static_assert(Triple::Compute - Triple::Pixel == 5,
+ "incorrect HLSL stage order");
+static_assert(Triple::Library - Triple::Pixel == 6,
+ "incorrect HLSL stage order");
More information about the cfe-commits
mailing list