@@ -199,6 +199,8 @@ class SPIRVEmitIntrinsics
199
199
DenseMap<Function *, CallInst *> Ptrcasts);
200
200
201
201
void replaceAllUsesWith (Value *Src, Value *Dest, bool DeleteOld = true );
202
+ void replaceAllUsesWithAndErase (IRBuilder<> &B, Instruction *Src,
203
+ Instruction *Dest, bool DeleteOld = true );
202
204
203
205
bool runOnFunction (Function &F);
204
206
bool postprocessTypes (Module &M);
@@ -322,6 +324,17 @@ static inline void reportFatalOnTokenType(const Instruction *I) {
322
324
false );
323
325
}
324
326
327
+ static void emitAssignName (Instruction *I, IRBuilder<> &B) {
328
+ if (!I->hasName () || I->getType ()->isAggregateType () ||
329
+ expectIgnoredInIRTranslation (I))
330
+ return ;
331
+ reportFatalOnTokenType (I);
332
+ setInsertPointAfterDef (B, I);
333
+ std::vector<Value *> Args = {I};
334
+ addStringImm (I->getName (), B, Args);
335
+ B.CreateIntrinsic (Intrinsic::spv_assign_name, {I->getType ()}, Args);
336
+ }
337
+
325
338
void SPIRVEmitIntrinsics::replaceAllUsesWith (Value *Src, Value *Dest,
326
339
bool DeleteOld) {
327
340
Src->replaceAllUsesWith (Dest);
@@ -336,6 +349,19 @@ void SPIRVEmitIntrinsics::replaceAllUsesWith(Value *Src, Value *Dest,
336
349
}
337
350
}
338
351
352
+ void SPIRVEmitIntrinsics::replaceAllUsesWithAndErase (IRBuilder<> &B,
353
+ Instruction *Src,
354
+ Instruction *Dest,
355
+ bool DeleteOld) {
356
+ replaceAllUsesWith (Src, Dest, DeleteOld);
357
+ std::string Name = Src->hasName () ? Src->getName ().str () : " " ;
358
+ Src->eraseFromParent ();
359
+ if (!Name.empty ()) {
360
+ Dest->setName (Name);
361
+ emitAssignName (Dest, B);
362
+ }
363
+ }
364
+
339
365
static bool IsKernelArgInt8 (Function *F, StoreInst *SI) {
340
366
return SI && F->getCallingConv () == CallingConv::SPIR_KERNEL &&
341
367
isPointerTy (SI->getValueOperand ()->getType ()) &&
@@ -475,7 +501,7 @@ void SPIRVEmitIntrinsics::propagateElemType(
475
501
DenseMap<Function *, CallInst *> Ptrcasts;
476
502
SmallVector<User *> Users (Op->users ());
477
503
for (auto *U : Users) {
478
- if (!isa<Instruction>(U) || isa<BitCastInst>(U) || isSpvIntrinsic (U))
504
+ if (!isa<Instruction>(U) || isSpvIntrinsic (U))
479
505
continue ;
480
506
if (!VisitedSubst.insert (std::make_pair (U, Op)).second )
481
507
continue ;
@@ -506,7 +532,7 @@ void SPIRVEmitIntrinsics::propagateElemTypeRec(
506
532
return ;
507
533
SmallVector<User *> Users (Op->users ());
508
534
for (auto *U : Users) {
509
- if (!isa<Instruction>(U) || isa<BitCastInst>(U) || isSpvIntrinsic (U))
535
+ if (!isa<Instruction>(U) || isSpvIntrinsic (U))
510
536
continue ;
511
537
if (!VisitedSubst.insert (std::make_pair (U, Op)).second )
512
538
continue ;
@@ -958,6 +984,14 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(
958
984
return ;
959
985
Uncomplete = isTodoType (I);
960
986
Ops.push_back (std::make_pair (Ref->getPointerOperand (), 0 ));
987
+ } else if (auto *Ref = dyn_cast<BitCastInst>(I)) {
988
+ if (!isPointerTy (I->getType ()))
989
+ return ;
990
+ KnownElemTy = GR->findDeducedElementType (I);
991
+ if (!KnownElemTy)
992
+ return ;
993
+ Uncomplete = isTodoType (I);
994
+ Ops.push_back (std::make_pair (Ref->getOperand (0 ), 0 ));
961
995
} else if (auto *Ref = dyn_cast<GetElementPtrInst>(I)) {
962
996
if (GR->findDeducedElementType (Ref->getPointerOperand ()))
963
997
return ;
@@ -1030,7 +1064,6 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(
1030
1064
}
1031
1065
}
1032
1066
}
1033
- TypeValidated.insert (I);
1034
1067
// Non-recursive update of types in the function uncomplete returns.
1035
1068
// This may happen just once per a function, the latch is a pair of
1036
1069
// findDeducedElementType(F) / addDeducedElementType(F, ...).
@@ -1043,6 +1076,7 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(
1043
1076
} else if (UncompleteRets) {
1044
1077
UncompleteRets->insert (I);
1045
1078
}
1079
+ TypeValidated.insert (I);
1046
1080
return ;
1047
1081
}
1048
1082
Uncomplete = isTodoType (CurrF);
@@ -1300,8 +1334,7 @@ Instruction *SPIRVEmitIntrinsics::visitGetElementPtrInst(GetElementPtrInst &I) {
1300
1334
for (auto &Op : I.operands ())
1301
1335
Args.push_back (Op);
1302
1336
auto *NewI = B.CreateIntrinsic (Intrinsic::spv_gep, {Types}, {Args});
1303
- replaceAllUsesWith (&I, NewI);
1304
- I.eraseFromParent ();
1337
+ replaceAllUsesWithAndErase (B, &I, NewI);
1305
1338
return NewI;
1306
1339
}
1307
1340
@@ -1323,10 +1356,7 @@ Instruction *SPIRVEmitIntrinsics::visitBitCastInst(BitCastInst &I) {
1323
1356
SmallVector<Type *, 2 > Types = {I.getType (), Source->getType ()};
1324
1357
SmallVector<Value *> Args (I.op_begin (), I.op_end ());
1325
1358
auto *NewI = B.CreateIntrinsic (Intrinsic::spv_bitcast, {Types}, {Args});
1326
- std::string InstName = I.hasName () ? I.getName ().str () : " " ;
1327
- replaceAllUsesWith (&I, NewI);
1328
- I.eraseFromParent ();
1329
- NewI->setName (InstName);
1359
+ replaceAllUsesWithAndErase (B, &I, NewI);
1330
1360
return NewI;
1331
1361
}
1332
1362
@@ -1369,10 +1399,6 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
1369
1399
Instruction *I, Value *Pointer, Type *ExpectedElementType,
1370
1400
unsigned OperandToReplace, IRBuilder<> &B) {
1371
1401
TypeValidated.insert (I);
1372
- // If Pointer is the result of nop BitCastInst (ptr -> ptr), use the source
1373
- // pointer instead. The BitCastInst should be later removed when visited.
1374
- while (BitCastInst *BC = dyn_cast<BitCastInst>(Pointer))
1375
- Pointer = BC->getOperand (0 );
1376
1402
1377
1403
// Do not emit spv_ptrcast if Pointer's element type is ExpectedElementType
1378
1404
Type *PointerElemTy = deduceElementTypeHelper (Pointer, false );
@@ -1585,10 +1611,7 @@ Instruction *SPIRVEmitIntrinsics::visitInsertElementInst(InsertElementInst &I) {
1585
1611
B.SetInsertPoint (&I);
1586
1612
SmallVector<Value *> Args (I.op_begin (), I.op_end ());
1587
1613
auto *NewI = B.CreateIntrinsic (Intrinsic::spv_insertelt, {Types}, {Args});
1588
- std::string InstName = I.hasName () ? I.getName ().str () : " " ;
1589
- replaceAllUsesWith (&I, NewI);
1590
- I.eraseFromParent ();
1591
- NewI->setName (InstName);
1614
+ replaceAllUsesWithAndErase (B, &I, NewI);
1592
1615
return NewI;
1593
1616
}
1594
1617
@@ -1600,10 +1623,7 @@ SPIRVEmitIntrinsics::visitExtractElementInst(ExtractElementInst &I) {
1600
1623
I.getIndexOperand ()->getType ()};
1601
1624
SmallVector<Value *, 2 > Args = {I.getVectorOperand (), I.getIndexOperand ()};
1602
1625
auto *NewI = B.CreateIntrinsic (Intrinsic::spv_extractelt, {Types}, {Args});
1603
- std::string InstName = I.hasName () ? I.getName ().str () : " " ;
1604
- replaceAllUsesWith (&I, NewI);
1605
- I.eraseFromParent ();
1606
- NewI->setName (InstName);
1626
+ replaceAllUsesWithAndErase (B, &I, NewI);
1607
1627
return NewI;
1608
1628
}
1609
1629
@@ -1637,8 +1657,7 @@ Instruction *SPIRVEmitIntrinsics::visitExtractValueInst(ExtractValueInst &I) {
1637
1657
Args.push_back (B.getInt32 (Op));
1638
1658
auto *NewI =
1639
1659
B.CreateIntrinsic (Intrinsic::spv_extractv, {I.getType ()}, {Args});
1640
- replaceAllUsesWith (&I, NewI);
1641
- I.eraseFromParent ();
1660
+ replaceAllUsesWithAndErase (B, &I, NewI);
1642
1661
return NewI;
1643
1662
}
1644
1663
@@ -1697,10 +1716,7 @@ Instruction *SPIRVEmitIntrinsics::visitAllocaInst(AllocaInst &I) {
1697
1716
ArraySize ? B.CreateIntrinsic (Intrinsic::spv_alloca_array,
1698
1717
{PtrTy, ArraySize->getType ()}, {ArraySize})
1699
1718
: B.CreateIntrinsic (Intrinsic::spv_alloca, {PtrTy}, {});
1700
- std::string InstName = I.hasName () ? I.getName ().str () : " " ;
1701
- replaceAllUsesWith (&I, NewI);
1702
- I.eraseFromParent ();
1703
- NewI->setName (InstName);
1719
+ replaceAllUsesWithAndErase (B, &I, NewI);
1704
1720
return NewI;
1705
1721
}
1706
1722
@@ -1759,8 +1775,7 @@ bool SPIRVEmitIntrinsics::insertAssignPtrTypeIntrs(Instruction *I,
1759
1775
IRBuilder<> &B,
1760
1776
bool UnknownElemTypeI8) {
1761
1777
reportFatalOnTokenType (I);
1762
- if (!isPointerTy (I->getType ()) || !requireAssignType (I) ||
1763
- isa<BitCastInst>(I))
1778
+ if (!isPointerTy (I->getType ()) || !requireAssignType (I))
1764
1779
return false ;
1765
1780
1766
1781
setInsertPointAfterDef (B, I);
@@ -1861,8 +1876,9 @@ void SPIRVEmitIntrinsics::insertSpirvDecorations(Instruction *I,
1861
1876
void SPIRVEmitIntrinsics::processInstrAfterVisit (Instruction *I,
1862
1877
IRBuilder<> &B) {
1863
1878
auto *II = dyn_cast<IntrinsicInst>(I);
1864
- if (II && II->getIntrinsicID () == Intrinsic::spv_const_composite &&
1865
- TrackConstants) {
1879
+ bool IsConstComposite =
1880
+ II && II->getIntrinsicID () == Intrinsic::spv_const_composite;
1881
+ if (IsConstComposite && TrackConstants) {
1866
1882
setInsertPointAfterDef (B, I);
1867
1883
auto t = AggrConsts.find (I);
1868
1884
assert (t != AggrConsts.end ());
@@ -1886,23 +1902,31 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
1886
1902
: B.SetInsertPoint (I);
1887
1903
BPrepared = true ;
1888
1904
}
1905
+ Type *OpTy = Op->getType ();
1889
1906
Value *OpTyVal = Op;
1890
- if (Op->getType ()->isTargetExtTy ())
1891
- OpTyVal = PoisonValue::get (Op->getType ());
1892
- auto *NewOp = buildIntrWithMD (Intrinsic::spv_track_constant,
1893
- {Op->getType (), OpTyVal->getType ()}, Op,
1894
- OpTyVal, {}, B);
1907
+ if (OpTy->isTargetExtTy ())
1908
+ OpTyVal = PoisonValue::get (OpTy);
1909
+ CallInst *NewOp =
1910
+ buildIntrWithMD (Intrinsic::spv_track_constant,
1911
+ {OpTy, OpTyVal->getType ()}, Op, OpTyVal, {}, B);
1912
+ Type *OpElemTy = nullptr ;
1913
+ if (!IsConstComposite && isPointerTy (OpTy) &&
1914
+ (OpElemTy = GR->findDeducedElementType (Op)) != nullptr &&
1915
+ OpElemTy != IntegerType::getInt8Ty (I->getContext ())) {
1916
+ buildAssignPtr (B, IntegerType::getInt8Ty (I->getContext ()), NewOp);
1917
+ SmallVector<Type *, 2 > Types = {OpTy, OpTy};
1918
+ SmallVector<Value *, 2 > Args = {
1919
+ NewOp, buildMD (PoisonValue::get (OpElemTy)),
1920
+ B.getInt32 (getPointerAddressSpace (OpTy))};
1921
+ CallInst *PtrCasted =
1922
+ B.CreateIntrinsic (Intrinsic::spv_ptrcast, {Types}, Args);
1923
+ buildAssignPtr (B, OpElemTy, PtrCasted);
1924
+ NewOp = PtrCasted;
1925
+ }
1895
1926
I->setOperand (OpNo, NewOp);
1896
1927
}
1897
1928
}
1898
- if (I->hasName () && !I->getType ()->isAggregateType () &&
1899
- !expectIgnoredInIRTranslation (I)) {
1900
- reportFatalOnTokenType (I);
1901
- setInsertPointAfterDef (B, I);
1902
- std::vector<Value *> Args = {I};
1903
- addStringImm (I->getName (), B, Args);
1904
- B.CreateIntrinsic (Intrinsic::spv_assign_name, {I->getType ()}, Args);
1905
- }
1929
+ emitAssignName (I, B);
1906
1930
}
1907
1931
1908
1932
Type *SPIRVEmitIntrinsics::deduceFunParamElementType (Function *F,
@@ -2022,8 +2046,16 @@ void SPIRVEmitIntrinsics::processParamTypes(Function *F, IRBuilder<> &B) {
2022
2046
if (!isUntypedPointerTy (Arg->getType ()))
2023
2047
continue ;
2024
2048
Type *ElemTy = GR->findDeducedElementType (Arg);
2025
- if (!ElemTy && (ElemTy = deduceFunParamElementType (F, OpIdx)) != nullptr )
2026
- buildAssignPtr (B, ElemTy, Arg);
2049
+ if (!ElemTy && (ElemTy = deduceFunParamElementType (F, OpIdx)) != nullptr ) {
2050
+ if (CallInst *AssignCI = GR->findAssignPtrTypeInstr (Arg)) {
2051
+ DenseSet<std::pair<Value *, Value *>> VisitedSubst;
2052
+ updateAssignType (AssignCI, Arg, PoisonValue::get (ElemTy));
2053
+ propagateElemType (Arg, IntegerType::getInt8Ty (F->getContext ()),
2054
+ VisitedSubst);
2055
+ } else {
2056
+ buildAssignPtr (B, ElemTy, Arg);
2057
+ }
2058
+ }
2027
2059
}
2028
2060
}
2029
2061
0 commit comments