@@ -33,9 +33,18 @@ using namespace llvm::dxil;
3333
3434namespace {
3535
36+ struct DXILArgSelect {
37+ enum class Type {
38+ Index,
39+ I32,
40+ I8,
41+ };
42+ Type Type = Type::Index;
43+ int Value = 0 ;
44+ };
3645struct DXILIntrinsicSelect {
3746 StringRef Intrinsic;
38- SmallVector<StringRef , 4 > ExtraArgs ;
47+ SmallVector<DXILArgSelect , 4 > Args ;
3948};
4049
4150struct DXILOperationDesc {
@@ -76,6 +85,21 @@ static void AscendingSortByVersion(std::vector<const Record *> &Recs) {
7685 });
7786}
7887
88+ // / Take a `int_{intrinsic_name}` and return just the intrinsic_name part if available.
89+ // / Otherwise return the empty string.
90+ static StringRef GetIntrinsicName (const RecordVal *RV){
91+ if (RV && RV->getValue ()) {
92+ if (const DefInit *DI = dyn_cast<DefInit>(RV->getValue ())) {
93+ auto *IntrinsicDef = DI->getDef ();
94+ auto DefName = IntrinsicDef->getName ();
95+ assert (DefName.starts_with (" int_" ) && " invalid intrinsic name" );
96+ // Remove the int_ from intrinsic name.
97+ return DefName.substr (4 );
98+ }
99+ }
100+ return " " ;
101+ }
102+
79103// / Construct an object using the DXIL Operation records specified
80104// / in DXIL.td. This serves as the single source of reference of
81105// / the information extracted from the specified Record R, for
@@ -162,40 +186,50 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) {
162186 OpName);
163187 }
164188
165- auto GetIntrinsicName = [](const RecordVal *RV) -> StringRef {
166- if (RV && RV->getValue ()) {
167- if (const DefInit *DI = dyn_cast<DefInit>(RV->getValue ())) {
168- auto *IntrinsicDef = DI->getDef ();
169- auto DefName = IntrinsicDef->getName ();
170- assert (DefName.starts_with (" int_" ) && " invalid intrinsic name" );
171- // Remove the int_ from intrinsic name.
172- return DefName.substr (4 );
173- }
174- }
175- return " " ;
176- };
177-
178189 {
179190 DXILIntrinsicSelect IntrSelect;
180191 IntrSelect.Intrinsic = GetIntrinsicName (R->getValue (" LLVMIntrinsic" ));
181192 if (IntrSelect.Intrinsic .size ())
182193 IntrinsicSelects.emplace_back (std::move (IntrSelect));
183194 }
184195
185- Recs = R->getValueAsListOfDefs (" intrinsic_selects" );
186- if (Recs .size ()) {
196+ auto IntrinsicSelectRecords = R->getValueAsListOfDefs (" intrinsic_selects" );
197+ if (IntrinsicSelectRecords .size ()) {
187198 if (IntrinsicSelects.size ()) {
188- PrintFatalError (R,
189- Twine (" LLVMIntrinsic and intrinsic_match cannot be both "
190- " defined for DXIL operation - " ) +
191- OpName);
199+ PrintFatalError (
200+ R, Twine (" LLVMIntrinsic and intrinsic_selects cannot be both "
201+ " defined for DXIL operation - " ) +
202+ OpName);
192203 } else {
193- for (const Record *R : Recs ) {
204+ for (const Record *R : IntrinsicSelectRecords ) {
194205 DXILIntrinsicSelect IntrSelect;
195- IntrSelect.Intrinsic = GetIntrinsicName (R->getValue (" Intr" ));
196- auto ExtraArgs = R->getValueAsListOfStrings (" ExtraArgs" );
197- for (StringRef Arg : ExtraArgs) {
198- IntrSelect.ExtraArgs .push_back (Arg);
206+ IntrSelect.Intrinsic = GetIntrinsicName (R->getValue (" intrinsic" ));
207+ auto Args = R->getValueAsListOfDefs (" args" );
208+ for (const Record *Arg : Args) {
209+ bool IsI8 = Arg->getValueAsBit (" is_i8" );
210+ bool IsI32 = Arg->getValueAsBit (" is_i32" );
211+ int Index = Arg->getValueAsInt (" index" );
212+ const Record *ValueRec = Arg->getValueAsDef (" value" );
213+
214+ DXILArgSelect ArgSelect;
215+ if (IsI8) {
216+ ArgSelect.Type = DXILArgSelect::Type::I8;
217+ ArgSelect.Value = ValueRec->getValueAsInt (" value" );
218+ } else if (IsI32) {
219+ ArgSelect.Type = DXILArgSelect::Type::I32;
220+ ArgSelect.Value = ValueRec->getValueAsInt (" value" );
221+ } else {
222+ if (Index < 0 ) {
223+ PrintFatalError (
224+ R, Twine (" Index in ArgSelect<index> must be equal to or "
225+ " greater than 0 for DXIL operation - " ) +
226+ OpName);
227+ }
228+ ArgSelect.Type = DXILArgSelect::Type::Index;
229+ ArgSelect.Value = Index;
230+ }
231+
232+ IntrSelect.Args .emplace_back (std::move (ArgSelect));
199233 }
200234 IntrinsicSelects.emplace_back (std::move (IntrSelect));
201235 }
@@ -416,11 +450,23 @@ static void emitDXILIntrinsicMap(ArrayRef<DXILOperationDesc> Ops,
416450 }
417451 for (const DXILIntrinsicSelect &MappedIntr : Op.IntrinsicSelects ) {
418452 OS << " DXIL_OP_INTRINSIC(dxil::OpCode::" << Op.OpName
419- << " , Intrinsic::" << MappedIntr.Intrinsic << " , (ArrayRef<Value *> {" ;
420- for (const StringRef &Arg : MappedIntr.ExtraArgs ) {
421- OS << Arg << " , " ;
453+ << " , Intrinsic::" << MappedIntr.Intrinsic ;
454+ for (const DXILArgSelect &ArgSelect : MappedIntr.Args ) {
455+ OS << " , (Arg { " ;
456+ switch (ArgSelect.Type ) {
457+ case DXILArgSelect::Type::Index:
458+ OS << " Arg::Type::Index, " ;
459+ break ;
460+ case DXILArgSelect::Type::I8:
461+ OS << " Arg::Type::I8, " ;
462+ break ;
463+ case DXILArgSelect::Type::I32:
464+ OS << " Arg::Type::I32, " ;
465+ break ;
466+ }
467+ OS << ArgSelect.Value << " })" ;
422468 }
423- OS << " }) )\n " ;
469+ OS << " )\n " ;
424470 }
425471 }
426472 OS << " \n " ;
0 commit comments