Skip to content

Commit 68182e6

Browse files
committed
Use Module field of DXILOpBuilder to find target SM version and Shader
Kind in createDXILOpCall() instead of computing them in its callers and passing them as arguments.
1 parent b21befa commit 68182e6

File tree

6 files changed

+202
-151
lines changed

6 files changed

+202
-151
lines changed

llvm/lib/Target/DirectX/DXIL.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,10 @@ def mesh : ShaderStage;
237237
def node : ShaderStage;
238238
def raygeneration : ShaderStage;
239239
def intersection : ShaderStage;
240+
def anyhit : ShaderStage;
241+
def closesthit : ShaderStage;
242+
def callable : ShaderStage;
243+
def miss : ShaderStage;
240244

241245
// Primitive predicate
242246
class Pred;

llvm/lib/Target/DirectX/DXILOpBuilder.cpp

Lines changed: 76 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "llvm/IR/Module.h"
1616
#include "llvm/Support/DXILABI.h"
1717
#include "llvm/Support/ErrorHandling.h"
18+
#include "llvm/TargetParser/Triple.h"
1819

1920
using namespace llvm;
2021
using namespace llvm::dxil;
@@ -24,9 +25,7 @@ constexpr StringLiteral DXILOpNamePrefix = "dx.op.";
2425
// Include DXIL Operation data and corresponding access functions
2526
// generated by the TableGen backend DXILEmitter.
2627
#define DXIL_OP_OPERATION_TABLE
27-
#define SHADER_KIND_ENUM
2828
#include "DXILOperation.inc"
29-
#undef SHADER_KIND_ENUM
3029
#undef DXIL_OP_OPERATION_TABLE
3130

3231
static OverloadKind getOverloadKind(Type *Ty) {
@@ -162,6 +161,45 @@ static Type *getTypeFromParameterKind(ParameterKind Kind, Type *OverloadTy) {
162161
return nullptr;
163162
}
164163

164+
static ShaderKind getShaderKindEnum(Triple::EnvironmentType EnvType) {
165+
switch (EnvType) {
166+
case Triple::Pixel:
167+
return ShaderKind::pixel;
168+
case Triple::Vertex:
169+
return ShaderKind::vertex;
170+
case Triple::Geometry:
171+
return ShaderKind::geometry;
172+
case Triple::Hull:
173+
return ShaderKind::hull;
174+
case Triple::Domain:
175+
return ShaderKind::domain;
176+
case Triple::Compute:
177+
return ShaderKind::compute;
178+
case Triple::Library:
179+
return ShaderKind::library;
180+
case Triple::RayGeneration:
181+
return ShaderKind::raygeneration;
182+
case Triple::Intersection:
183+
return ShaderKind::intersection;
184+
case Triple::AnyHit:
185+
return ShaderKind::anyhit;
186+
case Triple::ClosestHit:
187+
return ShaderKind::closesthit;
188+
case Triple::Miss:
189+
return ShaderKind::miss;
190+
case Triple::Callable:
191+
return ShaderKind::callable;
192+
case Triple::Mesh:
193+
return ShaderKind::mesh;
194+
case Triple::Amplification:
195+
return ShaderKind::amplification;
196+
default:
197+
break;
198+
}
199+
llvm_unreachable(
200+
"Shader Kind Not Found - Invalid DXIL Environment Specified");
201+
}
202+
165203
/// Construct DXIL function type. This is the type of a function with
166204
/// the following prototype
167205
/// OverloadType dx.op.<opclass>.<return-type>(int opcode, <param types>)
@@ -213,11 +251,23 @@ static int getValidConstraintIndex(const OpCodeProperty *Prop,
213251
namespace llvm {
214252
namespace dxil {
215253

216-
CallInst *DXILOpBuilder::createDXILOpCall(dxil::OpCode OpCode,
217-
VersionTuple SMVer,
218-
StringRef StageKind, Type *ReturnTy,
254+
CallInst *DXILOpBuilder::createDXILOpCall(dxil::OpCode OpCode, Type *ReturnTy,
219255
Type *OverloadTy,
220256
SmallVector<Value *> Args) {
257+
258+
std::string TTStr = M.getTargetTriple();
259+
// No extra checks need be performed to verify that the Triple is
260+
// well-formed or the target is supported since these checks would have
261+
// been done at the time the module M is constructed in the earlier stages of
262+
// compilation.
263+
auto Major = Triple(TTStr).getOSVersion().getMajor();
264+
auto MinorOrErr = Triple(TTStr).getOSVersion().getMinor();
265+
uint32_t Minor = MinorOrErr.has_value() ? *MinorOrErr : 0;
266+
VersionTuple SMVer(Major, Minor);
267+
// Get Shader Stage Kind
268+
Triple::EnvironmentType ShaderEnv = Triple(TTStr).getEnvironment();
269+
auto ShaderEnvStr = Triple(TTStr).getEnvironmentName();
270+
221271
const OpCodeProperty *Prop = getOpCodeProperty(OpCode);
222272
int Index = getValidConstraintIndex(Prop, SMVer);
223273
uint16_t ValidTyMask = Prop->Constraints[Index].ValidTys;
@@ -234,10 +284,18 @@ CallInst *DXILOpBuilder::createDXILOpCall(dxil::OpCode OpCode,
234284
/* gen_crash_diag=*/false);
235285
}
236286

287+
// Ensure Environment type is known
288+
if (ShaderEnv == Triple::UnknownEnvironment) {
289+
report_fatal_error(
290+
StringRef(SMVer.getAsString().append(
291+
": Unknown Compilation Target Shader Stage specified ")),
292+
/*gen_crash_diag*/ false);
293+
}
294+
237295
// Perform necessary checks to ensure Opcode is valid in the targeted shader
238296
// kind
239297
uint16_t ValidShaderKindMask = Prop->Constraints[Index].ValidShaderKinds;
240-
ShaderKind ModuleStagekind = getShaderkKindEnum(StageKind);
298+
enum ShaderKind ModuleStagekind = getShaderKindEnum(ShaderEnv);
241299

242300
// Ensure valid shader stage constraints are specified
243301
if (ValidShaderKindMask == ShaderKind::Unknown) {
@@ -260,7 +318,7 @@ CallInst *DXILOpBuilder::createDXILOpCall(dxil::OpCode OpCode,
260318
// Verify the target shader stage is valid for the DXIL operation
261319
if (!(ValidShaderKindMask & ModuleStagekind)) {
262320
report_fatal_error(
263-
StringRef(std::string(StageKind)
321+
StringRef(std::string(ShaderEnvStr)
264322
.append(" : Invalid Shader Stage for DXIL operation - ")
265323
.append(getOpCodeName(OpCode))
266324
.append(" for Shader Model ")
@@ -282,8 +340,17 @@ CallInst *DXILOpBuilder::createDXILOpCall(dxil::OpCode OpCode,
282340
return B.CreateCall(DXILFn, Args);
283341
}
284342

285-
Type *DXILOpBuilder::getOverloadType(dxil::OpCode OpCode, VersionTuple SMVer,
286-
FunctionType *FT) {
343+
Type *DXILOpBuilder::getOverloadType(dxil::OpCode OpCode, FunctionType *FT) {
344+
345+
std::string TTStr = M.getTargetTriple();
346+
// No extra checks need be performed to verify that the Triple is
347+
// well-formed or the target is supported since these checks would have
348+
// been done at the time the module M is constructed in the earlier stages of
349+
// compilation.
350+
auto Major = Triple(TTStr).getOSVersion().getMajor();
351+
auto MinorOrErr = Triple(TTStr).getOSVersion().getMinor();
352+
uint32_t Minor = MinorOrErr.has_value() ? *MinorOrErr : 0;
353+
VersionTuple SMVer(Major, Minor);
287354

288355
const OpCodeProperty *Prop = getOpCodeProperty(OpCode);
289356
// If DXIL Op has no overload parameter, just return the

llvm/lib/Target/DirectX/DXILOpBuilder.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,10 @@ class DXILOpBuilder {
4040
/// \param OverloadTy Overload type of the DXIL Op call constructed
4141
/// \param Args Arguments for the DXIL Op call constructed
4242
/// \return DXIL Op call constructed
43-
CallInst *createDXILOpCall(dxil::OpCode OpCode, VersionTuple SMVer,
44-
StringRef StageKind, Type *ReturnTy,
43+
CallInst *createDXILOpCall(dxil::OpCode OpCode, Type *ReturnTy,
4544
Type *OverloadTy, SmallVector<Value *> Args);
4645

47-
Type *getOverloadType(dxil::OpCode OpCode, VersionTuple SMVer,
48-
FunctionType *FT);
46+
Type *getOverloadType(dxil::OpCode OpCode, FunctionType *FT);
4947
static const char *getOpCodeName(dxil::OpCode DXILOp);
5048

5149
private:

llvm/lib/Target/DirectX/DXILOpLowering.cpp

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,10 @@ static SmallVector<Value *> argVectorFlatten(CallInst *Orig,
7474
return NewOperands;
7575
}
7676

77-
static void lowerIntrinsic(dxil::OpCode DXILOp, Function &F, Module &M,
78-
VersionTuple SMVer, StringRef StageKind) {
77+
static void lowerIntrinsic(dxil::OpCode DXILOp, Function &F, Module &M) {
7978
IRBuilder<> B(M.getContext());
8079
DXILOpBuilder DXILB(M, B);
81-
Type *OverloadTy = DXILB.getOverloadType(DXILOp, SMVer, F.getFunctionType());
80+
Type *OverloadTy = DXILB.getOverloadType(DXILOp, F.getFunctionType());
8281
for (User *U : make_early_inc_range(F.users())) {
8382
CallInst *CI = dyn_cast<CallInst>(U);
8483
if (!CI)
@@ -94,8 +93,8 @@ static void lowerIntrinsic(dxil::OpCode DXILOp, Function &F, Module &M,
9493
} else
9594
Args.append(CI->arg_begin(), CI->arg_end());
9695

97-
CallInst *DXILCI = DXILB.createDXILOpCall(
98-
DXILOp, SMVer, StageKind, F.getReturnType(), OverloadTy, Args);
96+
CallInst *DXILCI =
97+
DXILB.createDXILOpCall(DXILOp, F.getReturnType(), OverloadTy, Args);
9998

10099
CI->replaceAllUsesWith(DXILCI);
101100
CI->eraseFromParent();
@@ -111,19 +110,6 @@ static bool lowerIntrinsics(Module &M) {
111110
#include "DXILOperation.inc"
112111
#undef DXIL_OP_INTRINSIC_MAP
113112

114-
// Get Shader Model version
115-
std::string TTStr = M.getTargetTriple();
116-
// No extra checks need be performed to verify that the Triple is
117-
// well-formed or the target is supported since these checks would have
118-
// been done at the time the module M is constructed in the earlier stages of
119-
// compilation.
120-
auto Major = Triple(TTStr).getOSVersion().getMajor();
121-
auto MinorOrErr = Triple(TTStr).getOSVersion().getMinor();
122-
uint32_t Minor = MinorOrErr.has_value() ? *MinorOrErr : 0;
123-
VersionTuple SMVer(Major, Minor);
124-
// Get Shader Kind
125-
std::string StageKind = Triple(TTStr).getEnvironmentName().str();
126-
127113
for (Function &F : make_early_inc_range(M.functions())) {
128114
if (!F.isDeclaration())
129115
continue;
@@ -133,7 +119,7 @@ static bool lowerIntrinsics(Module &M) {
133119
auto LowerIt = LowerMap.find(ID);
134120
if (LowerIt == LowerMap.end())
135121
continue;
136-
lowerIntrinsic(LowerIt->second, F, M, SMVer, StageKind);
122+
lowerIntrinsic(LowerIt->second, F, M);
137123
Updated = true;
138124
}
139125
return Updated;

llvm/test/CodeGen/DirectX/sin_no_stage_error.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.0 %s 2>&1 | FileCheck %s
22

33
; Shader Stage is required to ensure the operation is supported.
4-
; CHECK: LLVM ERROR: 6.0: DXIL Module created with Unspecifed or Unknown Target Shader Stage
4+
; CHECK: LLVM ERROR: 6.0: Unknown Compilation Target Shader Stage specified
55

66
define noundef float @sin_float(float noundef %a) #0 {
77
entry:

0 commit comments

Comments
 (0)