@@ -55,6 +55,7 @@ THE SOFTWARE.
55
55
56
56
#include < llvm/Support/ScaledNumber.h>
57
57
#include < llvm/IR/IntrinsicInst.h>
58
+ #include < llvm/Analysis/CFG.h>
58
59
#include " libSPIRV/SPIRVDebugInfoExt.h"
59
60
#include " llvm/Transforms/Utils/Cloning.h"
60
61
#include " common/LLVMWarningsPop.hpp"
@@ -1433,6 +1434,9 @@ class SPIRVToLLVM {
1433
1434
// which are supposed to be replaced by the real values later.
1434
1435
typedef std::map<SPIRVValue *, LoadInst*> SPIRVToLLVMPlaceholderMap;
1435
1436
1437
+ typedef std::map<const BasicBlock*, const SPIRVValue*>
1438
+ SPIRVToLLVMLoopMetadataMap;
1439
+
1436
1440
Value *getTranslatedValue (SPIRVValue *BV);
1437
1441
1438
1442
private:
@@ -1455,6 +1459,11 @@ class SPIRVToLLVM {
1455
1459
SPIRVToLLVMMDAliasInstMap MDAliasScopeMap;
1456
1460
SPIRVToLLVMMDAliasInstMap MDAliasListMap;
1457
1461
1462
+ // Loops metadata is translated in the end of a function translation.
1463
+ // This storage contains pairs of translated loop header basic block and loop
1464
+ // metadata SPIR-V instruction in SPIR-V representation of this basic block.
1465
+ SPIRVToLLVMLoopMetadataMap FuncLoopMetadataMap;
1466
+
1458
1467
Type *mapType (SPIRVType *BT, Type *T) {
1459
1468
TypeMap[BT] = T;
1460
1469
return T;
@@ -1534,7 +1543,8 @@ class SPIRVToLLVM {
1534
1543
bool foreachFuncCtlMask (Source, Func);
1535
1544
1536
1545
template <typename LoopInstType>
1537
- void setLLVMLoopMetadata (LoopInstType* LM, BranchInst* BI);
1546
+ void setLLVMLoopMetadata (const LoopInstType* LM, Instruction* BI);
1547
+ void transLLVMLoopMetadata (const Function* F);
1538
1548
inline llvm::Metadata *getMetadataFromName (std::string Name);
1539
1549
inline std::vector<llvm::Metadata *>
1540
1550
getMetadataFromNameAndParameter (std::string Name, SPIRVWord Parameter);
@@ -1823,9 +1833,12 @@ SPIRVToLLVM::getMetadataFromNameAndParameter(std::string Name,
1823
1833
1824
1834
1825
1835
template <typename LoopInstType>
1826
- void SPIRVToLLVM::setLLVMLoopMetadata (LoopInstType* LM, BranchInst * BI) {
1836
+ void SPIRVToLLVM::setLLVMLoopMetadata (const LoopInstType* LM, Instruction * BI) {
1827
1837
if (!LM)
1828
1838
return ;
1839
+
1840
+ IGC_ASSERT (BI && isa<BranchInst>(BI));
1841
+
1829
1842
auto Temp = MDNode::getTemporary (*Context, None);
1830
1843
auto Self = MDNode::get (*Context, Temp.get ());
1831
1844
Self->replaceOperandWith (0 , Self);
@@ -1898,6 +1911,40 @@ void SPIRVToLLVM::setLLVMLoopMetadata(LoopInstType* LM, BranchInst* BI) {
1898
1911
BI->setMetadata (" llvm.loop" , Node);
1899
1912
}
1900
1913
1914
+ void SPIRVToLLVM::transLLVMLoopMetadata (const Function *F) {
1915
+ assert (F);
1916
+
1917
+ if (!FuncLoopMetadataMap.empty ()) {
1918
+ // In SPIRV loop metadata is linked to a header basic block of a loop
1919
+ // whilst in LLVM IR it is linked to a latch basic block (the one
1920
+ // whose back edge goes to a header basic block) of the loop.
1921
+
1922
+ using Edge = std::pair<const BasicBlock *, const BasicBlock *>;
1923
+ SmallVector<Edge, 32 > Edges;
1924
+ FindFunctionBackedges (*F, Edges);
1925
+
1926
+ for (const auto &BkEdge : Edges) {
1927
+ // Check that loop header BB contains loop metadata.
1928
+ const auto LMDItr = FuncLoopMetadataMap.find (BkEdge.second );
1929
+ if (LMDItr == FuncLoopMetadataMap.end ())
1930
+ continue ;
1931
+
1932
+ auto *BI = const_cast <Instruction *>(BkEdge.first ->getTerminator ());
1933
+ const auto *LMD = LMDItr->second ;
1934
+ if (LMD->getOpCode () == OpLoopMerge) {
1935
+ const auto *LM = static_cast <const SPIRVLoopMerge *>(LMD);
1936
+ setLLVMLoopMetadata<SPIRVLoopMerge>(LM, BI);
1937
+ } else if (LMD->getOpCode () == OpLoopControlINTEL) {
1938
+ const auto *LCI = static_cast <const SPIRVLoopControlINTEL *>(LMD);
1939
+ setLLVMLoopMetadata<SPIRVLoopControlINTEL>(LCI, BI);
1940
+ }
1941
+ }
1942
+
1943
+ // Loop metadata map should be re-filled during each function translation.
1944
+ FuncLoopMetadataMap.clear ();
1945
+ }
1946
+ }
1947
+
1901
1948
GlobalValue::LinkageTypes
1902
1949
SPIRVToLLVM::transLinkageType (const SPIRVValue* V) {
1903
1950
if (V->getLinkageType () == LinkageTypeInternal) {
@@ -2997,46 +3044,22 @@ SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
2997
3044
// Translation of instructions
2998
3045
switch (BV->getOpCode ()) {
2999
3046
case OpBranch: {
3000
- auto BR = static_cast <SPIRVBranch *>(BV);
3001
- IGC_ASSERT_MESSAGE (BB, " Invalid BB" );
3002
-
3003
- auto BI = BranchInst::Create (
3004
- dyn_cast<BasicBlock>(transValue (BR->getTargetLabel (), F, BB)), BB);
3005
-
3006
- SPIRVInstruction *Prev = BR->getPrevious ();
3007
- if (Prev && Prev->getOpCode () == OpLoopMerge) {
3008
- auto LM = static_cast <SPIRVLoopMerge*>(Prev);
3009
- setLLVMLoopMetadata<SPIRVLoopMerge>(LM, BI);
3010
- }
3011
- else if (Prev && Prev->getOpCode () == OpLoopControlINTEL) {
3012
- auto LCI = static_cast <SPIRVLoopControlINTEL*>(Prev);
3013
- setLLVMLoopMetadata<SPIRVLoopControlINTEL>(LCI, BI);
3014
- }
3015
-
3047
+ auto *BR = static_cast <SPIRVBranch *>(BV);
3048
+ auto *BI = BranchInst::Create (
3049
+ cast<BasicBlock>(transValue (BR->getTargetLabel (), F, BB)), BB);
3050
+ // Loop metadata will be translated in the end of function translation.
3016
3051
return mapValue (BV, BI);
3017
3052
}
3018
3053
break ;
3019
3054
3020
3055
case OpBranchConditional: {
3021
- auto BR = static_cast <SPIRVBranchConditional *>(BV);
3022
- IGC_ASSERT_MESSAGE (BB, " Invalid BB" );
3023
- auto BC = BranchInst::Create (
3024
- dyn_cast<BasicBlock>(transValue (BR->getTrueLabel (), F, BB)),
3025
- dyn_cast<BasicBlock>(transValue (BR->getFalseLabel (), F, BB)),
3026
- // cond must be an i1, truncate bool to i1 if it was an i8.
3027
- transValue (BR->getCondition (), F, BB, true , BoolAction::Truncate),
3028
- BB);
3029
-
3030
- SPIRVInstruction *Prev = BR->getPrevious ();
3031
- if (Prev && Prev->getOpCode () == OpLoopMerge) {
3032
- if (auto LM = static_cast <SPIRVLoopMerge *>(Prev))
3033
- setLLVMLoopMetadata<SPIRVLoopMerge>(LM, BC);
3034
- }
3035
- else if (Prev && Prev->getOpCode () == OpLoopControlINTEL) {
3036
- if (auto LCI = static_cast <SPIRVLoopControlINTEL *>(Prev))
3037
- setLLVMLoopMetadata<SPIRVLoopControlINTEL>(LCI, BC);
3038
- }
3039
-
3056
+ auto *BR = static_cast <SPIRVBranchConditional *>(BV);
3057
+ auto *BC = BranchInst::Create (
3058
+ cast<BasicBlock>(transValue (BR->getTrueLabel (), F, BB)),
3059
+ cast<BasicBlock>(transValue (BR->getFalseLabel (), F, BB)),
3060
+ // cond must be an i1, truncate bool to i1 if it was an i8.
3061
+ transValue (BR->getCondition (), F, BB, true , BoolAction::Truncate), BB);
3062
+ // Loop metadata will be translated in the end of function translation.
3040
3063
return mapValue (BV, BC);
3041
3064
}
3042
3065
break ;
@@ -3217,11 +3240,10 @@ SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
3217
3240
BV->getName (), BB));
3218
3241
}
3219
3242
break ;
3220
- // OpenCL Compiler does not use this instruction
3221
- // Should be translated at OpBranch or OpBranchConditional cases
3222
- case OpLoopMerge:
3223
- case OpLoopControlINTEL:
3243
+ case OpLoopMerge: // Will be translated after all other function's
3244
+ case OpLoopControlINTEL: // instructions are translated.
3224
3245
{
3246
+ FuncLoopMetadataMap[BB] = BV;
3225
3247
return nullptr ;
3226
3248
}
3227
3249
break ;
@@ -3655,6 +3677,9 @@ SPIRVToLLVM::transFunction(SPIRVFunction *BF) {
3655
3677
transValue (BInst, F, BB, false , BoolAction::Noop);
3656
3678
}
3657
3679
}
3680
+
3681
+ transLLVMLoopMetadata (F);
3682
+
3658
3683
return F;
3659
3684
}
3660
3685
0 commit comments