Skip to content

Commit 142b988

Browse files
committed
All working now
1 parent 36dbb21 commit 142b988

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
@@ -293,9 +293,41 @@ class Attributes<Version ver = DXIL1_0, list<DXILAttribute> attrs> {
293293
list<DXILAttribute> op_attrs = attrs;
294294
}
295295

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

301333
// Abstraction DXIL Operation
@@ -823,7 +855,7 @@ def Barrier : DXILOp<80, barrier> {
823855
let intrinsic_selects = [
824856
IntrinsicSelect<
825857
int_dx_group_memory_barrier_with_group_sync,
826-
[ "OpBuilder.getIRB().getInt32((unsigned)BarrierMode::SyncThreadGroup | (unsigned)BarrierMode::TGSMFence)" ]>,
858+
[ ArgI32<BarrierMode_GroupMemoryBarrierWithGroupSync> ]>,
827859
];
828860

829861
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
@@ -105,19 +105,44 @@ class OpLowerer {
105105
return false;
106106
}
107107

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

118-
NewArgs.append(ExtraArgs.begin(), ExtraArgs.end());
119-
120-
OpBuilder.getIRB().SetInsertPoint(CI);
121146
Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
122147
DXILOp, NewArgs, CI->getName(), F.getReturnType());
123148
if (Error E = OpCall.takeError())
@@ -473,9 +498,10 @@ class OpLowerer {
473498
switch (ID) {
474499
default:
475500
continue;
476-
#define DXIL_OP_INTRINSIC(OpCode, Intrin, ExtraArgs) \
477-
case Intrin: \
478-
HasErrors |= replaceFunctionWithOp(F, OpCode, ExtraArgs); \
501+
#define DXIL_OP_INTRINSIC(OpCode, Intrin, ...) \
502+
case Intrin: \
503+
HasErrors |= replaceFunctionWithOp(F, OpCode, \
504+
ArrayRef<Arg>{ __VA_ARGS__ }); \
479505
break;
480506
#include "DXILOperation.inc"
481507
case Intrinsic::dx_handle_fromBinding:

llvm/utils/TableGen/DXILEmitter.cpp

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

3434
namespace {
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+
};
3645
struct DXILIntrinsicSelect {
3746
StringRef Intrinsic;
38-
SmallVector<StringRef, 4> ExtraArgs;
47+
SmallVector<DXILArgSelect, 4> Args;
3948
};
4049

4150
struct 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 (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 (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

Comments
 (0)