Skip to content

Commit 9ffab56

Browse files
authored
[SPIR-V] Initial implementation of SPV_INTEL_long_composites (#126545)
This change introduces support of `OpTypeStructContinuedINTEL` instruction. Specification: https://github.khronos.org/SPIRV-Registry/extensions/INTEL/SPV_INTEL_long_composites.html
1 parent 24cd933 commit 9ffab56

File tree

7 files changed

+97
-10
lines changed

7 files changed

+97
-10
lines changed

llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
8686
{"SPV_KHR_cooperative_matrix",
8787
SPIRV::Extension::Extension::SPV_KHR_cooperative_matrix},
8888
{"SPV_KHR_non_semantic_info",
89-
SPIRV::Extension::Extension::SPV_KHR_non_semantic_info}};
89+
SPIRV::Extension::Extension::SPV_KHR_non_semantic_info},
90+
{"SPV_INTEL_long_composites",
91+
SPIRV::Extension::Extension::SPV_INTEL_long_composites}};
9092

9193
bool SPIRVExtensionsParser::parse(cl::Option &O, llvm::StringRef ArgName,
9294
llvm::StringRef ArgValue,

llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -882,23 +882,46 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeStruct(const StructType *Ty,
882882
MachineIRBuilder &MIRBuilder,
883883
bool EmitIR) {
884884
SmallVector<Register, 4> FieldTypes;
885+
constexpr unsigned MaxWordCount = UINT16_MAX;
886+
const size_t NumElements = Ty->getNumElements();
887+
888+
size_t MaxNumElements = MaxWordCount - 2;
889+
size_t SPIRVStructNumElements = NumElements;
890+
if (NumElements > MaxNumElements) {
891+
// Do adjustments for continued instructions.
892+
SPIRVStructNumElements = MaxNumElements;
893+
MaxNumElements = MaxWordCount - 1;
894+
}
895+
885896
for (const auto &Elem : Ty->elements()) {
886897
SPIRVType *ElemTy = findSPIRVType(toTypedPointer(Elem), MIRBuilder);
887898
assert(ElemTy && ElemTy->getOpcode() != SPIRV::OpTypeVoid &&
888899
"Invalid struct element type");
889900
FieldTypes.push_back(getSPIRVTypeID(ElemTy));
890901
}
891902
Register ResVReg = createTypeVReg(MIRBuilder);
892-
return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
903+
if (Ty->hasName())
904+
buildOpName(ResVReg, Ty->getName(), MIRBuilder);
905+
if (Ty->isPacked())
906+
buildOpDecorate(ResVReg, MIRBuilder, SPIRV::Decoration::CPacked, {});
907+
908+
auto SPVType = createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
893909
auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeStruct).addDef(ResVReg);
894-
for (const auto &Ty : FieldTypes)
895-
MIB.addUse(Ty);
896-
if (Ty->hasName())
897-
buildOpName(ResVReg, Ty->getName(), MIRBuilder);
898-
if (Ty->isPacked())
899-
buildOpDecorate(ResVReg, MIRBuilder, SPIRV::Decoration::CPacked, {});
910+
for (size_t I = 0; I < SPIRVStructNumElements; ++I)
911+
MIB.addUse(FieldTypes[I]);
900912
return MIB;
901913
});
914+
915+
for (size_t I = SPIRVStructNumElements; I < NumElements;
916+
I += MaxNumElements) {
917+
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
918+
auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeStructContinuedINTEL);
919+
for (size_t J = I; J < std::min(I + MaxNumElements, NumElements); ++J)
920+
MIB.addUse(FieldTypes[I]);
921+
return MIB;
922+
});
923+
}
924+
return SPVType;
902925
}
903926

904927
SPIRVType *SPIRVGlobalRegistry::getOrCreateSpecialType(
@@ -968,7 +991,8 @@ SPIRVType *SPIRVGlobalRegistry::findSPIRVType(
968991

969992
Register SPIRVGlobalRegistry::getSPIRVTypeID(const SPIRVType *SpirvType) const {
970993
assert(SpirvType && "Attempting to get type id for nullptr type.");
971-
if (SpirvType->getOpcode() == SPIRV::OpTypeForwardPointer)
994+
if (SpirvType->getOpcode() == SPIRV::OpTypeForwardPointer ||
995+
SpirvType->getOpcode() == SPIRV::OpTypeStructContinuedINTEL)
972996
return SpirvType->uses().begin()->getReg();
973997
return SpirvType->defs().begin()->getReg();
974998
}

llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,14 @@ bool SPIRVInstrInfo::isConstantInstr(const MachineInstr &MI) const {
3232
case SPIRV::OpConstantI:
3333
case SPIRV::OpConstantF:
3434
case SPIRV::OpConstantComposite:
35+
case SPIRV::OpConstantCompositeContinuedINTEL:
3536
case SPIRV::OpConstantSampler:
3637
case SPIRV::OpConstantNull:
3738
case SPIRV::OpSpecConstantTrue:
3839
case SPIRV::OpSpecConstantFalse:
3940
case SPIRV::OpSpecConstant:
4041
case SPIRV::OpSpecConstantComposite:
42+
case SPIRV::OpSpecConstantCompositeContinuedINTEL:
4143
case SPIRV::OpSpecConstantOp:
4244
case SPIRV::OpUndef:
4345
case SPIRV::OpConstantFunctionPointerINTEL:
@@ -76,7 +78,8 @@ bool SPIRVInstrInfo::isTypeDeclInstr(const MachineInstr &MI) const {
7678
auto DefRegClass = MRI.getRegClassOrNull(MI.getOperand(0).getReg());
7779
return DefRegClass && DefRegClass->getID() == SPIRV::TYPERegClass.getID();
7880
} else {
79-
return MI.getOpcode() == SPIRV::OpTypeForwardPointer;
81+
return MI.getOpcode() == SPIRV::OpTypeForwardPointer ||
82+
MI.getOpcode() == SPIRV::OpTypeStructContinuedINTEL;
8083
}
8184
}
8285

llvm/lib/Target/SPIRV/SPIRVInstrInfo.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ def OpTypeArray: Op<28, (outs TYPE:$type), (ins TYPE:$elementType, ID:$length),
188188
def OpTypeRuntimeArray: Op<29, (outs TYPE:$type), (ins TYPE:$elementType),
189189
"$type = OpTypeRuntimeArray $elementType">;
190190
def OpTypeStruct: Op<30, (outs TYPE:$res), (ins variable_ops), "$res = OpTypeStruct">;
191+
def OpTypeStructContinuedINTEL: Op<6090, (outs), (ins variable_ops),
192+
"OpTypeStructContinuedINTEL">;
191193
def OpTypeOpaque: Op<31, (outs TYPE:$res), (ins StringImm:$name, variable_ops),
192194
"$res = OpTypeOpaque $name">;
193195
def OpTypePointer: Op<32, (outs TYPE:$res), (ins StorageClass:$storage, TYPE:$type),
@@ -252,6 +254,9 @@ defm OpConstant: IntFPImm<43, "OpConstant">;
252254

253255
def OpConstantComposite: Op<44, (outs ID:$res), (ins TYPE:$type, variable_ops),
254256
"$res = OpConstantComposite $type">;
257+
def OpConstantCompositeContinuedINTEL: Op<6091, (outs), (ins variable_ops),
258+
"OpConstantCompositeContinuedINTEL">;
259+
255260
def OpConstantSampler: Op<45, (outs ID:$res),
256261
(ins TYPE:$t, SamplerAddressingMode:$s, i32imm:$p, SamplerFilterMode:$f),
257262
"$res = OpConstantSampler $t $s $p $f">;
@@ -263,6 +268,8 @@ def OpSpecConstant: Op<50, (outs ID:$res), (ins TYPE:$type, i32imm:$imm, variabl
263268
"$res = OpSpecConstant $type $imm">;
264269
def OpSpecConstantComposite: Op<51, (outs ID:$res), (ins TYPE:$type, variable_ops),
265270
"$res = OpSpecConstantComposite $type">;
271+
def OpSpecConstantCompositeContinuedINTEL: Op<6092, (outs), (ins variable_ops),
272+
"OpSpecConstantCompositeContinuedINTEL">;
266273
def OpSpecConstantOp: Op<52, (outs ID:$res), (ins TYPE:$t, i32imm:$c, ID:$o, variable_ops),
267274
"$res = OpSpecConstantOp $t $c $o">;
268275

@@ -476,6 +483,8 @@ def OpVectorShuffle: Op<79, (outs ID:$res), (ins TYPE:$ty, ID:$v1, ID:$v2, varia
476483
"$res = OpVectorShuffle $ty $v1 $v2">;
477484
def OpCompositeConstruct: Op<80, (outs ID:$res), (ins TYPE:$type, variable_ops),
478485
"$res = OpCompositeConstruct $type">;
486+
def OpCompositeConstructContinuedINTEL: Op<6096, (outs), (ins variable_ops),
487+
"OpCompositeConstructContinuedINTEL">;
479488
def OpCompositeExtract: Op<81, (outs ID:$res), (ins TYPE:$type, ID:$base, variable_ops),
480489
"$res = OpCompositeExtract $type $base">;
481490
def OpCompositeInsert: Op<82, (outs ID:$r), (ins TYPE:$ty, ID:$obj, ID:$base, variable_ops),

llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,16 @@ void SPIRVModuleAnalysis::visitDecl(
362362
} else if (Opcode == SPIRV::OpFunction ||
363363
Opcode == SPIRV::OpFunctionParameter) {
364364
GReg = handleFunctionOrParameter(MF, MI, GlobalToGReg, IsFunDef);
365+
} else if (Opcode == SPIRV::OpTypeStruct) {
366+
GReg = handleTypeDeclOrConstant(MI, SignatureToGReg);
367+
const MachineInstr *NextInstr = MI.getNextNode();
368+
while (NextInstr &&
369+
NextInstr->getOpcode() == SPIRV::OpTypeStructContinuedINTEL) {
370+
Register Tmp = handleTypeDeclOrConstant(*NextInstr, SignatureToGReg);
371+
MAI.setRegisterAlias(MF, NextInstr->getOperand(0).getReg(), Tmp);
372+
MAI.setSkipEmission(NextInstr);
373+
NextInstr = NextInstr->getNextNode();
374+
}
365375
} else if (TII->isTypeDeclInstr(MI) || TII->isConstantInstr(MI) ||
366376
TII->isInlineAsmDefInstr(MI)) {
367377
GReg = handleTypeDeclOrConstant(MI, SignatureToGReg);
@@ -1725,6 +1735,19 @@ void addInstrRequirements(const MachineInstr &MI,
17251735
Reqs.addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
17261736
break;
17271737
}
1738+
case SPIRV::OpTypeStructContinuedINTEL:
1739+
case SPIRV::OpConstantCompositeContinuedINTEL:
1740+
case SPIRV::OpSpecConstantCompositeContinuedINTEL:
1741+
case SPIRV::OpCompositeConstructContinuedINTEL: {
1742+
if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_long_composites))
1743+
report_fatal_error(
1744+
"Continued instructions require the "
1745+
"following SPIR-V extension: SPV_INTEL_long_composites",
1746+
false);
1747+
Reqs.addExtension(SPIRV::Extension::SPV_INTEL_long_composites);
1748+
Reqs.addCapability(SPIRV::Capability::LongCompositesINTEL);
1749+
break;
1750+
}
17281751

17291752
default:
17301753
break;

llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ defm SPV_EXT_optnone : ExtensionOperand<113>;
310310
defm SPV_INTEL_joint_matrix : ExtensionOperand<114>;
311311
defm SPV_INTEL_float_controls2 : ExtensionOperand<115>;
312312
defm SPV_INTEL_bindless_images : ExtensionOperand<116>;
313+
defm SPV_INTEL_long_composites : ExtensionOperand<117>;
313314

314315
//===----------------------------------------------------------------------===//
315316
// Multiclass used to define Capabilities enum values and at the same time
@@ -506,6 +507,7 @@ defm CooperativeMatrixBFloat16ComponentTypeINTEL : CapabilityOperand<6437, 0, 0,
506507
defm RoundToInfinityINTEL : CapabilityOperand<5582, 0, 0, [SPV_INTEL_float_controls2], []>;
507508
defm FloatingPointModeINTEL : CapabilityOperand<5583, 0, 0, [SPV_INTEL_float_controls2], []>;
508509
defm FunctionFloatControlINTEL : CapabilityOperand<5821, 0, 0, [SPV_INTEL_float_controls2], []>;
510+
defm LongCompositesINTEL : CapabilityOperand<6089, 0, 0, [SPV_INTEL_long_composites], []>;
509511
defm BindlessImagesINTEL : CapabilityOperand<6528, 0, 0, [SPV_INTEL_bindless_images], []>;
510512

511513
//===----------------------------------------------------------------------===//

llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_long_composites/long-type-struct.ll

Lines changed: 24 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)