Skip to content

Commit 10e3f7b

Browse files
committed
[DXIL] Define DXILAttribute
- switch to using DXILAttribute to only denote function attributes - attribute enums can't be or'd together as is currently implemented, so we switch to using a list of attributes in DXILOpBuilder.cpp and DXILEmitter.cpp
1 parent 01d233f commit 10e3f7b

File tree

4 files changed

+69
-34
lines changed

4 files changed

+69
-34
lines changed

llvm/lib/Target/DirectX/DXIL.td

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -266,18 +266,18 @@ def miss : DXILShaderStage;
266266
def all_stages : DXILShaderStage;
267267
// Denote support for DXIL Op to have been removed
268268
def removed : DXILShaderStage;
269+
269270
// DXIL Op attributes
270271

272+
// A function attribute denotes that there is a corresponding LLVM function
273+
// attribute that will be set when building the DXIL op. The mapping for
274+
// non-trivial cases is defined by setDXILAttribute in DXILOpBuilder.cpp
271275
class DXILAttribute;
272276

273-
def ReadOnly : DXILAttribute;
274277
def ReadNone : DXILAttribute;
275-
def IsDerivative : DXILAttribute;
276-
def IsGradient : DXILAttribute;
277-
def IsFeedback : DXILAttribute;
278-
def IsWave : DXILAttribute;
279-
def NeedsUniformInputs : DXILAttribute;
280-
def IsBarrier : DXILAttribute;
278+
def ReadOnly : DXILAttribute;
279+
def NoDuplicate : DXILAttribute;
280+
def NoReturn : DXILAttribute;
281281

282282
class Overloads<Version ver, list<DXILOpParamType> ols> {
283283
Version dxil_version = ver;
@@ -291,7 +291,7 @@ class Stages<Version ver, list<DXILShaderStage> st> {
291291

292292
class Attributes<Version ver = DXIL1_0, list<DXILAttribute> attrs> {
293293
Version dxil_version = ver;
294-
list<DXILAttribute> op_attrs = attrs;
294+
list<DXILAttribute> fn_attrs = attrs;
295295
}
296296

297297
// Abstraction DXIL Operation

llvm/lib/Target/DirectX/DXILConstants.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ enum class OpParamType : unsigned {
3030
#include "DXILOperation.inc"
3131
};
3232

33+
enum class Attribute : unsigned {
34+
#define DXIL_ATTRIBUTE(Name) Name,
35+
#include "DXILOperation.inc"
36+
};
37+
3338
} // namespace dxil
3439
} // namespace llvm
3540

llvm/lib/Target/DirectX/DXILOpBuilder.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct OpStage {
5454

5555
struct OpAttribute {
5656
Version DXILVersion;
57-
uint32_t ValidAttrs;
57+
llvm::SmallVector<dxil::Attribute> ValidAttrs;
5858
};
5959

6060
static const char *getOverloadTypeName(OverloadKind Kind) {
@@ -367,6 +367,20 @@ static std::optional<size_t> getPropIndex(ArrayRef<T> PropList,
367367
return std::nullopt;
368368
}
369369

370+
static void setDXILAttribute(CallInst *CI, dxil::Attribute Attr) {
371+
switch (Attr) {
372+
case dxil::Attribute::ReadNone:
373+
return CI->setDoesNotAccessMemory();
374+
case dxil::Attribute::ReadOnly:
375+
return CI->setOnlyReadsMemory();
376+
case dxil::Attribute::NoReturn:
377+
return CI->setDoesNotReturn();
378+
case dxil::Attribute::NoDuplicate:
379+
return CI->setCannotDuplicate();
380+
}
381+
llvm_unreachable("Invalid function attribute specified for DXIL operation");
382+
}
383+
370384
namespace llvm {
371385
namespace dxil {
372386

@@ -461,7 +475,17 @@ Expected<CallInst *> DXILOpBuilder::tryCreateOp(dxil::OpCode OpCode,
461475
OpArgs.push_back(IRB.getInt32(llvm::to_underlying(OpCode)));
462476
OpArgs.append(Args.begin(), Args.end());
463477

464-
return IRB.CreateCall(DXILFn, OpArgs, Name);
478+
// Create the function call instruction
479+
CallInst *CI = IRB.CreateCall(DXILFn, OpArgs, Name);
480+
481+
// We then need to attach available function attributes
482+
for (auto OpAttr : Prop->Attributes)
483+
if (VersionTuple(OpAttr.DXILVersion.Major, OpAttr.DXILVersion.Minor) <=
484+
DXILVersion)
485+
for (auto Attr : OpAttr.ValidAttrs)
486+
setDXILAttribute(CI, Attr);
487+
488+
return CI;
465489
}
466490

467491
CallInst *DXILOpBuilder::createOp(dxil::OpCode OpCode, ArrayRef<Value *> Args,

llvm/utils/TableGen/DXILEmitter.cpp

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -285,41 +285,37 @@ static std::string getStageMaskString(ArrayRef<const Record *> Recs) {
285285
// by input records
286286
//
287287
/// \param Recs A vector of records of TableGen Attribute records
288-
/// \return std::string string representation of stages mask string
288+
/// \return std::string string representation of attributes list string
289289
/// predicated by DXIL Version. E.g.,
290-
// {{{1, 0}, Mask1}, {{1, 2}, Mask2}, ...}
291-
static std::string getAttributeMaskString(ArrayRef<const Record *> Recs) {
292-
std::string MaskString = "";
290+
// {{{1, 0}, {Attr1, ...}}, {{1, 2}, {Attr2, ...}}, ...}
291+
static std::string getAttributeListString(ArrayRef<const Record *> Recs) {
292+
std::string ListString = "";
293293
std::string Prefix = "";
294-
MaskString.append("{");
294+
ListString.append("{");
295295

296296
for (const auto *Rec : Recs) {
297297
unsigned Major = Rec->getValueAsDef("dxil_version")->getValueAsInt("Major");
298298
unsigned Minor = Rec->getValueAsDef("dxil_version")->getValueAsInt("Minor");
299-
MaskString.append(Prefix)
299+
ListString.append(Prefix)
300300
.append("{{")
301301
.append(std::to_string(Major))
302302
.append(", ")
303-
.append(std::to_string(Minor).append("}, "));
304-
305-
std::string PipePrefix = "";
306-
auto Attrs = Rec->getValueAsListOfDefs("op_attrs");
307-
if (Attrs.empty()) {
308-
MaskString.append("Attribute::None");
309-
} else {
310-
for (const auto *Attr : Attrs) {
311-
MaskString.append(PipePrefix)
312-
.append("Attribute::")
313-
.append(Attr->getName());
314-
PipePrefix = " | ";
315-
}
303+
.append(std::to_string(Minor).append("}, {"));
304+
305+
std::string CommaPrefix = "";
306+
auto Attrs = Rec->getValueAsListOfDefs("fn_attrs");
307+
for (const auto *Attr : Attrs) {
308+
ListString.append(CommaPrefix)
309+
.append("dxil::Attribute::")
310+
.append(Attr->getName());
311+
CommaPrefix = ", ";
316312
}
317-
318-
MaskString.append("}");
313+
ListString.append("}"); // End of Attrs
314+
ListString.append("}"); // End of Rec
319315
Prefix = ", ";
320316
}
321-
MaskString.append("}");
322-
return MaskString;
317+
ListString.append("}"); // End of List
318+
return ListString;
323319
}
324320

325321
/// Emit a mapping of DXIL opcode to opname
@@ -351,6 +347,15 @@ static void emitDXILOpParamTypes(const RecordKeeper &Records, raw_ostream &OS) {
351347
OS << "#endif\n\n";
352348
}
353349

350+
/// Emit a list of DXIL op function attributes
351+
static void emitDXILAttributes(const RecordKeeper &Records, raw_ostream &OS) {
352+
OS << "#ifdef DXIL_ATTRIBUTE\n";
353+
for (const Record *Attr : Records.getAllDerivedDefinitions("DXILAttribute"))
354+
OS << "DXIL_ATTRIBUTE(" << Attr->getName() << ")\n";
355+
OS << "#undef DXIL_ATTRIBUTE\n";
356+
OS << "#endif\n\n";
357+
}
358+
354359
/// Emit a list of DXIL op function types
355360
static void emitDXILOpFunctionTypes(ArrayRef<DXILOperationDesc> Ops,
356361
raw_ostream &OS) {
@@ -421,7 +426,7 @@ static void emitDXILOperationTable(ArrayRef<DXILOperationDesc> Ops,
421426
<< OpClassStrings.get(Op.OpClass.data()) << ", "
422427
<< getOverloadMaskString(Op.OverloadRecs) << ", "
423428
<< getStageMaskString(Op.StageRecs) << ", "
424-
<< getAttributeMaskString(Op.AttrRecs) << ", " << Op.OverloadParamIndex
429+
<< getAttributeListString(Op.AttrRecs) << ", " << Op.OverloadParamIndex
425430
<< " }";
426431
Prefix = ",\n";
427432
}
@@ -526,6 +531,7 @@ static void emitDxilOperation(const RecordKeeper &Records, raw_ostream &OS) {
526531
emitDXILOpCodes(DXILOps, OS);
527532
emitDXILOpClasses(Records, OS);
528533
emitDXILOpParamTypes(Records, OS);
534+
emitDXILAttributes(Records, OS);
529535
emitDXILOpFunctionTypes(DXILOps, OS);
530536
emitDXILIntrinsicMap(DXILOps, OS);
531537
OS << "#ifdef DXIL_OP_OPERATION_TABLE\n\n";

0 commit comments

Comments
 (0)