@@ -61,9 +61,6 @@ class SPIRVEmitIntrinsics
61
61
DenseMap<Instruction *, Type *> AggrConstTypes;
62
62
DenseSet<Instruction *> AggrStores;
63
63
64
- // a registry of created Intrinsic::spv_assign_ptr_type instructions
65
- DenseMap<Value *, CallInst *> AssignPtrTypeInstr;
66
-
67
64
// deduce element type of untyped pointers
68
65
Type *deduceElementType (Value *I);
69
66
Type *deduceElementTypeHelper (Value *I);
@@ -98,14 +95,16 @@ class SPIRVEmitIntrinsics
98
95
return B.CreateIntrinsic (IntrID, {Types}, Args);
99
96
}
100
97
98
+ void buildAssignType (IRBuilder<> &B, Type *ElemTy, Value *Arg);
101
99
void buildAssignPtr (IRBuilder<> &B, Type *ElemTy, Value *Arg);
100
+ void updateAssignType (CallInst *AssignCI, Value *Arg, Value *OfType);
102
101
103
102
void replaceMemInstrUses (Instruction *Old, Instruction *New, IRBuilder<> &B);
104
103
void processInstrAfterVisit (Instruction *I, IRBuilder<> &B);
105
104
void insertAssignPtrTypeIntrs (Instruction *I, IRBuilder<> &B);
106
105
void insertAssignTypeIntrs (Instruction *I, IRBuilder<> &B);
107
- void insertAssignTypeInstrForTargetExtTypes (TargetExtType *AssignedType,
108
- Value *V, IRBuilder<> &B);
106
+ void insertAssignPtrTypeTargetExt (TargetExtType *AssignedType, Value *V ,
107
+ IRBuilder<> &B);
109
108
void replacePointerOperandWithPtrCast (Instruction *I, Value *Pointer,
110
109
Type *ExpectedElementType,
111
110
unsigned OperandToReplace,
@@ -218,15 +217,39 @@ static inline void reportFatalOnTokenType(const Instruction *I) {
218
217
false );
219
218
}
220
219
220
+ void SPIRVEmitIntrinsics::buildAssignType (IRBuilder<> &B, Type *Ty,
221
+ Value *Arg) {
222
+ Value *OfType = PoisonValue::get (Ty);
223
+ CallInst *AssignCI = buildIntrWithMD (Intrinsic::spv_assign_type,
224
+ {Arg->getType ()}, OfType, Arg, {}, B);
225
+ GR->addAssignPtrTypeInstr (Arg, AssignCI);
226
+ }
227
+
221
228
void SPIRVEmitIntrinsics::buildAssignPtr (IRBuilder<> &B, Type *ElemTy,
222
229
Value *Arg) {
223
- CallInst *AssignPtrTyCI =
224
- buildIntrWithMD (Intrinsic::spv_assign_ptr_type, {Arg-> getType ()},
225
- Constant::getNullValue (ElemTy) , Arg,
226
- {B.getInt32 (getPointerAddressSpace (Arg->getType ()))}, B);
230
+ Value *OfType = PoisonValue::get (ElemTy);
231
+ CallInst *AssignPtrTyCI = buildIntrWithMD (
232
+ Intrinsic::spv_assign_ptr_type, {Arg-> getType ()}, OfType , Arg,
233
+ {B.getInt32 (getPointerAddressSpace (Arg->getType ()))}, B);
227
234
GR->addDeducedElementType (AssignPtrTyCI, ElemTy);
228
235
GR->addDeducedElementType (Arg, ElemTy);
229
- AssignPtrTypeInstr[Arg] = AssignPtrTyCI;
236
+ GR->addAssignPtrTypeInstr (Arg, AssignPtrTyCI);
237
+ }
238
+
239
+ void SPIRVEmitIntrinsics::updateAssignType (CallInst *AssignCI, Value *Arg,
240
+ Value *OfType) {
241
+ LLVMContext &Ctx = Arg->getContext ();
242
+ AssignCI->setArgOperand (
243
+ 1 , MetadataAsValue::get (
244
+ Ctx, MDNode::get (Ctx, ValueAsMetadata::getConstant (OfType))));
245
+ if (cast<IntrinsicInst>(AssignCI)->getIntrinsicID () !=
246
+ Intrinsic::spv_assign_ptr_type)
247
+ return ;
248
+
249
+ // update association with the pointee type
250
+ Type *ElemTy = OfType->getType ();
251
+ GR->addDeducedElementType (AssignCI, ElemTy);
252
+ GR->addDeducedElementType (Arg, ElemTy);
230
253
}
231
254
232
255
// Set element pointer type to the given value of ValueTy and tries to
@@ -513,19 +536,16 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(Instruction *I) {
513
536
if (!Ty) {
514
537
GR->addDeducedElementType (Op, KnownElemTy);
515
538
// check if there is existing Intrinsic::spv_assign_ptr_type instruction
516
- auto It = AssignPtrTypeInstr. find (Op);
517
- if (It == AssignPtrTypeInstr. end () ) {
539
+ CallInst *AssignCI = GR-> findAssignPtrTypeInstr (Op);
540
+ if (AssignCI == nullptr ) {
518
541
Instruction *User = dyn_cast<Instruction>(Op->use_begin ()->get ());
519
542
setInsertPointSkippingPhis (B, User ? User->getNextNode () : I);
520
543
CallInst *CI =
521
544
buildIntrWithMD (Intrinsic::spv_assign_ptr_type, {OpTy}, OpTyVal, Op,
522
545
{B.getInt32 (getPointerAddressSpace (OpTy))}, B);
523
- AssignPtrTypeInstr[Op] = CI ;
546
+ GR-> addAssignPtrTypeInstr (Op, CI) ;
524
547
} else {
525
- It->second ->setArgOperand (
526
- 1 ,
527
- MetadataAsValue::get (
528
- Ctx, MDNode::get (Ctx, ValueAsMetadata::getConstant (OpTyVal))));
548
+ updateAssignType (AssignCI, Op, OpTyVal);
529
549
}
530
550
} else {
531
551
if (auto *OpI = dyn_cast<Instruction>(Op)) {
@@ -559,7 +579,9 @@ void SPIRVEmitIntrinsics::replaceMemInstrUses(Instruction *Old,
559
579
if (isAssignTypeInstr (U)) {
560
580
B.SetInsertPoint (U);
561
581
SmallVector<Value *, 2 > Args = {New, U->getOperand (1 )};
562
- B.CreateIntrinsic (Intrinsic::spv_assign_type, {New->getType ()}, Args);
582
+ CallInst *AssignCI =
583
+ B.CreateIntrinsic (Intrinsic::spv_assign_type, {New->getType ()}, Args);
584
+ GR->addAssignPtrTypeInstr (New, AssignCI);
563
585
U->eraseFromParent ();
564
586
} else if (isMemInstrToReplace (U) || isa<ReturnInst>(U) ||
565
587
isa<CallInst>(U)) {
@@ -751,33 +773,39 @@ Instruction *SPIRVEmitIntrinsics::visitBitCastInst(BitCastInst &I) {
751
773
return NewI;
752
774
}
753
775
754
- void SPIRVEmitIntrinsics::insertAssignTypeInstrForTargetExtTypes (
776
+ void SPIRVEmitIntrinsics::insertAssignPtrTypeTargetExt (
755
777
TargetExtType *AssignedType, Value *V, IRBuilder<> &B) {
756
- // Do not emit spv_assign_type if the V is of the AssignedType already.
757
- if (V->getType () == AssignedType)
758
- return ;
778
+ Type *VTy = V->getType ();
759
779
760
- // Do not emit spv_assign_type if there is one already targetting V. If the
761
- // found spv_assign_type assigns a type different than AssignedType, report an
762
- // error. Builtin types cannot be redeclared or casted.
763
- for (auto User : V->users ()) {
764
- auto *II = dyn_cast<IntrinsicInst>(User);
765
- if (!II || II->getIntrinsicID () != Intrinsic::spv_assign_type)
766
- continue ;
780
+ // A couple of sanity checks.
781
+ assert (isPointerTy (VTy) && " Expect a pointer type!" );
782
+ if (auto PType = dyn_cast<TypedPointerType>(VTy))
783
+ if (PType->getElementType () != AssignedType)
784
+ report_fatal_error (" Unexpected pointer element type!" );
767
785
768
- MetadataAsValue *VMD = cast<MetadataAsValue>(II->getOperand (1 ));
769
- Type *BuiltinType =
770
- dyn_cast<ConstantAsMetadata>(VMD->getMetadata ())->getType ();
771
- if (BuiltinType != AssignedType)
772
- report_fatal_error (" Type mismatch " + BuiltinType->getTargetExtName () +
773
- " /" + AssignedType->getTargetExtName () +
774
- " for value " + V->getName (),
775
- false );
786
+ CallInst *AssignCI = GR->findAssignPtrTypeInstr (V);
787
+ if (!AssignCI) {
788
+ buildAssignType (B, AssignedType, V);
776
789
return ;
777
790
}
778
791
779
- Constant *Const = UndefValue::get (AssignedType);
780
- buildIntrWithMD (Intrinsic::spv_assign_type, {V->getType ()}, Const, V, {}, B);
792
+ Type *CurrentType =
793
+ dyn_cast<ConstantAsMetadata>(
794
+ cast<MetadataAsValue>(AssignCI->getOperand (1 ))->getMetadata ())
795
+ ->getType ();
796
+ if (CurrentType == AssignedType)
797
+ return ;
798
+
799
+ // Builtin types cannot be redeclared or casted.
800
+ if (CurrentType->isTargetExtTy ())
801
+ report_fatal_error (" Type mismatch " + CurrentType->getTargetExtName () +
802
+ " /" + AssignedType->getTargetExtName () +
803
+ " for value " + V->getName (),
804
+ false );
805
+
806
+ // Our previous guess about the type seems to be wrong, let's update
807
+ // inferred type according to a new, more precise type information.
808
+ updateAssignType (AssignCI, V, PoisonValue::get (AssignedType));
781
809
}
782
810
783
811
void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast (
@@ -850,7 +878,7 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
850
878
ExpectedElementTypeConst, Pointer, {B.getInt32 (AddressSpace)}, B);
851
879
GR->addDeducedElementType (CI, ExpectedElementType);
852
880
GR->addDeducedElementType (Pointer, ExpectedElementType);
853
- AssignPtrTypeInstr[ Pointer] = CI ;
881
+ GR-> addAssignPtrTypeInstr ( Pointer, CI) ;
854
882
return ;
855
883
}
856
884
@@ -929,8 +957,7 @@ void SPIRVEmitIntrinsics::insertPtrCastOrAssignTypeInstr(Instruction *I,
929
957
930
958
for (unsigned OpIdx = 0 ; OpIdx < CI->arg_size (); OpIdx++) {
931
959
Value *ArgOperand = CI->getArgOperand (OpIdx);
932
- if (!isa<PointerType>(ArgOperand->getType ()) &&
933
- !isa<TypedPointerType>(ArgOperand->getType ()))
960
+ if (!isPointerTy (ArgOperand->getType ()))
934
961
continue ;
935
962
936
963
// Constants (nulls/undefs) are handled in insertAssignPtrTypeIntrs()
@@ -952,8 +979,8 @@ void SPIRVEmitIntrinsics::insertPtrCastOrAssignTypeInstr(Instruction *I,
952
979
continue ;
953
980
954
981
if (ExpectedType->isTargetExtTy ())
955
- insertAssignTypeInstrForTargetExtTypes (cast<TargetExtType>(ExpectedType),
956
- ArgOperand, B);
982
+ insertAssignPtrTypeTargetExt (cast<TargetExtType>(ExpectedType),
983
+ ArgOperand, B);
957
984
else
958
985
replacePointerOperandWithPtrCast (CI, ArgOperand, ExpectedType, OpIdx, B);
959
986
}
@@ -1145,7 +1172,7 @@ void SPIRVEmitIntrinsics::insertAssignPtrTypeIntrs(Instruction *I,
1145
1172
CallInst *CI = buildIntrWithMD (Intrinsic::spv_assign_ptr_type, {I->getType ()},
1146
1173
EltTyConst, I, {B.getInt32 (AddressSpace)}, B);
1147
1174
GR->addDeducedElementType (CI, ElemTy);
1148
- AssignPtrTypeInstr[I] = CI ;
1175
+ GR-> addAssignPtrTypeInstr (I, CI) ;
1149
1176
}
1150
1177
1151
1178
void SPIRVEmitIntrinsics::insertAssignTypeIntrs (Instruction *I,
@@ -1164,20 +1191,32 @@ void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I,
1164
1191
TypeToAssign = It->second ;
1165
1192
}
1166
1193
}
1167
- Constant *Const = UndefValue::get (TypeToAssign);
1168
- buildIntrWithMD (Intrinsic::spv_assign_type, {Ty}, Const, I, {}, B);
1194
+ buildAssignType (B, TypeToAssign, I);
1169
1195
}
1170
1196
for (const auto &Op : I->operands ()) {
1171
1197
if (isa<ConstantPointerNull>(Op) || isa<UndefValue>(Op) ||
1172
1198
// Check GetElementPtrConstantExpr case.
1173
1199
(isa<ConstantExpr>(Op) && isa<GEPOperator>(Op))) {
1174
1200
setInsertPointSkippingPhis (B, I);
1175
- if (isa<UndefValue>(Op) && Op->getType ()->isAggregateType ())
1176
- buildIntrWithMD (Intrinsic::spv_assign_type, {B.getInt32Ty ()}, Op,
1177
- UndefValue::get (B.getInt32Ty ()), {}, B);
1178
- else if (!isa<Instruction>(Op))
1179
- buildIntrWithMD (Intrinsic::spv_assign_type, {Op->getType ()}, Op, Op, {},
1180
- B);
1201
+ Type *OpTy = Op->getType ();
1202
+ if (isa<UndefValue>(Op) && OpTy->isAggregateType ()) {
1203
+ CallInst *AssignCI =
1204
+ buildIntrWithMD (Intrinsic::spv_assign_type, {B.getInt32Ty ()}, Op,
1205
+ UndefValue::get (B.getInt32Ty ()), {}, B);
1206
+ GR->addAssignPtrTypeInstr (Op, AssignCI);
1207
+ } else if (!isa<Instruction>(Op)) {
1208
+ Type *OpTy = Op->getType ();
1209
+ if (auto PType = dyn_cast<TypedPointerType>(OpTy)) {
1210
+ buildAssignPtr (B, PType->getElementType (), Op);
1211
+ } else if (isPointerTy (OpTy)) {
1212
+ Type *ElemTy = GR->findDeducedElementType (Op);
1213
+ buildAssignPtr (B, ElemTy ? ElemTy : deduceElementType (Op), Op);
1214
+ } else {
1215
+ CallInst *AssignCI = buildIntrWithMD (Intrinsic::spv_assign_type,
1216
+ {OpTy}, Op, Op, {}, B);
1217
+ GR->addAssignPtrTypeInstr (Op, AssignCI);
1218
+ }
1219
+ }
1181
1220
}
1182
1221
}
1183
1222
}
@@ -1368,14 +1407,12 @@ bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) {
1368
1407
continue ;
1369
1408
1370
1409
insertAssignPtrTypeIntrs (I, B);
1410
+ deduceOperandElementType (I);
1371
1411
insertAssignTypeIntrs (I, B);
1372
1412
insertPtrCastOrAssignTypeInstr (I, B);
1373
1413
insertSpirvDecorations (I, B);
1374
1414
}
1375
1415
1376
- for (auto &I : instructions (Func))
1377
- deduceOperandElementType (&I);
1378
-
1379
1416
for (auto *I : Worklist) {
1380
1417
TrackConstants = true ;
1381
1418
if (!I->getType ()->isVoidTy () || isa<StoreInst>(I))
0 commit comments