summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkkyzylov <ksenia.kyzylova@intel.com>2016-10-12 21:20:31 +0300
committerYaxun (Sam) Liu <yaxun.liu@amd.com>2016-10-12 14:20:31 -0400
commit9fa297ba488462588a1a606765b6849013b90aca (patch)
treecb81435963153842d764851a86d94c0b2a0541b1
parent6a1bbcba8e9e0810fdf6f4d1546099a075176001 (diff)
Translation of OpLoopMerge (#192)
-rw-r--r--lib/SPIRV/SPIRVReader.cpp56
-rw-r--r--lib/SPIRV/libSPIRV/SPIRVEntry.h1
-rw-r--r--lib/SPIRV/libSPIRV/SPIRVInstruction.h30
-rw-r--r--lib/SPIRV/libSPIRV/SPIRVModule.cpp9
-rw-r--r--lib/SPIRV/libSPIRV/SPIRVModule.h2
-rw-r--r--test/OpLoopMergeDontUnroll.spt91
-rw-r--r--test/OpLoopMergeNone.spt87
-rw-r--r--test/OpLoopMergeUnroll.spt88
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