aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorS. Bharadwaj Yadavalli <Bharadwaj.Yadavalli@microsoft.com>2024-02-13 11:12:03 -0500
committerGitHub <noreply@github.com>2024-02-13 08:12:03 -0800
commit8ba4ff392538dac7b803cfdf5bde217ff538a644 (patch)
tree2bdfd78f9161a73399fb24a1fcba9563f9239f43
parent1f90af183d7a007584fac041eaca9f126a1a942f (diff)
downloadllvm-8ba4ff392538dac7b803cfdf5bde217ff538a644.zip
llvm-8ba4ff392538dac7b803cfdf5bde217ff538a644.tar.gz
llvm-8ba4ff392538dac7b803cfdf5bde217ff538a644.tar.bz2
[DirectX][NFC] Change specification of overload types and attribute in DXIL.td (#81184)
- Specify overload types of DXIL Operation as list of types instead of a string. - Add supported DXIL type record definitions to `DXIL.td` leveraging `LLVMType` to avoid duplicate definitions. - Spell out DXIL Operation Attribute specification string. - Make corresponding changes to process the records in DXILEmitter.cpp
-rw-r--r--llvm/lib/Target/DirectX/DXIL.td44
-rw-r--r--llvm/utils/TableGen/DXILEmitter.cpp160
2 files changed, 133 insertions, 71 deletions
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index 3f3ace5..5215813 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
include "llvm/IR/Intrinsics.td"
+include "llvm/IR/Attributes.td"
// Abstract representation of the class a DXIL Operation belongs to.
class DXILOpClass<string name> {
@@ -34,12 +35,29 @@ def BinaryUintCategory : DXILOpCategory<"Binary uint">;
def UnaryFloatCategory : DXILOpCategory<"Unary float">;
def ComputeIDCategory : DXILOpCategory<"Compute/Mesh/Amplification shader">;
+// Following are the scalar types supported by DXIL operations and are synonymous
+// to llvm_*_ty defined for readability and ease of use in the context of this file.
+
+def voidTy : LLVMType<isVoid>;
+
+// Floating point types
+def f16Ty : LLVMType<f16>;
+def f32Ty : LLVMType<f32>;
+def f64Ty : LLVMType<f64>;
+
+// Integer types
+def i1Ty : LLVMType<i1>;
+def i8Ty : LLVMType<i8>;
+def i16Ty : LLVMType<i16>;
+def i32Ty : LLVMType<i32>;
+def i64Ty : LLVMType<i64>;
+
// The parameter description for a DXIL operation
class DXILOpParameter<int pos, string type, string name, string doc,
bit isConstant = 0, string enumName = "",
int maxValue = 0> {
int Pos = pos; // Position in parameter list
- string LLVMType = type; // LLVM type name, $o for overload, $r for resource
+ string Type = type; // LLVM type name, $o for overload, $r for resource
// type, $cb for legacy cbuffer, $u4 for u4 struct
string Name = name; // Short, unique parameter name
string Doc = doc; // Description of this parameter
@@ -56,9 +74,11 @@ class DXILOperationDesc {
DXILOpCategory OpCategory; // Category of the operation
string Doc = ""; // Description of the operation
list<DXILOpParameter> Params = []; // Parameter list of the operation
- string OverloadTypes = ""; // Overload types, if applicable
- string Attributes = ""; // Attribute shorthands: rn=does not access
- // memory,ro=only reads from memory,
+ list<LLVMType> OverloadTypes = []; // Overload types, if applicable
+ EnumAttr Attribute; // Operation Attribute. Leverage attributes defined in Attributes.td
+ // ReadNone - operation does not access memory.
+ // ReadOnly - only reads from memory.
+ // "ReadMemory" - reads memory
bit IsDerivative = 0; // Whether this is some kind of derivative
bit IsGradient = 0; // Whether this requires a gradient calculation
bit IsFeedback = 0; // Whether this is a sampler feedback operation
@@ -71,7 +91,7 @@ class DXILOperationDesc {
}
class DXILOperation<string name, int opCode, DXILOpClass opClass, DXILOpCategory opCategory, string doc,
- string oloadTypes, string attrs, list<DXILOpParameter> params,
+ list<LLVMType> oloadTypes, EnumAttr attrs, list<DXILOpParameter> params,
list<string> statsGroup = []> : DXILOperationDesc {
let OpName = name;
let OpCode = opCode;
@@ -80,7 +100,7 @@ class DXILOperation<string name, int opCode, DXILOpClass opClass, DXILOpCategory
let OpClass = opClass;
let OpCategory = opCategory;
let OverloadTypes = oloadTypes;
- let Attributes = attrs;
+ let Attribute = attrs;
let StatsGroup = statsGroup;
}
@@ -88,7 +108,7 @@ class DXILOperation<string name, int opCode, DXILOpClass opClass, DXILOpCategory
class LLVMIntrinsic<Intrinsic llvm_intrinsic_> { Intrinsic llvm_intrinsic = llvm_intrinsic_; }
def Sin : DXILOperation<"Sin", 13, UnaryClass, UnaryFloatCategory, "returns sine(theta) for theta in radians.",
- "half;float;", "rn",
+ [f16Ty,f32Ty], ReadNone,
[
DXILOpParameter<0, "$o", "", "operation result">,
DXILOpParameter<1, "i32", "opcode", "DXIL opcode">,
@@ -98,7 +118,7 @@ def Sin : DXILOperation<"Sin", 13, UnaryClass, UnaryFloatCategory, "returns sine
LLVMIntrinsic<int_sin>;
def UMax : DXILOperation< "UMax", 39, BinaryClass, BinaryUintCategory, "unsigned integer maximum. UMax(a,b) = a > b ? a : b",
- "i16;i32;i64;", "rn",
+ [i16Ty,i32Ty,i64Ty], ReadNone,
[
DXILOpParameter<0, "$o", "", "operation result">,
DXILOpParameter<1, "i32", "opcode", "DXIL opcode">,
@@ -108,7 +128,7 @@ def UMax : DXILOperation< "UMax", 39, BinaryClass, BinaryUintCategory, "unsign
["uints"]>,
LLVMIntrinsic<int_umax>;
-def ThreadId : DXILOperation< "ThreadId", 93, ThreadIdClass, ComputeIDCategory, "reads the thread ID", "i32;", "rn",
+def ThreadId : DXILOperation< "ThreadId", 93, ThreadIdClass, ComputeIDCategory, "reads the thread ID", [i32Ty], ReadNone,
[
DXILOpParameter<0, "i32", "", "thread ID component">,
DXILOpParameter<1, "i32", "opcode", "DXIL opcode">,
@@ -116,7 +136,7 @@ def ThreadId : DXILOperation< "ThreadId", 93, ThreadIdClass, ComputeIDCategory,
]>,
LLVMIntrinsic<int_dx_thread_id>;
-def GroupId : DXILOperation< "GroupId", 94, GroupIdClass, ComputeIDCategory, "reads the group ID (SV_GroupID)", "i32;", "rn",
+def GroupId : DXILOperation< "GroupId", 94, GroupIdClass, ComputeIDCategory, "reads the group ID (SV_GroupID)", [i32Ty], ReadNone,
[
DXILOpParameter<0, "i32", "", "group ID component">,
DXILOpParameter<1, "i32", "opcode", "DXIL opcode">,
@@ -125,7 +145,7 @@ def GroupId : DXILOperation< "GroupId", 94, GroupIdClass, ComputeIDCategory, "r
LLVMIntrinsic<int_dx_group_id>;
def ThreadIdInGroup : DXILOperation< "ThreadIdInGroup", 95, ThreadIdInGroupClass, ComputeIDCategory,
- "reads the thread ID within the group (SV_GroupThreadID)", "i32;", "rn",
+ "reads the thread ID within the group (SV_GroupThreadID)", [i32Ty], ReadNone,
[
DXILOpParameter<0, "i32", "", "thread ID in group component">,
DXILOpParameter<1, "i32", "opcode", "DXIL opcode">,
@@ -134,7 +154,7 @@ def ThreadIdInGroup : DXILOperation< "ThreadIdInGroup", 95, ThreadIdInGroupClas
LLVMIntrinsic<int_dx_thread_id_in_group>;
def FlattenedThreadIdInGroup : DXILOperation< "FlattenedThreadIdInGroup", 96, FlattenedThreadIdInGroupClass, ComputeIDCategory,
- "provides a flattened index for a given thread within a given group (SV_GroupIndex)", "i32;", "rn",
+ "provides a flattened index for a given thread within a given group (SV_GroupIndex)", [i32Ty], ReadNone,
[
DXILOpParameter<0, "i32", "", "result">,
DXILOpParameter<1, "i32", "opcode", "DXIL opcode">
diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp
index 25e818a..3378a90 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -49,11 +49,11 @@ struct DXILOperationDesc {
StringRef Doc; // the documentation description of this instruction
SmallVector<DXILParameter> Params; // the operands that this instruction takes
- StringRef OverloadTypes; // overload types if applicable
- StringRef FnAttr; // attribute shorthands: rn=does not access
- // memory,ro=only reads from memory
+ SmallVector<ParameterKind> OverloadTypes; // overload types if applicable
+ StringRef Attr; // operation attribute; reference to string representation
+ // of llvm::Attribute::AttrKind
StringRef Intrinsic; // The llvm intrinsic map to OpName. Default is "" which
- // means no map exist
+ // means no map exists
bool IsDeriv = false; // whether this is some kind of derivative
bool IsGradient = false; // whether this requires a gradient calculation
bool IsFeedback = false; // whether this is a sampler feedback op
@@ -70,37 +70,32 @@ struct DXILOperationDesc {
int OverloadParamIndex; // parameter index which control the overload.
// When < 0, should be only 1 overload type.
SmallVector<StringRef, 4> counters; // counters for this inst.
- DXILOperationDesc(const Record *R) {
- OpName = R->getValueAsString("OpName");
- OpCode = R->getValueAsInt("OpCode");
- OpClass = R->getValueAsDef("OpClass")->getValueAsString("Name");
- Category = R->getValueAsDef("OpCategory")->getValueAsString("Name");
-
- if (R->getValue("llvm_intrinsic")) {
- auto *IntrinsicDef = R->getValueAsDef("llvm_intrinsic");
- auto DefName = IntrinsicDef->getName();
- assert(DefName.starts_with("int_") && "invalid intrinsic name");
- // Remove the int_ from intrinsic name.
- Intrinsic = DefName.substr(4);
- }
-
- Doc = R->getValueAsString("Doc");
-
- ListInit *ParamList = R->getValueAsListInit("Params");
- OverloadParamIndex = -1;
- for (unsigned I = 0; I < ParamList->size(); ++I) {
- Record *Param = ParamList->getElementAsRecord(I);
- Params.emplace_back(DXILParameter(Param));
- auto &CurParam = Params.back();
- if (CurParam.Kind >= ParameterKind::OVERLOAD)
- OverloadParamIndex = I;
- }
- OverloadTypes = R->getValueAsString("OverloadTypes");
- FnAttr = R->getValueAsString("Attributes");
- }
+ DXILOperationDesc(const Record *);
};
} // end anonymous namespace
+// Convert DXIL type name string to dxil::ParameterKind
+//
+// @param typeNameStr Type name string
+// @return ParameterKind as defined in llvm/Support/DXILABI.h
+static ParameterKind getDXILTypeNameToKind(StringRef typeNameStr) {
+ return StringSwitch<ParameterKind>(typeNameStr)
+ .Case("voidTy", ParameterKind::VOID)
+ .Case("f16Ty", ParameterKind::HALF)
+ .Case("f32Ty", ParameterKind::FLOAT)
+ .Case("f64Ty", ParameterKind::DOUBLE)
+ .Case("i1Ty", ParameterKind::I1)
+ .Case("i8Ty", ParameterKind::I8)
+ .Case("i16Ty", ParameterKind::I16)
+ .Case("i32Ty", ParameterKind::I32)
+ .Case("i64Ty", ParameterKind::I64)
+ .Case("overloadTy", ParameterKind::OVERLOAD)
+ .Case("handleTy", ParameterKind::DXIL_HANDLE)
+ .Case("cbufferRetTy", ParameterKind::CBUFFER_RET)
+ .Case("resourceRetTy", ParameterKind::RESOURCE_RET)
+ .Default(ParameterKind::INVALID);
+}
+
static ParameterKind parameterTypeNameToKind(StringRef Name) {
return StringSwitch<ParameterKind>(Name)
.Case("void", ParameterKind::VOID)
@@ -119,10 +114,44 @@ static ParameterKind parameterTypeNameToKind(StringRef Name) {
.Default(ParameterKind::INVALID);
}
+DXILOperationDesc::DXILOperationDesc(const Record *R) {
+ OpName = R->getValueAsString("OpName");
+ OpCode = R->getValueAsInt("OpCode");
+ OpClass = R->getValueAsDef("OpClass")->getValueAsString("Name");
+ Category = R->getValueAsDef("OpCategory")->getValueAsString("Name");
+
+ if (R->getValue("llvm_intrinsic")) {
+ auto *IntrinsicDef = R->getValueAsDef("llvm_intrinsic");
+ auto DefName = IntrinsicDef->getName();
+ assert(DefName.starts_with("int_") && "invalid intrinsic name");
+ // Remove the int_ from intrinsic name.
+ Intrinsic = DefName.substr(4);
+ }
+
+ Doc = R->getValueAsString("Doc");
+
+ ListInit *ParamList = R->getValueAsListInit("Params");
+ OverloadParamIndex = -1;
+ for (unsigned I = 0; I < ParamList->size(); ++I) {
+ Record *Param = ParamList->getElementAsRecord(I);
+ Params.emplace_back(DXILParameter(Param));
+ auto &CurParam = Params.back();
+ if (CurParam.Kind >= ParameterKind::OVERLOAD)
+ OverloadParamIndex = I;
+ }
+ ListInit *OverloadTypeList = R->getValueAsListInit("OverloadTypes");
+
+ for (unsigned I = 0; I < OverloadTypeList->size(); ++I) {
+ Record *R = OverloadTypeList->getElementAsRecord(I);
+ OverloadTypes.emplace_back(getDXILTypeNameToKind(R->getNameInitAsString()));
+ }
+ Attr = StringRef(R->getValue("Attribute")->getNameInitAsString());
+}
+
DXILParameter::DXILParameter(const Record *R) {
Name = R->getValueAsString("Name");
Pos = R->getValueAsInt("Pos");
- Kind = parameterTypeNameToKind(R->getValueAsString("LLVMType"));
+ Kind = parameterTypeNameToKind(R->getValueAsString("Type"));
if (R->getValue("Doc"))
Doc = R->getValueAsString("Doc");
IsConst = R->getValueAsBit("IsConstant");
@@ -267,38 +296,51 @@ static void emitDXILIntrinsicMap(std::vector<DXILOperationDesc> &Ops,
OS << "\n";
}
-static std::string emitDXILOperationFnAttr(StringRef FnAttr) {
- return StringSwitch<std::string>(FnAttr)
- .Case("rn", "Attribute::ReadNone")
- .Case("ro", "Attribute::ReadOnly")
+// Convert operation attribute string to Attribute enum
+//
+// @param Attr string reference
+// @return std::string Attribute enum string
+static std::string emitDXILOperationAttr(StringRef Attr) {
+ return StringSwitch<std::string>(Attr)
+ .Case("ReadNone", "Attribute::ReadNone")
+ .Case("ReadOnly", "Attribute::ReadOnly")
.Default("Attribute::None");
}
-static std::string getOverloadKind(StringRef Overload) {
- return StringSwitch<std::string>(Overload)
- .Case("half", "OverloadKind::HALF")
- .Case("float", "OverloadKind::FLOAT")
- .Case("double", "OverloadKind::DOUBLE")
- .Case("i1", "OverloadKind::I1")
- .Case("i16", "OverloadKind::I16")
- .Case("i32", "OverloadKind::I32")
- .Case("i64", "OverloadKind::I64")
- .Case("udt", "OverloadKind::UserDefineType")
- .Case("obj", "OverloadKind::ObjectType")
- .Default("OverloadKind::VOID");
+static std::string overloadKindStr(ParameterKind Overload) {
+ switch (Overload) {
+ case ParameterKind::HALF:
+ return "OverloadKind::HALF";
+ case ParameterKind::FLOAT:
+ return "OverloadKind::FLOAT";
+ case ParameterKind::DOUBLE:
+ return "OverloadKind::DOUBLE";
+ case ParameterKind::I1:
+ return "OverloadKind::I1";
+ case ParameterKind::I8:
+ return "OverloadKind::I8";
+ case ParameterKind::I16:
+ return "OverloadKind::I16";
+ case ParameterKind::I32:
+ return "OverloadKind::I32";
+ case ParameterKind::I64:
+ return "OverloadKind::I64";
+ case ParameterKind::VOID:
+ return "OverloadKind::VOID";
+ default:
+ return "OverloadKind::UNKNOWN";
+ }
}
-static std::string getDXILOperationOverload(StringRef Overloads) {
- SmallVector<StringRef> OverloadStrs;
- Overloads.split(OverloadStrs, ';', /*MaxSplit*/ -1, /*KeepEmpty*/ false);
+static std::string
+getDXILOperationOverloads(SmallVector<ParameterKind> Overloads) {
// Format is: OverloadKind::FLOAT | OverloadKind::HALF
- assert(!OverloadStrs.empty() && "Invalid overloads");
- auto It = OverloadStrs.begin();
+ auto It = Overloads.begin();
std::string Result;
raw_string_ostream OS(Result);
- OS << getOverloadKind(*It);
- for (++It; It != OverloadStrs.end(); ++It) {
- OS << " | " << getOverloadKind(*It);
+ OS << overloadKindStr(*It);
+ for (++It; It != Overloads.end(); ++It) {
+ OS << " | " << overloadKindStr(*It);
}
return OS.str();
}
@@ -368,8 +410,8 @@ static void emitDXILOperationTable(std::vector<DXILOperationDesc> &Ops,
OS << " { dxil::OpCode::" << Op.OpName << ", "
<< OpStrings.get(Op.OpName.str()) << ", OpCodeClass::" << Op.OpClass
<< ", " << OpClassStrings.get(getDXILOpClassName(Op.OpClass)) << ", "
- << getDXILOperationOverload(Op.OverloadTypes) << ", "
- << emitDXILOperationFnAttr(Op.FnAttr) << ", " << Op.OverloadParamIndex
+ << getDXILOperationOverloads(Op.OverloadTypes) << ", "
+ << emitDXILOperationAttr(Op.Attr) << ", " << Op.OverloadParamIndex
<< ", " << Op.Params.size() << ", "
<< Parameters.get(ParameterMap[Op.OpClass]) << " },\n";
}