aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/DXILEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils/TableGen/DXILEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/DXILEmitter.cpp282
1 files changed, 160 insertions, 122 deletions
diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp
index 475a57a..3378a90 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -30,7 +30,7 @@ struct DXILShaderModel {
int Minor = 0;
};
-struct DXILParam {
+struct DXILParameter {
int Pos; // position in parameter list
ParameterKind Kind;
StringRef Name; // short, unique name
@@ -38,28 +38,27 @@ struct DXILParam {
bool IsConst; // whether this argument requires a constant value in the IR
StringRef EnumName; // the name of the enum type if applicable
int MaxValue; // the maximum value for this parameter if applicable
- DXILParam(const Record *R);
+ DXILParameter(const Record *R);
};
-struct DXILOperationData {
- StringRef Name; // short, unique name
-
- StringRef DXILOp; // name of DXIL operation
- int DXILOpID; // ID of DXIL operation
- StringRef DXILClass; // name of the opcode class
- StringRef Category; // classification for this instruction
- StringRef Doc; // the documentation description of this instruction
-
- SmallVector<DXILParam> 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
- StringRef Intrinsic; // The llvm intrinsic map to DXILOp. Default is "" which
- // means no map exist
- bool IsDeriv = false; // whether this is some kind of derivative
+struct DXILOperationDesc {
+ StringRef OpName; // name of DXIL operation
+ int OpCode; // ID of DXIL operation
+ StringRef OpClass; // name of the opcode class
+ StringRef Category; // classification for this instruction
+ StringRef Doc; // the documentation description of this instruction
+
+ SmallVector<DXILParameter> Params; // the operands that this instruction takes
+ 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 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
- bool IsWave = false; // whether this requires in-wave, cross-lane functionality
+ bool IsWave =
+ false; // whether this requires in-wave, cross-lane functionality
bool RequiresUniformInputs = false; // whether this operation requires that
// all of its inputs are uniform across
// the wave
@@ -71,38 +70,32 @@ struct DXILOperationData {
int OverloadParamIndex; // parameter index which control the overload.
// When < 0, should be only 1 overload type.
SmallVector<StringRef, 4> counters; // counters for this inst.
- DXILOperationData(const Record *R) {
- Name = R->getValueAsString("Name");
- DXILOp = R->getValueAsString("OpName");
- DXILOpID = R->getValueAsInt("OpCode");
- DXILClass = 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(DXILParam(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)
@@ -121,10 +114,44 @@ static ParameterKind parameterTypeNameToKind(StringRef Name) {
.Default(ParameterKind::INVALID);
}
-DXILParam::DXILParam(const Record *R) {
+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");
@@ -166,10 +193,9 @@ static std::string parameterKindToString(ParameterKind Kind) {
llvm_unreachable("Unknown llvm::dxil::ParameterKind enum");
}
-static void emitDXILOpEnum(DXILOperationData &DXILOp, raw_ostream &OS) {
+static void emitDXILOpEnum(DXILOperationDesc &Op, raw_ostream &OS) {
// Name = ID, // Doc
- OS << DXILOp.Name << " = " << DXILOp.DXILOpID << ", // " << DXILOp.Doc
- << "\n";
+ OS << Op.OpName << " = " << Op.OpCode << ", // " << Op.Doc << "\n";
}
static std::string buildCategoryStr(StringSet<> &Cetegorys) {
@@ -182,14 +208,14 @@ static std::string buildCategoryStr(StringSet<> &Cetegorys) {
}
// Emit enum declaration for DXIL.
-static void emitDXILEnums(std::vector<DXILOperationData> &DXILOps,
+static void emitDXILEnums(std::vector<DXILOperationDesc> &Ops,
raw_ostream &OS) {
// Sort by Category + OpName.
- llvm::sort(DXILOps, [](DXILOperationData &A, DXILOperationData &B) {
+ llvm::sort(Ops, [](DXILOperationDesc &A, DXILOperationDesc &B) {
// Group by Category first.
if (A.Category == B.Category)
// Inside same Category, order by OpName.
- return A.DXILOp < B.DXILOp;
+ return A.OpName < B.OpName;
else
return A.Category < B.Category;
});
@@ -199,18 +225,18 @@ static void emitDXILEnums(std::vector<DXILOperationData> &DXILOps,
StringMap<StringSet<>> ClassMap;
StringRef PrevCategory = "";
- for (auto &DXILOp : DXILOps) {
- StringRef Category = DXILOp.Category;
+ for (auto &Op : Ops) {
+ StringRef Category = Op.Category;
if (Category != PrevCategory) {
OS << "\n// " << Category << "\n";
PrevCategory = Category;
}
- emitDXILOpEnum(DXILOp, OS);
- auto It = ClassMap.find(DXILOp.DXILClass);
+ emitDXILOpEnum(Op, OS);
+ auto It = ClassMap.find(Op.OpClass);
if (It != ClassMap.end()) {
- It->second.insert(DXILOp.Category);
+ It->second.insert(Op.Category);
} else {
- ClassMap[DXILOp.DXILClass].insert(DXILOp.Category);
+ ClassMap[Op.OpClass].insert(Op.Category);
}
}
@@ -253,55 +279,68 @@ static void emitDXILEnums(std::vector<DXILOperationData> &DXILOps,
}
// Emit map from llvm intrinsic to DXIL operation.
-static void emitDXILIntrinsicMap(std::vector<DXILOperationData> &DXILOps,
+static void emitDXILIntrinsicMap(std::vector<DXILOperationDesc> &Ops,
raw_ostream &OS) {
OS << "\n";
// FIXME: use array instead of SmallDenseMap.
OS << "static const SmallDenseMap<Intrinsic::ID, dxil::OpCode> LowerMap = "
"{\n";
- for (auto &DXILOp : DXILOps) {
- if (DXILOp.Intrinsic.empty())
+ for (auto &Op : Ops) {
+ if (Op.Intrinsic.empty())
continue;
// {Intrinsic::sin, dxil::OpCode::Sin},
- OS << " { Intrinsic::" << DXILOp.Intrinsic
- << ", dxil::OpCode::" << DXILOp.DXILOp << "},\n";
+ OS << " { Intrinsic::" << Op.Intrinsic << ", dxil::OpCode::" << Op.OpName
+ << "},\n";
}
OS << "};\n";
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();
}
@@ -315,20 +354,20 @@ static std::string lowerFirstLetter(StringRef Name) {
return LowerName;
}
-static std::string getDXILOpClassName(StringRef DXILOpClass) {
+static std::string getDXILOpClassName(StringRef OpClass) {
// Lower first letter expect for special case.
- return StringSwitch<std::string>(DXILOpClass)
+ return StringSwitch<std::string>(OpClass)
.Case("CBufferLoad", "cbufferLoad")
.Case("CBufferLoadLegacy", "cbufferLoadLegacy")
.Case("GSInstanceID", "gsInstanceID")
- .Default(lowerFirstLetter(DXILOpClass));
+ .Default(lowerFirstLetter(OpClass));
}
-static void emitDXILOperationTable(std::vector<DXILOperationData> &DXILOps,
+static void emitDXILOperationTable(std::vector<DXILOperationDesc> &Ops,
raw_ostream &OS) {
- // Sort by DXILOpID.
- llvm::sort(DXILOps, [](DXILOperationData &A, DXILOperationData &B) {
- return A.DXILOpID < B.DXILOpID;
+ // Sort by OpCode.
+ llvm::sort(Ops, [](DXILOperationDesc &A, DXILOperationDesc &B) {
+ return A.OpCode < B.OpCode;
});
// Collect Names.
@@ -338,18 +377,18 @@ static void emitDXILOperationTable(std::vector<DXILOperationData> &DXILOps,
StringMap<SmallVector<ParameterKind>> ParameterMap;
StringSet<> ClassSet;
- for (auto &DXILOp : DXILOps) {
- OpStrings.add(DXILOp.DXILOp.str());
+ for (auto &Op : Ops) {
+ OpStrings.add(Op.OpName.str());
- if (ClassSet.contains(DXILOp.DXILClass))
+ if (ClassSet.contains(Op.OpClass))
continue;
- ClassSet.insert(DXILOp.DXILClass);
- OpClassStrings.add(getDXILOpClassName(DXILOp.DXILClass));
+ ClassSet.insert(Op.OpClass);
+ OpClassStrings.add(getDXILOpClassName(Op.OpClass));
SmallVector<ParameterKind> ParamKindVec;
- for (auto &Param : DXILOp.Params) {
+ for (auto &Param : Op.Params) {
ParamKindVec.emplace_back(Param.Kind);
}
- ParameterMap[DXILOp.DXILClass] = ParamKindVec;
+ ParameterMap[Op.OpClass] = ParamKindVec;
Parameters.add(ParamKindVec);
}
@@ -363,26 +402,25 @@ static void emitDXILOperationTable(std::vector<DXILOperationData> &DXILOps,
// OpCodeClassNameIndex,
// OverloadKind::FLOAT | OverloadKind::HALF, Attribute::AttrKind::ReadNone, 0,
// 3, ParameterTableOffset},
- OS << "static const OpCodeProperty *getOpCodeProperty(dxil::OpCode DXILOp) "
+ OS << "static const OpCodeProperty *getOpCodeProperty(dxil::OpCode Op) "
"{\n";
OS << " static const OpCodeProperty OpCodeProps[] = {\n";
- for (auto &DXILOp : DXILOps) {
- OS << " { dxil::OpCode::" << DXILOp.DXILOp << ", "
- << OpStrings.get(DXILOp.DXILOp.str())
- << ", OpCodeClass::" << DXILOp.DXILClass << ", "
- << OpClassStrings.get(getDXILOpClassName(DXILOp.DXILClass)) << ", "
- << getDXILOperationOverload(DXILOp.OverloadTypes) << ", "
- << emitDXILOperationFnAttr(DXILOp.FnAttr) << ", "
- << DXILOp.OverloadParamIndex << ", " << DXILOp.Params.size() << ", "
- << Parameters.get(ParameterMap[DXILOp.DXILClass]) << " },\n";
+ for (auto &Op : Ops) {
+ OS << " { dxil::OpCode::" << Op.OpName << ", "
+ << OpStrings.get(Op.OpName.str()) << ", OpCodeClass::" << Op.OpClass
+ << ", " << OpClassStrings.get(getDXILOpClassName(Op.OpClass)) << ", "
+ << getDXILOperationOverloads(Op.OverloadTypes) << ", "
+ << emitDXILOperationAttr(Op.Attr) << ", " << Op.OverloadParamIndex
+ << ", " << Op.Params.size() << ", "
+ << Parameters.get(ParameterMap[Op.OpClass]) << " },\n";
}
OS << " };\n";
OS << " // FIXME: change search to indexing with\n";
- OS << " // DXILOp once all DXIL op is added.\n";
+ OS << " // Op once all DXIL operations are added.\n";
OS << " OpCodeProperty TmpProp;\n";
- OS << " TmpProp.OpCode = DXILOp;\n";
+ OS << " TmpProp.OpCode = Op;\n";
OS << " const OpCodeProperty *Prop =\n";
OS << " llvm::lower_bound(OpCodeProps, TmpProp,\n";
OS << " [](const OpCodeProperty &A, const "
@@ -394,12 +432,12 @@ static void emitDXILOperationTable(std::vector<DXILOperationData> &DXILOps,
OS << "}\n\n";
// Emit the string tables.
- OS << "static const char *getOpCodeName(dxil::OpCode DXILOp) {\n\n";
+ OS << "static const char *getOpCodeName(dxil::OpCode Op) {\n\n";
OpStrings.emitStringLiteralDef(OS,
" static const char DXILOpCodeNameTable[]");
- OS << " auto *Prop = getOpCodeProperty(DXILOp);\n";
+ OS << " auto *Prop = getOpCodeProperty(Op);\n";
OS << " unsigned Index = Prop->OpCodeNameOffset;\n";
OS << " return DXILOpCodeNameTable + Index;\n";
OS << "}\n\n";
@@ -431,14 +469,14 @@ static void emitDXILOperationTable(std::vector<DXILOperationData> &DXILOps,
}
static void EmitDXILOperation(RecordKeeper &Records, raw_ostream &OS) {
- std::vector<Record *> Ops = Records.getAllDerivedDefinitions("DxilOperation");
+ std::vector<Record *> Ops = Records.getAllDerivedDefinitions("DXILOperation");
OS << "// Generated code, do not edit.\n";
OS << "\n";
- std::vector<DXILOperationData> DXILOps;
+ std::vector<DXILOperationDesc> DXILOps;
DXILOps.reserve(Ops.size());
for (auto *Record : Ops) {
- DXILOps.emplace_back(DXILOperationData(Record));
+ DXILOps.emplace_back(DXILOperationDesc(Record));
}
OS << "#ifdef DXIL_OP_ENUM\n";