diff options
author | kkyzylov <ksenia.kyzylova@intel.com> | 2016-10-12 21:20:31 +0300 |
---|---|---|
committer | Yaxun (Sam) Liu <yaxun.liu@amd.com> | 2016-10-12 14:20:31 -0400 |
commit | 9fa297ba488462588a1a606765b6849013b90aca (patch) | |
tree | cb81435963153842d764851a86d94c0b2a0541b1 | |
parent | 6a1bbcba8e9e0810fdf6f4d1546099a075176001 (diff) |
Translation of OpLoopMerge (#192)
-rw-r--r-- | lib/SPIRV/SPIRVReader.cpp | 56 | ||||
-rw-r--r-- | lib/SPIRV/libSPIRV/SPIRVEntry.h | 1 | ||||
-rw-r--r-- | lib/SPIRV/libSPIRV/SPIRVInstruction.h | 30 | ||||
-rw-r--r-- | lib/SPIRV/libSPIRV/SPIRVModule.cpp | 9 | ||||
-rw-r--r-- | lib/SPIRV/libSPIRV/SPIRVModule.h | 2 | ||||
-rw-r--r-- | test/OpLoopMergeDontUnroll.spt | 91 | ||||
-rw-r--r-- | test/OpLoopMergeNone.spt | 87 | ||||
-rw-r--r-- | test/OpLoopMergeUnroll.spt | 88 |
8 files changed, 353 insertions, 11 deletions
diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index a6b4163..b409162 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -496,6 +496,7 @@ private: Value *oclTransConstantSampler(SPIRV::SPIRVConstantSampler* BCS);
Value * oclTransConstantPipeStorage(SPIRV::SPIRVConstantPipeStorage* BCPS);
void setName(llvm::Value* V, SPIRVValue* BV);
+ void setLLVMLoopMetadata(SPIRVLoopMerge* LM, BranchInst* BI);
void insertImageNameAccessQualifier(SPIRV::SPIRVTypeImage* ST, std::string &Name);
template<class Source, class Func>
bool foreachFuncCtlMask(Source, Func);
@@ -904,6 +905,37 @@ SPIRVToLLVM::setName(llvm::Value* V, SPIRVValue* BV) { V->setName(Name);
}
+void
+SPIRVToLLVM::setLLVMLoopMetadata(SPIRVLoopMerge* LM, BranchInst* BI) {
+ if (!LM)
+ return;
+ llvm::MDString *Name = nullptr; + auto Temp = MDNode::getTemporary(*Context, None); + auto Self = MDNode::get(*Context, Temp); + Self->replaceOperandWith(0, Self); + MDNode::deleteTemporary(Temp); + + if (LM->getLoopControl() == LoopControlMaskNone) { + BI->setMetadata("llvm.loop", Self); + return; + } + else if(LM->getLoopControl() == LoopControlUnrollMask) + Name = llvm::MDString::get(*Context, "llvm.loop.unroll.full"); + else if (LM->getLoopControl() == LoopControlDontUnrollMask) + Name = llvm::MDString::get(*Context, "llvm.loop.unroll.disable"); + else + return; + + std::vector<llvm::Metadata *> OpValues(1, Name); + SmallVector<llvm::Metadata *, 2> Metadata; + Metadata.push_back(llvm::MDNode::get(*Context, Self)); + Metadata.push_back(llvm::MDNode::get(*Context, OpValues)); + + llvm::MDNode *Node = llvm::MDNode::get(*Context, Metadata); + Node->replaceOperandWith(0, Node); + BI->setMetadata("llvm.loop", Node);
+}
+
void SPIRVToLLVM::insertImageNameAccessQualifier(SPIRV::SPIRVTypeImage* ST, std::string &Name) {
std::string QName = rmap<std::string>(ST->getAccessQualifier());
// transform: read_only -> ro, write_only -> wo, read_write -> rw
@@ -1524,17 +1556,22 @@ SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, switch (BV->getOpCode()) {
case OpBranch: {
auto BR = static_cast<SPIRVBranch *>(BV);
- return mapValue(BV, BranchInst::Create(
- dyn_cast<BasicBlock>(transValue(BR->getTargetLabel(), F, BB)), BB));
+ auto BI = BranchInst::Create(
+ dyn_cast<BasicBlock>(transValue(BR->getTargetLabel(), F, BB)), BB);
+ if (auto LM = static_cast<SPIRVLoopMerge *>(BR->getPrevious()))
+ setLLVMLoopMetadata(LM, BI);
+ return mapValue(BV, BI);
}
case OpBranchConditional: {
auto BR = static_cast<SPIRVBranchConditional *>(BV);
- return mapValue(
- BV, BranchInst::Create(
- dyn_cast<BasicBlock>(transValue(BR->getTrueLabel(), F, BB)),
- dyn_cast<BasicBlock>(transValue(BR->getFalseLabel(), F, BB)),
- transValue(BR->getCondition(), F, BB), BB));
+ auto BC = BranchInst::Create(
+ dyn_cast<BasicBlock>(transValue(BR->getTrueLabel(), F, BB)),
+ dyn_cast<BasicBlock>(transValue(BR->getFalseLabel(), F, BB)),
+ transValue(BR->getCondition(), F, BB), BB);
+ if (auto LM = static_cast<SPIRVLoopMerge *>(BR->getPrevious()))
+ setLLVMLoopMetadata(LM, BC);
+ return mapValue(BV, BC);
}
case OpPhi: {
@@ -1662,10 +1699,9 @@ SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, }
case OpLine:
- case OpSelectionMerge: {
- // OpenCL Compiler does not use this instruction
+ case OpSelectionMerge: // OpenCL Compiler does not use this instruction
+ case OpLoopMerge: // Should be translated at OpBranch or OpBranchConditional cases
return nullptr;
- }
case OpSwitch: {
auto BS = static_cast<SPIRVSwitch *>(BV);
diff --git a/lib/SPIRV/libSPIRV/SPIRVEntry.h b/lib/SPIRV/libSPIRV/SPIRVEntry.h index 4092b16..3355e97 100644 --- a/lib/SPIRV/libSPIRV/SPIRVEntry.h +++ b/lib/SPIRV/libSPIRV/SPIRVEntry.h @@ -751,7 +751,6 @@ _SPIRV_OP(EmitVertex) _SPIRV_OP(EndPrimitive)
_SPIRV_OP(EmitStreamVertex)
_SPIRV_OP(EndStreamPrimitive)
-_SPIRV_OP(LoopMerge)
_SPIRV_OP(Kill)
_SPIRV_OP(ImageSparseSampleImplicitLod, 305)
_SPIRV_OP(ImageSparseSampleExplicitLod, 306)
diff --git a/lib/SPIRV/libSPIRV/SPIRVInstruction.h b/lib/SPIRV/libSPIRV/SPIRVInstruction.h index 2a5223d..dffdcc8 100644 --- a/lib/SPIRV/libSPIRV/SPIRVInstruction.h +++ b/lib/SPIRV/libSPIRV/SPIRVInstruction.h @@ -1016,6 +1016,36 @@ protected: SPIRVWord SelectionControl;
};
+class SPIRVLoopMerge : public SPIRVInstruction {
+public:
+ static const Op OC = OpLoopMerge;
+ static const SPIRVWord FixedWordCount = 4;
+
+ SPIRVLoopMerge(SPIRVId TheMergeBlock, SPIRVId TheContinueTarget,
+ SPIRVWord TheLoopControl, SPIRVBasicBlock *BB)
+ :SPIRVInstruction(FixedWordCount, OC, BB), MergeBlock(TheMergeBlock),
+ ContinueTarget(TheContinueTarget), LoopControl(TheLoopControl) {
+ validate();
+ assert(BB && "Invalid BB");
+ }
+
+ SPIRVLoopMerge() : SPIRVInstruction(OC), MergeBlock(SPIRVID_MAX),
+ LoopControl(SPIRVWORD_MAX) {
+ setHasNoId();
+ setHasNoType();
+ }
+
+ SPIRVId getMergeBlock() { return MergeBlock; }
+ SPIRVId getContinueTarget() { return ContinueTarget; }
+ SPIRVWord getLoopControl() { return LoopControl; }
+ _SPIRV_DEF_ENCDEC3(MergeBlock, ContinueTarget, LoopControl)
+
+protected:
+ SPIRVId MergeBlock;
+ SPIRVId ContinueTarget;
+ SPIRVWord LoopControl;
+};
+
class SPIRVSwitch: public SPIRVInstruction {
public:
static const Op OC = OpSwitch;
diff --git a/lib/SPIRV/libSPIRV/SPIRVModule.cpp b/lib/SPIRV/libSPIRV/SPIRVModule.cpp index f3058d5..d24db9b 100644 --- a/lib/SPIRV/libSPIRV/SPIRVModule.cpp +++ b/lib/SPIRV/libSPIRV/SPIRVModule.cpp @@ -287,6 +287,8 @@ public: virtual SPIRVInstruction *addReturnValueInst(SPIRVValue *, SPIRVBasicBlock *);
virtual SPIRVInstruction *addSelectInst(SPIRVValue *, SPIRVValue *, SPIRVValue *,
SPIRVBasicBlock *);
+ virtual SPIRVInstruction *addLoopMergeInst(SPIRVId MergeBlock,
+ SPIRVId ContinueTarget, SPIRVWord LoopControl, SPIRVBasicBlock *BB);
virtual SPIRVInstruction *addSelectionMergeInst(SPIRVId MergeBlock,
SPIRVWord SelectionControl, SPIRVBasicBlock *BB);
virtual SPIRVInstruction *addStoreInst(SPIRVValue *, SPIRVValue *,
@@ -1149,6 +1151,13 @@ SPIRVModuleImpl::addSelectionMergeInst(SPIRVId MergeBlock, }
SPIRVInstruction *
+SPIRVModuleImpl::addLoopMergeInst(SPIRVId MergeBlock, SPIRVId ContinueTarget,
+ SPIRVWord LoopControl, SPIRVBasicBlock *BB) {
+ return addInstruction(new SPIRVLoopMerge(MergeBlock, ContinueTarget,
+ LoopControl, BB), BB);
+}
+
+SPIRVInstruction *
SPIRVModuleImpl::addPtrAccessChainInst(SPIRVType *Type, SPIRVValue *Base,
std::vector<SPIRVValue *> Indices, SPIRVBasicBlock *BB, bool IsInBounds){
return addInstruction(SPIRVInstTemplateBase::create(
diff --git a/lib/SPIRV/libSPIRV/SPIRVModule.h b/lib/SPIRV/libSPIRV/SPIRVModule.h index 21b8a66..a5e3f28 100644 --- a/lib/SPIRV/libSPIRV/SPIRVModule.h +++ b/lib/SPIRV/libSPIRV/SPIRVModule.h @@ -298,6 +298,8 @@ public: SPIRVBasicBlock *) = 0;
virtual SPIRVInstruction *addSelectionMergeInst(SPIRVId MergeBlock,
SPIRVWord SelectionControl, SPIRVBasicBlock *BB) = 0;
+ virtual SPIRVInstruction *addLoopMergeInst(SPIRVId MergeBlock,
+ SPIRVId ContinueTarget, SPIRVWord LoopControl, SPIRVBasicBlock *BB) = 0;
virtual SPIRVInstruction *addStoreInst(SPIRVValue *, SPIRVValue *,
const std::vector<SPIRVWord>&, SPIRVBasicBlock *) = 0;
virtual SPIRVInstruction *addSwitchInst(SPIRVValue *, SPIRVBasicBlock *,
diff --git a/test/OpLoopMergeDontUnroll.spt b/test/OpLoopMergeDontUnroll.spt new file mode 100644 index 0000000..0689925 --- /dev/null +++ b/test/OpLoopMergeDontUnroll.spt @@ -0,0 +1,91 @@ +119734787 65536 458752 46 0
+2 Capability Addresses
+2 Capability Linkage
+2 Capability Kernel
+2 Capability Int64
+3 MemoryModel 2 2
+11 EntryPoint 6 1 "loop_merge_branch_dont_unroll"
+3 Source 3 102000
+3 Name 2 "res"
+3 Name 3 "in"
+3 Name 4 "rep"
+3 Name 5 "num"
+4 Decorate 6 FuncParamAttr 5
+2 DecorationGroup 6
+4 Decorate 7 BuiltIn 28
+3 Decorate 7 Constant
+11 Decorate 7 LinkageAttributes "__spirv_GlobalInvocationId" Import
+4 GroupDecorate 6 2 3
+4 TypeInt 8 64 0
+4 TypeInt 14 32 1
+5 Constant 8 11 32 0
+4 Constant 14 15 0
+4 Constant 14 16 1
+4 TypeVector 9 8 3
+4 TypePointer 10 0 9
+2 TypeBool 12
+2 TypeVoid 13
+4 TypePointer 17 5 14
+4 TypePointer 18 7 14
+7 TypeFunction 19 13 17 17 14 14
+4 Variable 10 7 0
+
+5 Function 13 1 0 19
+3 FunctionParameter 17 2
+3 FunctionParameter 17 3
+3 FunctionParameter 14 4
+3 FunctionParameter 14 5
+
+2 Label 20
+6 Load 9 21 7 2 0
+5 CompositeExtract 8 22 21 0
+5 ShiftLeftLogical 8 23 22 11
+5 ShiftRightArithmetic 8 24 23 11
+4 SConvert 14 25 24
+4 Variable 18 26 7
+4 Variable 18 27 7
+5 Store 26 15 2 4
+5 Store 27 15 2 4
+2 Branch 28
+
+2 Label 28
+4 LoopMerge 29 30 2
+2 Branch 31
+
+2 Label 31
+4 Load 14 32 27
+5 SLessThan 12 33 32 4
+4 BranchConditional 33 34 29
+
+2 Label 34
+4 Load 14 35 27
+5 IMul 14 36 35 5
+5 IAdd 14 37 25 36
+5 InBoundsPtrAccessChain 17 38 3 37
+4 Load 14 39 38
+4 Load 14 40 26
+5 IAdd 14 41 40 39
+5 Store 26 41 2 4
+2 Branch 30
+
+2 Label 30
+4 Load 14 42 27
+5 IAdd 14 43 42 16
+3 Store 27 43
+2 Branch 28
+
+2 Label 29
+4 Load 14 44 26
+5 InBoundsPtrAccessChain 17 45 2 24
+5 Store 45 44 2 4
+1 Return
+
+1 FunctionEnd
+
+; RUN: llvm-spirv %s -to-binary -o %t.spv
+; RUN: llvm-spirv -r %t.spv -o %t.bc
+; RUN: llvm-dis < %t.bc | FileCheck %s --check-prefix=CHECK-LLVM
+
+; CHECK-LLVM: br label %{{[0-9]+}}, !llvm.loop ![[MD:[0-9]+]]
+; CHECK-LLVM: ![[MD]] = distinct !{![[MD]], ![[MD_unroll_disable:[0-9]+]]}
+; CHECK-LLVM: ![[MD_unroll_disable]] = !{!"llvm.loop.unroll.disable"}
\ No newline at end of file diff --git a/test/OpLoopMergeNone.spt b/test/OpLoopMergeNone.spt new file mode 100644 index 0000000..95b4808 --- /dev/null +++ b/test/OpLoopMergeNone.spt @@ -0,0 +1,87 @@ +119734787 65536 458752 45 0
+2 Capability Addresses
+2 Capability Linkage
+2 Capability Kernel
+2 Capability Int64
+3 MemoryModel 2 2
+12 EntryPoint 6 1 "loop_merge_branch_conditional_none"
+3 Source 3 102000
+3 Name 2 "res"
+3 Name 3 "in"
+3 Name 4 "rep"
+3 Name 5 "num"
+4 Decorate 6 FuncParamAttr 5
+2 DecorationGroup 6
+4 Decorate 7 BuiltIn 28
+3 Decorate 7 Constant
+11 Decorate 7 LinkageAttributes "__spirv_GlobalInvocationId" Import
+4 GroupDecorate 6 2 3
+4 TypeInt 8 64 0
+4 TypeInt 14 32 1
+5 Constant 8 11 32 0
+4 Constant 14 15 0
+4 Constant 14 16 1
+4 TypeVector 9 8 3
+4 TypePointer 10 0 9
+2 TypeBool 12
+2 TypeVoid 13
+4 TypePointer 17 5 14
+4 TypePointer 18 7 14
+7 TypeFunction 19 13 17 17 14 14
+4 Variable 10 7 0
+
+5 Function 13 1 0 19
+3 FunctionParameter 17 2
+3 FunctionParameter 17 3
+3 FunctionParameter 14 4
+3 FunctionParameter 14 5
+
+2 Label 20
+6 Load 9 21 7 2 0
+5 CompositeExtract 8 22 21 0
+5 ShiftLeftLogical 8 23 22 11
+5 ShiftRightArithmetic 8 24 23 11
+4 SConvert 14 25 24
+4 Variable 18 26 7
+4 Variable 18 27 7
+5 Store 26 15 2 4
+5 Store 27 15 2 4
+2 Branch 28
+
+2 Label 28
+4 Load 14 29 27
+5 SLessThan 12 30 29 4
+4 LoopMerge 31 32 0
+4 BranchConditional 30 33 31
+
+2 Label 33
+4 Load 14 34 27
+5 IMul 14 35 34 5
+5 IAdd 14 36 25 35
+5 InBoundsPtrAccessChain 17 37 3 36
+4 Load 14 38 37
+4 Load 14 39 26
+5 IAdd 14 40 39 38
+5 Store 26 40 2 4
+2 Branch 32
+
+2 Label 32
+4 Load 14 41 27
+5 IAdd 14 42 41 16
+3 Store 27 42
+2 Branch 28
+
+2 Label 31
+4 Load 14 43 26
+5 InBoundsPtrAccessChain 17 44 2 24
+5 Store 44 43 2 4
+1 Return
+
+1 FunctionEnd
+
+; RUN: llvm-spirv %s -to-binary -o %t.spv
+; RUN: llvm-spirv -r %t.spv -o %t.bc
+; RUN: llvm-dis < %t.bc | FileCheck %s --check-prefix=CHECK-LLVM
+
+; CHECK-LLVM: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !llvm.loop ![[MD:[0-9]+]]
+; CHECK-LLVM: ![[MD]] = distinct !{![[MD]]}
\ No newline at end of file diff --git a/test/OpLoopMergeUnroll.spt b/test/OpLoopMergeUnroll.spt new file mode 100644 index 0000000..7253b3e --- /dev/null +++ b/test/OpLoopMergeUnroll.spt @@ -0,0 +1,88 @@ +119734787 65536 458752 45 0
+2 Capability Addresses
+2 Capability Linkage
+2 Capability Kernel
+2 Capability Int64
+3 MemoryModel 2 2
+13 EntryPoint 6 1 "loop_merge_branch_conditional_unroll"
+3 Source 3 102000
+3 Name 2 "res"
+3 Name 3 "in"
+3 Name 4 "rep"
+3 Name 5 "num"
+4 Decorate 6 FuncParamAttr 5
+2 DecorationGroup 6
+4 Decorate 7 BuiltIn 28
+3 Decorate 7 Constant
+11 Decorate 7 LinkageAttributes "__spirv_GlobalInvocationId" Import
+4 GroupDecorate 6 2 3
+4 TypeInt 8 64 0
+4 TypeInt 14 32 1
+5 Constant 8 11 32 0
+4 Constant 14 15 0
+4 Constant 14 16 1
+4 TypeVector 9 8 3
+4 TypePointer 10 0 9
+2 TypeBool 12
+2 TypeVoid 13
+4 TypePointer 17 5 14
+4 TypePointer 18 7 14
+7 TypeFunction 19 13 17 17 14 14
+4 Variable 10 7 0
+
+5 Function 13 1 0 19
+3 FunctionParameter 17 2
+3 FunctionParameter 17 3
+3 FunctionParameter 14 4
+3 FunctionParameter 14 5
+
+2 Label 20
+6 Load 9 21 7 2 0
+5 CompositeExtract 8 22 21 0
+5 ShiftLeftLogical 8 23 22 11
+5 ShiftRightArithmetic 8 24 23 11
+4 SConvert 14 25 24
+4 Variable 18 26 7
+4 Variable 18 27 7
+5 Store 26 15 2 4
+5 Store 27 15 2 4
+2 Branch 28
+
+2 Label 28
+4 Load 14 29 27
+5 SLessThan 12 30 29 4
+4 LoopMerge 31 32 1
+4 BranchConditional 30 33 31
+
+2 Label 33
+4 Load 14 34 27
+5 IMul 14 35 34 5
+5 IAdd 14 36 25 35
+5 InBoundsPtrAccessChain 17 37 3 36
+4 Load 14 38 37
+4 Load 14 39 26
+5 IAdd 14 40 39 38
+5 Store 26 40 2 4
+2 Branch 32
+
+2 Label 32
+4 Load 14 41 27
+5 IAdd 14 42 41 16
+3 Store 27 42
+2 Branch 28
+
+2 Label 31
+4 Load 14 43 26
+5 InBoundsPtrAccessChain 17 44 2 24
+5 Store 44 43 2 4
+1 Return
+
+1 FunctionEnd
+
+; RUN: llvm-spirv %s -to-binary -o %t.spv
+; RUN: llvm-spirv -r %t.spv -o %t.bc
+; RUN: llvm-dis < %t.bc | FileCheck %s --check-prefix=CHECK-LLVM
+
+; CHECK-LLVM: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !llvm.loop ![[MD:[0-9]+]]
+; CHECK-LLVM: ![[MD]] = distinct !{![[MD]], ![[MD_unroll:[0-9]+]]}
+; CHECK-LLVM: ![[MD_unroll]] = !{!"llvm.loop.unroll.full"}
\ No newline at end of file |