@@ -76,8 +76,8 @@ class SPIRVEmitIntrinsics
7676 SPIRV::InstructionSet::InstructionSet InstrSet;
7777
7878 // a register of Instructions that don't have a complete type definition
79- SmallPtrSet <Value *, 8 > UncompleteTypeInfo;
80- SmallVector<Instruction *> PostprocessWorklist;
79+ DenseMap <Value *, unsigned > UncompleteTypeInfo;
80+ SmallVector<Value *> PostprocessWorklist;
8181
8282 // well known result types of builtins
8383 enum WellKnownTypes { Event };
@@ -147,6 +147,7 @@ class SPIRVEmitIntrinsics
147147 std::unordered_set<Function *> &FVisited);
148148 void replaceWithPtrcasted (Instruction *CI, Type *NewElemTy, Type *KnownElemTy,
149149 CallInst *AssignCI);
150+ void replaceAllUsesWith (Value *Src, Value *Dest, bool DeleteOld = true );
150151
151152 bool runOnFunction (Function &F);
152153 bool postprocessTypes ();
@@ -272,6 +273,27 @@ static inline void reportFatalOnTokenType(const Instruction *I) {
272273 false );
273274}
274275
276+ void SPIRVEmitIntrinsics::replaceAllUsesWith (Value *Src, Value *Dest,
277+ bool DeleteOld) {
278+ Src->replaceAllUsesWith (Dest);
279+ // Update deduced type records
280+ GR->updateIfExistDeducedElementType (Src, Dest, DeleteOld);
281+ GR->updateIfExistAssignPtrTypeInstr (Src, Dest, DeleteOld);
282+ // Update uncomplete type records if any
283+ auto It = UncompleteTypeInfo.find (Src);
284+ if (It == UncompleteTypeInfo.end ())
285+ return ;
286+ if (DeleteOld) {
287+ unsigned Pos = It->second ;
288+ UncompleteTypeInfo.erase (Src);
289+ UncompleteTypeInfo[Dest] = Pos;
290+ PostprocessWorklist[Pos] = Dest;
291+ } else {
292+ UncompleteTypeInfo[Dest] = PostprocessWorklist.size ();
293+ PostprocessWorklist.push_back (Dest);
294+ }
295+ }
296+
275297static bool IsKernelArgInt8 (Function *F, StoreInst *SI) {
276298 return SI && F->getCallingConv () == CallingConv::SPIR_KERNEL &&
277299 isPointerTy (SI->getValueOperand ()->getType ()) &&
@@ -434,7 +456,7 @@ void SPIRVEmitIntrinsics::maybeAssignPtrType(Type *&Ty, Value *Op, Type *RefTy,
434456 if (!UnknownElemTypeI8)
435457 return ;
436458 if (auto *I = dyn_cast<Instruction>(Op)) {
437- UncompleteTypeInfo. insert (I );
459+ UncompleteTypeInfo[I] = PostprocessWorklist. size ( );
438460 PostprocessWorklist.push_back (I);
439461 }
440462 }
@@ -640,7 +662,7 @@ Type *SPIRVEmitIntrinsics::deduceElementType(Value *I, bool UnknownElemTypeI8) {
640662 if (!UnknownElemTypeI8)
641663 return nullptr ;
642664 if (auto *Instr = dyn_cast<Instruction>(I)) {
643- UncompleteTypeInfo. insert (Instr );
665+ UncompleteTypeInfo[Instr] = PostprocessWorklist. size ( );
644666 PostprocessWorklist.push_back (Instr);
645667 }
646668 return IntegerType::getInt8Ty (I->getContext ());
@@ -1062,7 +1084,7 @@ Instruction *SPIRVEmitIntrinsics::visitSwitchInst(SwitchInst &I) {
10621084 {I.getOperand (0 )->getType ()}, {Args});
10631085 // remove switch to avoid its unneeded and undesirable unwrap into branches
10641086 // and conditions
1065- I. replaceAllUsesWith (NewI);
1087+ replaceAllUsesWith (&I, NewI);
10661088 I.eraseFromParent ();
10671089 // insert artificial and temporary instruction to preserve valid CFG,
10681090 // it will be removed after IR translation pass
@@ -1084,7 +1106,7 @@ Instruction *SPIRVEmitIntrinsics::visitGetElementPtrInst(GetElementPtrInst &I) {
10841106 for (auto &Op : I.operands ())
10851107 Args.push_back (Op);
10861108 auto *NewI = B.CreateIntrinsic (Intrinsic::spv_gep, {Types}, {Args});
1087- I. replaceAllUsesWith (NewI);
1109+ replaceAllUsesWith (&I, NewI);
10881110 I.eraseFromParent ();
10891111 return NewI;
10901112}
@@ -1099,7 +1121,7 @@ Instruction *SPIRVEmitIntrinsics::visitBitCastInst(BitCastInst &I) {
10991121 // such bitcasts do not provide sufficient information, should be just skipped
11001122 // here, and handled in insertPtrCastOrAssignTypeInstr.
11011123 if (isPointerTy (I.getType ())) {
1102- I. replaceAllUsesWith (Source);
1124+ replaceAllUsesWith (&I, Source);
11031125 I.eraseFromParent ();
11041126 return nullptr ;
11051127 }
@@ -1108,7 +1130,7 @@ Instruction *SPIRVEmitIntrinsics::visitBitCastInst(BitCastInst &I) {
11081130 SmallVector<Value *> Args (I.op_begin (), I.op_end ());
11091131 auto *NewI = B.CreateIntrinsic (Intrinsic::spv_bitcast, {Types}, {Args});
11101132 std::string InstName = I.hasName () ? I.getName ().str () : " " ;
1111- I. replaceAllUsesWith (NewI);
1133+ replaceAllUsesWith (&I, NewI);
11121134 I.eraseFromParent ();
11131135 NewI->setName (InstName);
11141136 return NewI;
@@ -1333,7 +1355,7 @@ Instruction *SPIRVEmitIntrinsics::visitInsertElementInst(InsertElementInst &I) {
13331355 SmallVector<Value *> Args (I.op_begin (), I.op_end ());
13341356 auto *NewI = B.CreateIntrinsic (Intrinsic::spv_insertelt, {Types}, {Args});
13351357 std::string InstName = I.hasName () ? I.getName ().str () : " " ;
1336- I. replaceAllUsesWith (NewI);
1358+ replaceAllUsesWith (&I, NewI);
13371359 I.eraseFromParent ();
13381360 NewI->setName (InstName);
13391361 return NewI;
@@ -1348,7 +1370,7 @@ SPIRVEmitIntrinsics::visitExtractElementInst(ExtractElementInst &I) {
13481370 SmallVector<Value *, 2 > Args = {I.getVectorOperand (), I.getIndexOperand ()};
13491371 auto *NewI = B.CreateIntrinsic (Intrinsic::spv_extractelt, {Types}, {Args});
13501372 std::string InstName = I.hasName () ? I.getName ().str () : " " ;
1351- I. replaceAllUsesWith (NewI);
1373+ replaceAllUsesWith (&I, NewI);
13521374 I.eraseFromParent ();
13531375 NewI->setName (InstName);
13541376 return NewI;
@@ -1384,7 +1406,7 @@ Instruction *SPIRVEmitIntrinsics::visitExtractValueInst(ExtractValueInst &I) {
13841406 Args.push_back (B.getInt32 (Op));
13851407 auto *NewI =
13861408 B.CreateIntrinsic (Intrinsic::spv_extractv, {I.getType ()}, {Args});
1387- I. replaceAllUsesWith (NewI);
1409+ replaceAllUsesWith (&I, NewI);
13881410 I.eraseFromParent ();
13891411 return NewI;
13901412}
@@ -1445,7 +1467,7 @@ Instruction *SPIRVEmitIntrinsics::visitAllocaInst(AllocaInst &I) {
14451467 {PtrTy, ArraySize->getType ()}, {ArraySize})
14461468 : B.CreateIntrinsic (Intrinsic::spv_alloca, {PtrTy}, {});
14471469 std::string InstName = I.hasName () ? I.getName ().str () : " " ;
1448- I. replaceAllUsesWith (NewI);
1470+ replaceAllUsesWith (&I, NewI);
14491471 I.eraseFromParent ();
14501472 NewI->setName (InstName);
14511473 return NewI;
@@ -1615,7 +1637,7 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
16151637 auto *NewOp =
16161638 buildIntrWithMD (Intrinsic::spv_track_constant,
16171639 {II->getType (), II->getType ()}, t->second , I, {}, B);
1618- I-> replaceAllUsesWith (NewOp);
1640+ replaceAllUsesWith (I, NewOp, false );
16191641 NewOp->setArgOperand (0 , I);
16201642 }
16211643 bool IsPhi = isa<PHINode>(I), BPrepared = false ;
0 commit comments