Skip to content

Commit c6dcd20

Browse files
committed
All working now
1 parent 3d869fe commit c6dcd20

File tree

4 files changed

+146
-49
lines changed

4 files changed

+146
-49
lines changed

llvm/lib/Target/DirectX/DXIL.td

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,41 @@ class Attributes<Version ver = DXIL1_0, list<DXILAttribute> attrs> {
294294
list<DXILAttribute> op_attrs = attrs;
295295
}
296296

297-
class IntrinsicSelect<Intrinsic intr, list<string> extra_args> {
298-
Intrinsic Intr = intr;
299-
list<string> ExtraArgs = extra_args;
297+
class DXILConstant<int value_> {
298+
int value = value_;
299+
}
300+
301+
defset list<DXILConstant> BarrierModes = {
302+
def BarrierMode_DeviceMemoryBarrier : DXILConstant<2>;
303+
def BarrierMode_DeviceMemoryBarrierWithGroupSync : DXILConstant<3>;
304+
def BarrierMode_GroupMemoryBarrier : DXILConstant<8>;
305+
def BarrierMode_GroupMemoryBarrierWithGroupSync : DXILConstant<9>;
306+
def BarrierMode_AllMemoryBarrier : DXILConstant<10>;
307+
def BarrierMode_AllMemoryBarrierWithGroupSync : DXILConstant<11>;
308+
}
309+
310+
// Intrinsic arg selection
311+
class Arg {
312+
int index = -1;
313+
DXILConstant value;
314+
bit is_i8 = 0;
315+
bit is_i32 = 0;
316+
}
317+
class ArgSelect<int index_> : Arg {
318+
let index = index_;
319+
}
320+
class ArgI32<DXILConstant value_> : Arg {
321+
let value = value_;
322+
let is_i32 = 1;
323+
}
324+
class ArgI8<DXILConstant value_> : Arg {
325+
let value = value_;
326+
let is_i8 = 1;
327+
}
328+
329+
class IntrinsicSelect<Intrinsic intrinsic_, list<Arg> args_=?> {
330+
Intrinsic intrinsic = intrinsic_;
331+
list<Arg> args = args_;
300332
}
301333

302334
// Abstraction DXIL Operation
@@ -842,7 +874,7 @@ def Barrier : DXILOp<80, barrier> {
842874
let intrinsic_selects = [
843875
IntrinsicSelect<
844876
int_dx_group_memory_barrier_with_group_sync,
845-
[ "OpBuilder.getIRB().getInt32((unsigned)BarrierMode::SyncThreadGroup | (unsigned)BarrierMode::TGSMFence)" ]>,
877+
[ ArgI32<BarrierMode_GroupMemoryBarrierWithGroupSync> ]>,
846878
];
847879

848880
let arguments = [Int32Ty];

llvm/lib/Target/DirectX/DXILConstants.h

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

33-
enum class BarrierMode : unsigned {
34-
SyncThreadGroup = 0x00000001,
35-
UAVFenceGlobal = 0x00000002,
36-
UAVFenceThreadGroup = 0x00000004,
37-
TGSMFence = 0x00000008,
38-
};
39-
4033
} // namespace dxil
4134
} // namespace llvm
4235

llvm/lib/Target/DirectX/DXILOpLowering.cpp

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,19 +106,44 @@ class OpLowerer {
106106
return false;
107107
}
108108

109+
struct Arg {
110+
enum class Type {
111+
Index,
112+
I8,
113+
I32,
114+
};
115+
Type Type = Type::Index;
116+
int Value = -1;
117+
};
118+
109119
[[nodiscard]] bool replaceFunctionWithOp(Function &F, dxil::OpCode DXILOp,
110-
ArrayRef<Value *> ExtraArgs) {
120+
ArrayRef<Arg> Args) {
111121
bool IsVectorArgExpansion = isVectorArgExpansion(F);
112122
return replaceFunction(F, [&](CallInst *CI) -> Error {
123+
OpBuilder.getIRB().SetInsertPoint(CI);
113124
SmallVector<Value *> NewArgs;
114-
if (IsVectorArgExpansion) {
125+
if (Args.size()) {
126+
for (const Arg &A : Args) {
127+
switch (A.Type) {
128+
case Arg::Type::Index:
129+
NewArgs.push_back(CI->getArgOperand(A.Value));
130+
break;
131+
case Arg::Type::I8:
132+
NewArgs.push_back(OpBuilder.getIRB().getInt8((uint8_t)A.Value));
133+
break;
134+
case Arg::Type::I32:
135+
NewArgs.push_back(OpBuilder.getIRB().getInt32(A.Value));
136+
break;
137+
default:
138+
llvm_unreachable("Invalid type of intrinsic arg.");
139+
}
140+
}
141+
} else if (IsVectorArgExpansion) {
115142
NewArgs = argVectorFlatten(CI, OpBuilder.getIRB());
116-
} else
143+
} else {
117144
NewArgs.append(CI->arg_begin(), CI->arg_end());
145+
}
118146

119-
NewArgs.append(ExtraArgs.begin(), ExtraArgs.end());
120-
121-
OpBuilder.getIRB().SetInsertPoint(CI);
122147
Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
123148
DXILOp, NewArgs, CI->getName(), F.getReturnType());
124149
if (Error E = OpCall.takeError())
@@ -584,9 +609,10 @@ class OpLowerer {
584609
switch (ID) {
585610
default:
586611
continue;
587-
#define DXIL_OP_INTRINSIC(OpCode, Intrin, ExtraArgs) \
588-
case Intrin: \
589-
HasErrors |= replaceFunctionWithOp(F, OpCode, ExtraArgs); \
612+
#define DXIL_OP_INTRINSIC(OpCode, Intrin, ...) \
613+
case Intrin: \
614+
HasErrors |= replaceFunctionWithOp(F, OpCode, \
615+
ArrayRef<Arg>{ __VA_ARGS__ }); \
590616
break;
591617
#include "DXILOperation.inc"
592618
case Intrinsic::dx_handle_fromBinding:

llvm/utils/TableGen/DXILEmitter.cpp

Lines changed: 75 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,18 @@ using namespace llvm::dxil;
3232

3333
namespace {
3434

35+
struct DXILArgSelect {
36+
enum class Type {
37+
Index,
38+
I32,
39+
I8,
40+
};
41+
Type Type = Type::Index;
42+
int Value = 0;
43+
};
3544
struct DXILIntrinsicSelect {
3645
StringRef Intrinsic;
37-
SmallVector<StringRef, 4> ExtraArgs;
46+
SmallVector<DXILArgSelect, 4> Args;
3847
};
3948

4049
struct DXILOperationDesc {
@@ -75,6 +84,21 @@ static void ascendingSortByVersion(std::vector<const Record *> &Recs) {
7584
});
7685
}
7786

87+
/// Take a `int_{intrinsic_name}` and return just the intrinsic_name part if available.
88+
/// Otherwise return the empty string.
89+
static StringRef GetIntrinsicName(const RecordVal *RV){
90+
if (RV && RV->getValue()) {
91+
if (const DefInit *DI = dyn_cast<DefInit>(RV->getValue())) {
92+
auto *IntrinsicDef = DI->getDef();
93+
auto DefName = IntrinsicDef->getName();
94+
assert(DefName.starts_with("int_") && "invalid intrinsic name");
95+
// Remove the int_ from intrinsic name.
96+
return DefName.substr(4);
97+
}
98+
}
99+
return "";
100+
}
101+
78102
/// Construct an object using the DXIL Operation records specified
79103
/// in DXIL.td. This serves as the single source of reference of
80104
/// the information extracted from the specified Record R, for
@@ -161,40 +185,50 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) {
161185
OpName);
162186
}
163187

164-
auto GetIntrinsicName = [](const RecordVal *RV) -> StringRef {
165-
if (RV && RV->getValue()) {
166-
if (const DefInit *DI = dyn_cast<DefInit>(RV->getValue())) {
167-
auto *IntrinsicDef = DI->getDef();
168-
auto DefName = IntrinsicDef->getName();
169-
assert(DefName.starts_with("int_") && "invalid intrinsic name");
170-
// Remove the int_ from intrinsic name.
171-
return DefName.substr(4);
172-
}
173-
}
174-
return "";
175-
};
176-
177188
{
178189
DXILIntrinsicSelect IntrSelect;
179190
IntrSelect.Intrinsic = GetIntrinsicName(R->getValue("LLVMIntrinsic"));
180191
if (IntrSelect.Intrinsic.size())
181192
IntrinsicSelects.emplace_back(std::move(IntrSelect));
182193
}
183194

184-
Recs = R->getValueAsListOfDefs("intrinsic_selects");
185-
if (Recs.size()) {
195+
auto IntrinsicSelectRecords = R->getValueAsListOfDefs("intrinsic_selects");
196+
if (IntrinsicSelectRecords.size()) {
186197
if (IntrinsicSelects.size()) {
187-
PrintFatalError(R,
188-
Twine("LLVMIntrinsic and intrinsic_match cannot be both "
189-
"defined for DXIL operation - ") +
190-
OpName);
198+
PrintFatalError(
199+
R, Twine("LLVMIntrinsic and intrinsic_selects cannot be both "
200+
"defined for DXIL operation - ") +
201+
OpName);
191202
} else {
192-
for (const Record *R : Recs) {
203+
for (const Record *R : IntrinsicSelectRecords) {
193204
DXILIntrinsicSelect IntrSelect;
194-
IntrSelect.Intrinsic = GetIntrinsicName(R->getValue("Intr"));
195-
auto ExtraArgs = R->getValueAsListOfStrings("ExtraArgs");
196-
for (StringRef Arg : ExtraArgs) {
197-
IntrSelect.ExtraArgs.push_back(Arg);
205+
IntrSelect.Intrinsic = GetIntrinsicName(R->getValue("intrinsic"));
206+
auto Args = R->getValueAsListOfDefs("args");
207+
for (const Record *Arg : Args) {
208+
bool IsI8 = Arg->getValueAsBit("is_i8");
209+
bool IsI32 = Arg->getValueAsBit("is_i32");
210+
int Index = Arg->getValueAsInt("index");
211+
const Record *ValueRec = Arg->getValueAsDef("value");
212+
213+
DXILArgSelect ArgSelect;
214+
if (IsI8) {
215+
ArgSelect.Type = DXILArgSelect::Type::I8;
216+
ArgSelect.Value = ValueRec->getValueAsInt("value");
217+
} else if (IsI32) {
218+
ArgSelect.Type = DXILArgSelect::Type::I32;
219+
ArgSelect.Value = ValueRec->getValueAsInt("value");
220+
} else {
221+
if (Index < 0) {
222+
PrintFatalError(
223+
R, Twine("Index in ArgSelect<index> must be equal to or "
224+
"greater than 0 for DXIL operation - ") +
225+
OpName);
226+
}
227+
ArgSelect.Type = DXILArgSelect::Type::Index;
228+
ArgSelect.Value = Index;
229+
}
230+
231+
IntrSelect.Args.emplace_back(std::move(ArgSelect));
198232
}
199233
IntrinsicSelects.emplace_back(std::move(IntrSelect));
200234
}
@@ -415,11 +449,23 @@ static void emitDXILIntrinsicMap(ArrayRef<DXILOperationDesc> Ops,
415449
}
416450
for (const DXILIntrinsicSelect &MappedIntr : Op.IntrinsicSelects) {
417451
OS << "DXIL_OP_INTRINSIC(dxil::OpCode::" << Op.OpName
418-
<< ", Intrinsic::" << MappedIntr.Intrinsic << ", (ArrayRef<Value *> {";
419-
for (const StringRef &Arg : MappedIntr.ExtraArgs) {
420-
OS << Arg << ", ";
452+
<< ", Intrinsic::" << MappedIntr.Intrinsic;
453+
for (const DXILArgSelect &ArgSelect : MappedIntr.Args) {
454+
OS << ", (Arg { ";
455+
switch (ArgSelect.Type) {
456+
case DXILArgSelect::Type::Index:
457+
OS << "Arg::Type::Index, ";
458+
break;
459+
case DXILArgSelect::Type::I8:
460+
OS << "Arg::Type::I8, ";
461+
break;
462+
case DXILArgSelect::Type::I32:
463+
OS << "Arg::Type::I32, ";
464+
break;
465+
}
466+
OS << ArgSelect.Value << "})";
421467
}
422-
OS << "}))\n";
468+
OS << ")\n";
423469
}
424470
}
425471
OS << "\n";

0 commit comments

Comments
 (0)