Skip to content

Commit cfbe6f8

Browse files
ViacheslavRbigcbot
authored andcommitted
Implemented SPV_INTEL_unstructured_loop_controls extension,
that adds a new capability: UnstructuredLoopControlsINTEL and a new instruction: LoopControlINTEL. This instruction can be used in place of an OpLoopMerge on unstructured loops. This is port of KhronosGroup/SPIRV-LLVM-Translator@3b6882e
1 parent 73f568c commit cfbe6f8

File tree

5 files changed

+71
-10
lines changed

5 files changed

+71
-10
lines changed

IGC/AdaptorOCL/SPIRV/SPIRVReader.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,7 +1478,8 @@ class SPIRVToLLVM {
14781478
template<class Source, class Func>
14791479
bool foreachFuncCtlMask(Source, Func);
14801480

1481-
void setLLVMLoopMetadata(SPIRVLoopMerge* LM, BranchInst* BI);
1481+
template <typename LoopInstType>
1482+
void setLLVMLoopMetadata(LoopInstType* LM, BranchInst* BI);
14821483
inline llvm::Metadata *getMetadataFromName(std::string Name);
14831484
inline std::vector<llvm::Metadata *>
14841485
getMetadataFromNameAndParameter(std::string Name, SPIRVWord Parameter);
@@ -1707,7 +1708,8 @@ SPIRVToLLVM::getMetadataFromNameAndParameter(std::string Name,
17071708
}
17081709

17091710

1710-
void SPIRVToLLVM::setLLVMLoopMetadata(SPIRVLoopMerge *LM, BranchInst *BI) {
1711+
template <typename LoopInstType>
1712+
void SPIRVToLLVM::setLLVMLoopMetadata(LoopInstType* LM, BranchInst* BI) {
17111713
if (!LM)
17121714
return;
17131715
auto Temp = MDNode::getTemporary(*Context, None);
@@ -2817,9 +2819,14 @@ SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
28172819
dyn_cast<BasicBlock>(transValue(BR->getTargetLabel(), F, BB)), BB);
28182820

28192821
SPIRVInstruction *Prev = BR->getPrevious();
2820-
if(Prev && Prev->getOpCode() == OpLoopMerge)
2821-
if (auto LM = static_cast<SPIRVLoopMerge *>(Prev))
2822-
setLLVMLoopMetadata(LM, BI);
2822+
if(Prev && Prev->getOpCode() == OpLoopMerge) {
2823+
auto LM = static_cast<SPIRVLoopMerge*>(Prev);
2824+
setLLVMLoopMetadata<SPIRVLoopMerge>(LM, BI);
2825+
}
2826+
else if (Prev && Prev->getOpCode() == OpLoopControlINTEL) {
2827+
auto LCI = static_cast<SPIRVLoopControlINTEL*>(Prev);
2828+
setLLVMLoopMetadata<SPIRVLoopControlINTEL>(LCI, BI);
2829+
}
28232830

28242831
return mapValue(BV, BI);
28252832
}
@@ -2836,9 +2843,14 @@ SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
28362843
BB);
28372844

28382845
SPIRVInstruction *Prev = BR->getPrevious();
2839-
if (Prev && Prev->getOpCode() == OpLoopMerge)
2846+
if (Prev && Prev->getOpCode() == OpLoopMerge) {
28402847
if (auto LM = static_cast<SPIRVLoopMerge *>(Prev))
2841-
setLLVMLoopMetadata(LM, BC);
2848+
setLLVMLoopMetadata<SPIRVLoopMerge>(LM, BC);
2849+
}
2850+
else if (Prev && Prev->getOpCode() == OpLoopControlINTEL) {
2851+
if (auto LCI = static_cast<SPIRVLoopControlINTEL *>(Prev))
2852+
setLLVMLoopMetadata<SPIRVLoopControlINTEL>(LCI, BC);
2853+
}
28422854

28432855
return mapValue(BV, BC);
28442856
}
@@ -3014,7 +3026,9 @@ SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
30143026
break;
30153027
// OpenCL Compiler does not use this instruction
30163028
// Should be translated at OpBranch or OpBranchConditional cases
3017-
case OpLoopMerge: {
3029+
case OpLoopMerge:
3030+
case OpLoopControlINTEL:
3031+
{
30183032
return nullptr;
30193033
}
30203034
break;

IGC/AdaptorOCL/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,52 @@ typedef SPIRVAccessChainGeneric<OpPtrAccessChain, 5> SPIRVPtrAccessChain;
10801080
typedef SPIRVAccessChainGeneric<OpInBoundsPtrAccessChain, 5>
10811081
SPIRVInBoundsPtrAccessChain;
10821082

1083+
class SPIRVLoopControlINTEL : public SPIRVInstruction {
1084+
public:
1085+
static const Op OC = OpLoopControlINTEL;
1086+
static const SPIRVWord FixedWordCount = 2;
1087+
1088+
SPIRVLoopControlINTEL(SPIRVWord TheLoopControl,
1089+
std::vector<SPIRVWord> TheLoopControlParameters,
1090+
SPIRVBasicBlock* BB)
1091+
: SPIRVInstruction(FixedWordCount + TheLoopControlParameters.size(), OC,
1092+
BB),
1093+
LoopControl(TheLoopControl),
1094+
LoopControlParameters(TheLoopControlParameters) {
1095+
validate();
1096+
IGC_ASSERT_MESSAGE(BB, "Invalid BB");
1097+
}
1098+
1099+
SPIRVLoopControlINTEL() : SPIRVInstruction(OC), LoopControl(SPIRVWORD_MAX) {
1100+
setHasNoId();
1101+
setHasNoType();
1102+
}
1103+
1104+
SPIRVWord getLoopControl() { return LoopControl; }
1105+
1106+
std::vector<SPIRVWord> getLoopControlParameters() {
1107+
return LoopControlParameters;
1108+
}
1109+
1110+
CapVec getRequiredCapability() const override {
1111+
return getVec(CapabilityUnstructuredLoopControlsINTEL);
1112+
}
1113+
1114+
// SPIRVExtSet getRequiredExtensions() const override { // getRequiredExtensions() is not supported yet
1115+
// return getSet(SPV_INTEL_unstructured_loop_controls);
1116+
// }
1117+
1118+
void setWordCount(SPIRVWord TheWordCount) override {
1119+
SPIRVEntry::setWordCount(TheWordCount);
1120+
LoopControlParameters.resize(TheWordCount - FixedWordCount);
1121+
}
1122+
_SPIRV_DEF_DEC2(LoopControl, LoopControlParameters)
1123+
1124+
protected:
1125+
SPIRVWord LoopControl;
1126+
std::vector<SPIRVWord> LoopControlParameters;
1127+
};
1128+
10831129
template<Op OC, SPIRVWord FixedWordCount>
10841130
class SPIRVFunctionCallGeneric: public SPIRVInstruction {
10851131
public:

IGC/AdaptorOCL/SPIRV/libSPIRV/SPIRVModule.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,12 @@ class SPIRVModuleImpl : public SPIRVModule {
215215
virtual SPIRVValue *addConstant(SPIRVValue *) override;
216216
virtual SPIRVValue *addConstant(SPIRVType *, uint64_t) override;
217217

218+
// Instruction creation functions
218219
virtual SPIRVInstruction *addLoopMergeInst(
219220
SPIRVId MergeBlock, SPIRVId ContinueTarget,
220221
SPIRVWord LoopControl,
221222
std::vector<SPIRVWord> LoopControlParameters,
222223
SPIRVBasicBlock *BB) override;
223-
224-
// Instruction creation functions
225224
virtual SPIRVInstruction *
226225
addInstruction(SPIRVInstruction *Inst, SPIRVBasicBlock *BB,
227226
SPIRVInstruction *InsertBefore = nullptr);

IGC/AdaptorOCL/SPIRV/libSPIRV/SPIRVOpCodeEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,3 +507,4 @@ _SPIRV_OP(SubgroupAvcSicGetInterRawSadsINTEL, 5816)
507507
_SPIRV_OP(VariableLengthArrayINTEL, 5818)
508508
_SPIRV_OP(SaveMemoryINTEL, 5819)
509509
_SPIRV_OP(RestoreMemoryINTEL, 5820)
510+
_SPIRV_OP(LoopControlINTEL, 5887)

IGC/AdaptorOCL/SPIRV/libSPIRV/spirv.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,7 @@ enum Capability {
613613
CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
614614
CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
615615
CapabilityVariableLengthArrayINTEL = 5817,
616+
CapabilityUnstructuredLoopControlsINTEL = 5886,
616617
};
617618

618619
enum Op {

0 commit comments

Comments
 (0)