1 //===-- SPIRVEmitIntrinsics.cpp - emit SPIRV intrinsics ---------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // The pass emits SPIRV intrinsics keeping essential high-level information for
10 // the translation of LLVM IR to SPIR-V.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "SPIRV.h"
15 #include "SPIRVTargetMachine.h"
16 #include "SPIRVUtils.h"
17 #include "llvm/IR/IRBuilder.h"
18 #include "llvm/IR/InstIterator.h"
19 #include "llvm/IR/InstVisitor.h"
20 #include "llvm/IR/IntrinsicsSPIRV.h"
21 
22 #include <queue>
23 
24 // This pass performs the following transformation on LLVM IR level required
25 // for the following translation to SPIR-V:
26 // - replaces direct usages of aggregate constants with target-specific
27 //   intrinsics;
28 // - replaces aggregates-related instructions (extract/insert, ld/st, etc)
29 //   with a target-specific intrinsics;
30 // - emits intrinsics for the global variable initializers since IRTranslator
31 //   doesn't handle them and it's not very convenient to translate them
32 //   ourselves;
33 // - emits intrinsics to keep track of the string names assigned to the values;
34 // - emits intrinsics to keep track of constants (this is necessary to have an
35 //   LLVM IR constant after the IRTranslation is completed) for their further
36 //   deduplication;
37 // - emits intrinsics to keep track of original LLVM types of the values
38 //   to be able to emit proper SPIR-V types eventually.
39 //
40 // TODO: consider removing spv.track.constant in favor of spv.assign.type.
41 
42 using namespace llvm;
43 
44 namespace llvm {
45 void initializeSPIRVEmitIntrinsicsPass(PassRegistry &);
46 } // namespace llvm
47 
48 namespace {
49 class SPIRVEmitIntrinsics
50     : public FunctionPass,
51       public InstVisitor<SPIRVEmitIntrinsics, Instruction *> {
52   SPIRVTargetMachine *TM = nullptr;
53   IRBuilder<> *IRB = nullptr;
54   Function *F = nullptr;
55   bool TrackConstants = true;
56   DenseMap<Instruction *, Constant *> AggrConsts;
57   DenseSet<Instruction *> AggrStores;
58   void preprocessCompositeConstants();
59   void preprocessUndefs();
60   CallInst *buildIntrWithMD(Intrinsic::ID IntrID, ArrayRef<Type *> Types,
61                             Value *Arg, Value *Arg2,
62                             ArrayRef<Constant *> Imms) {
63     ConstantAsMetadata *CM = ValueAsMetadata::getConstant(Arg);
64     MDTuple *TyMD = MDNode::get(F->getContext(), CM);
65     MetadataAsValue *VMD = MetadataAsValue::get(F->getContext(), TyMD);
66     SmallVector<Value *, 4> Args;
67     Args.push_back(Arg2);
68     Args.push_back(VMD);
69     for (auto *Imm : Imms)
70       Args.push_back(Imm);
71     return IRB->CreateIntrinsic(IntrID, {Types}, Args);
72   }
73   void replaceMemInstrUses(Instruction *Old, Instruction *New);
74   void processInstrAfterVisit(Instruction *I);
75   void insertAssignPtrTypeIntrs(Instruction *I);
76   void insertAssignTypeIntrs(Instruction *I);
77   void processGlobalValue(GlobalVariable &GV);
78 
79 public:
80   static char ID;
81   SPIRVEmitIntrinsics() : FunctionPass(ID) {
82     initializeSPIRVEmitIntrinsicsPass(*PassRegistry::getPassRegistry());
83   }
84   SPIRVEmitIntrinsics(SPIRVTargetMachine *_TM) : FunctionPass(ID), TM(_TM) {
85     initializeSPIRVEmitIntrinsicsPass(*PassRegistry::getPassRegistry());
86   }
87   Instruction *visitInstruction(Instruction &I) { return &I; }
88   Instruction *visitSwitchInst(SwitchInst &I);
89   Instruction *visitGetElementPtrInst(GetElementPtrInst &I);
90   Instruction *visitBitCastInst(BitCastInst &I);
91   Instruction *visitInsertElementInst(InsertElementInst &I);
92   Instruction *visitExtractElementInst(ExtractElementInst &I);
93   Instruction *visitInsertValueInst(InsertValueInst &I);
94   Instruction *visitExtractValueInst(ExtractValueInst &I);
95   Instruction *visitLoadInst(LoadInst &I);
96   Instruction *visitStoreInst(StoreInst &I);
97   Instruction *visitAllocaInst(AllocaInst &I);
98   Instruction *visitAtomicCmpXchgInst(AtomicCmpXchgInst &I);
99   Instruction *visitUnreachableInst(UnreachableInst &I);
100   bool runOnFunction(Function &F) override;
101 };
102 } // namespace
103 
104 char SPIRVEmitIntrinsics::ID = 0;
105 
106 INITIALIZE_PASS(SPIRVEmitIntrinsics, "emit-intrinsics", "SPIRV emit intrinsics",
107                 false, false)
108 
109 static inline bool isAssignTypeInstr(const Instruction *I) {
110   return isa<IntrinsicInst>(I) &&
111          cast<IntrinsicInst>(I)->getIntrinsicID() == Intrinsic::spv_assign_type;
112 }
113 
114 static bool isMemInstrToReplace(Instruction *I) {
115   return isa<StoreInst>(I) || isa<LoadInst>(I) || isa<InsertValueInst>(I) ||
116          isa<ExtractValueInst>(I) || isa<AtomicCmpXchgInst>(I);
117 }
118 
119 static bool isAggrToReplace(const Value *V) {
120   return isa<ConstantAggregate>(V) || isa<ConstantDataArray>(V) ||
121          (isa<ConstantAggregateZero>(V) && !V->getType()->isVectorTy());
122 }
123 
124 static void setInsertPointSkippingPhis(IRBuilder<> &B, Instruction *I) {
125   if (isa<PHINode>(I))
126     B.SetInsertPoint(I->getParent(), I->getParent()->getFirstInsertionPt());
127   else
128     B.SetInsertPoint(I);
129 }
130 
131 static bool requireAssignPtrType(Instruction *I) {
132   if (isa<AllocaInst>(I) || isa<GetElementPtrInst>(I))
133     return true;
134 
135   return false;
136 }
137 
138 static bool requireAssignType(Instruction *I) {
139   IntrinsicInst *Intr = dyn_cast<IntrinsicInst>(I);
140   if (Intr) {
141     switch (Intr->getIntrinsicID()) {
142     case Intrinsic::invariant_start:
143     case Intrinsic::invariant_end:
144       return false;
145     }
146   }
147   return true;
148 }
149 
150 void SPIRVEmitIntrinsics::replaceMemInstrUses(Instruction *Old,
151                                               Instruction *New) {
152   while (!Old->user_empty()) {
153     auto *U = Old->user_back();
154     if (isAssignTypeInstr(U)) {
155       IRB->SetInsertPoint(U);
156       SmallVector<Value *, 2> Args = {New, U->getOperand(1)};
157       IRB->CreateIntrinsic(Intrinsic::spv_assign_type, {New->getType()}, Args);
158       U->eraseFromParent();
159     } else if (isMemInstrToReplace(U) || isa<ReturnInst>(U) ||
160                isa<CallInst>(U)) {
161       U->replaceUsesOfWith(Old, New);
162     } else {
163       llvm_unreachable("illegal aggregate intrinsic user");
164     }
165   }
166   Old->eraseFromParent();
167 }
168 
169 void SPIRVEmitIntrinsics::preprocessUndefs() {
170   std::queue<Instruction *> Worklist;
171   for (auto &I : instructions(F))
172     Worklist.push(&I);
173 
174   while (!Worklist.empty()) {
175     Instruction *I = Worklist.front();
176     Worklist.pop();
177 
178     for (auto &Op : I->operands()) {
179       auto *AggrUndef = dyn_cast<UndefValue>(Op);
180       if (!AggrUndef || !Op->getType()->isAggregateType())
181         continue;
182 
183       IRB->SetInsertPoint(I);
184       auto *IntrUndef = IRB->CreateIntrinsic(Intrinsic::spv_undef, {}, {});
185       Worklist.push(IntrUndef);
186       I->replaceUsesOfWith(Op, IntrUndef);
187       AggrConsts[IntrUndef] = AggrUndef;
188     }
189   }
190 }
191 
192 void SPIRVEmitIntrinsics::preprocessCompositeConstants() {
193   std::queue<Instruction *> Worklist;
194   for (auto &I : instructions(F))
195     Worklist.push(&I);
196 
197   while (!Worklist.empty()) {
198     auto *I = Worklist.front();
199     assert(I);
200     bool KeepInst = false;
201     for (const auto &Op : I->operands()) {
202       auto BuildCompositeIntrinsic = [&KeepInst, &Worklist, &I, &Op,
203                                       this](Constant *AggrC,
204                                             ArrayRef<Value *> Args) {
205         IRB->SetInsertPoint(I);
206         auto *CCI =
207             IRB->CreateIntrinsic(Intrinsic::spv_const_composite, {}, {Args});
208         Worklist.push(CCI);
209         I->replaceUsesOfWith(Op, CCI);
210         KeepInst = true;
211         AggrConsts[CCI] = AggrC;
212       };
213 
214       if (auto *AggrC = dyn_cast<ConstantAggregate>(Op)) {
215         SmallVector<Value *> Args(AggrC->op_begin(), AggrC->op_end());
216         BuildCompositeIntrinsic(AggrC, Args);
217       } else if (auto *AggrC = dyn_cast<ConstantDataArray>(Op)) {
218         SmallVector<Value *> Args;
219         for (unsigned i = 0; i < AggrC->getNumElements(); ++i)
220           Args.push_back(AggrC->getElementAsConstant(i));
221         BuildCompositeIntrinsic(AggrC, Args);
222       } else if (isa<ConstantAggregateZero>(Op) &&
223                  !Op->getType()->isVectorTy()) {
224         auto *AggrC = cast<ConstantAggregateZero>(Op);
225         SmallVector<Value *> Args(AggrC->op_begin(), AggrC->op_end());
226         BuildCompositeIntrinsic(AggrC, Args);
227       }
228     }
229     if (!KeepInst)
230       Worklist.pop();
231   }
232 }
233 
234 Instruction *SPIRVEmitIntrinsics::visitSwitchInst(SwitchInst &I) {
235   SmallVector<Value *, 4> Args;
236   for (auto &Op : I.operands())
237     if (Op.get()->getType()->isSized())
238       Args.push_back(Op);
239   IRB->SetInsertPoint(&I);
240   IRB->CreateIntrinsic(Intrinsic::spv_switch, {I.getOperand(0)->getType()},
241                        {Args});
242   return &I;
243 }
244 
245 Instruction *SPIRVEmitIntrinsics::visitGetElementPtrInst(GetElementPtrInst &I) {
246   SmallVector<Type *, 2> Types = {I.getType(), I.getOperand(0)->getType()};
247   SmallVector<Value *, 4> Args;
248   Args.push_back(IRB->getInt1(I.isInBounds()));
249   for (auto &Op : I.operands())
250     Args.push_back(Op);
251   auto *NewI = IRB->CreateIntrinsic(Intrinsic::spv_gep, {Types}, {Args});
252   I.replaceAllUsesWith(NewI);
253   I.eraseFromParent();
254   return NewI;
255 }
256 
257 Instruction *SPIRVEmitIntrinsics::visitBitCastInst(BitCastInst &I) {
258   SmallVector<Type *, 2> Types = {I.getType(), I.getOperand(0)->getType()};
259   SmallVector<Value *> Args(I.op_begin(), I.op_end());
260   auto *NewI = IRB->CreateIntrinsic(Intrinsic::spv_bitcast, {Types}, {Args});
261   std::string InstName = I.hasName() ? I.getName().str() : "";
262   I.replaceAllUsesWith(NewI);
263   I.eraseFromParent();
264   NewI->setName(InstName);
265   return NewI;
266 }
267 
268 Instruction *SPIRVEmitIntrinsics::visitInsertElementInst(InsertElementInst &I) {
269   SmallVector<Type *, 4> Types = {I.getType(), I.getOperand(0)->getType(),
270                                   I.getOperand(1)->getType(),
271                                   I.getOperand(2)->getType()};
272   SmallVector<Value *> Args(I.op_begin(), I.op_end());
273   auto *NewI = IRB->CreateIntrinsic(Intrinsic::spv_insertelt, {Types}, {Args});
274   std::string InstName = I.hasName() ? I.getName().str() : "";
275   I.replaceAllUsesWith(NewI);
276   I.eraseFromParent();
277   NewI->setName(InstName);
278   return NewI;
279 }
280 
281 Instruction *
282 SPIRVEmitIntrinsics::visitExtractElementInst(ExtractElementInst &I) {
283   SmallVector<Type *, 3> Types = {I.getType(), I.getVectorOperandType(),
284                                   I.getIndexOperand()->getType()};
285   SmallVector<Value *, 2> Args = {I.getVectorOperand(), I.getIndexOperand()};
286   auto *NewI = IRB->CreateIntrinsic(Intrinsic::spv_extractelt, {Types}, {Args});
287   std::string InstName = I.hasName() ? I.getName().str() : "";
288   I.replaceAllUsesWith(NewI);
289   I.eraseFromParent();
290   NewI->setName(InstName);
291   return NewI;
292 }
293 
294 Instruction *SPIRVEmitIntrinsics::visitInsertValueInst(InsertValueInst &I) {
295   SmallVector<Type *, 1> Types = {I.getInsertedValueOperand()->getType()};
296   SmallVector<Value *> Args;
297   for (auto &Op : I.operands())
298     if (isa<UndefValue>(Op))
299       Args.push_back(UndefValue::get(IRB->getInt32Ty()));
300     else
301       Args.push_back(Op);
302   for (auto &Op : I.indices())
303     Args.push_back(IRB->getInt32(Op));
304   Instruction *NewI =
305       IRB->CreateIntrinsic(Intrinsic::spv_insertv, {Types}, {Args});
306   replaceMemInstrUses(&I, NewI);
307   return NewI;
308 }
309 
310 Instruction *SPIRVEmitIntrinsics::visitExtractValueInst(ExtractValueInst &I) {
311   SmallVector<Value *> Args;
312   for (auto &Op : I.operands())
313     Args.push_back(Op);
314   for (auto &Op : I.indices())
315     Args.push_back(IRB->getInt32(Op));
316   auto *NewI =
317       IRB->CreateIntrinsic(Intrinsic::spv_extractv, {I.getType()}, {Args});
318   I.replaceAllUsesWith(NewI);
319   I.eraseFromParent();
320   return NewI;
321 }
322 
323 Instruction *SPIRVEmitIntrinsics::visitLoadInst(LoadInst &I) {
324   if (!I.getType()->isAggregateType())
325     return &I;
326   TrackConstants = false;
327   const auto *TLI = TM->getSubtargetImpl()->getTargetLowering();
328   MachineMemOperand::Flags Flags =
329       TLI->getLoadMemOperandFlags(I, F->getParent()->getDataLayout());
330   auto *NewI =
331       IRB->CreateIntrinsic(Intrinsic::spv_load, {I.getOperand(0)->getType()},
332                            {I.getPointerOperand(), IRB->getInt16(Flags),
333                             IRB->getInt8(I.getAlign().value())});
334   replaceMemInstrUses(&I, NewI);
335   return NewI;
336 }
337 
338 Instruction *SPIRVEmitIntrinsics::visitStoreInst(StoreInst &I) {
339   if (!AggrStores.contains(&I))
340     return &I;
341   TrackConstants = false;
342   const auto *TLI = TM->getSubtargetImpl()->getTargetLowering();
343   MachineMemOperand::Flags Flags =
344       TLI->getStoreMemOperandFlags(I, F->getParent()->getDataLayout());
345   auto *PtrOp = I.getPointerOperand();
346   auto *NewI = IRB->CreateIntrinsic(
347       Intrinsic::spv_store, {I.getValueOperand()->getType(), PtrOp->getType()},
348       {I.getValueOperand(), PtrOp, IRB->getInt16(Flags),
349        IRB->getInt8(I.getAlign().value())});
350   I.eraseFromParent();
351   return NewI;
352 }
353 
354 Instruction *SPIRVEmitIntrinsics::visitAllocaInst(AllocaInst &I) {
355   TrackConstants = false;
356   Type *PtrTy = I.getType();
357   auto *NewI = IRB->CreateIntrinsic(Intrinsic::spv_alloca, {PtrTy}, {});
358   std::string InstName = I.hasName() ? I.getName().str() : "";
359   I.replaceAllUsesWith(NewI);
360   I.eraseFromParent();
361   NewI->setName(InstName);
362   return NewI;
363 }
364 
365 Instruction *SPIRVEmitIntrinsics::visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
366   assert(I.getType()->isAggregateType() && "Aggregate result is expected");
367   SmallVector<Value *> Args;
368   for (auto &Op : I.operands())
369     Args.push_back(Op);
370   Args.push_back(IRB->getInt32(I.getSyncScopeID()));
371   Args.push_back(IRB->getInt32(
372       static_cast<uint32_t>(getMemSemantics(I.getSuccessOrdering()))));
373   Args.push_back(IRB->getInt32(
374       static_cast<uint32_t>(getMemSemantics(I.getFailureOrdering()))));
375   auto *NewI = IRB->CreateIntrinsic(Intrinsic::spv_cmpxchg,
376                                     {I.getPointerOperand()->getType()}, {Args});
377   replaceMemInstrUses(&I, NewI);
378   return NewI;
379 }
380 
381 Instruction *SPIRVEmitIntrinsics::visitUnreachableInst(UnreachableInst &I) {
382   IRB->SetInsertPoint(&I);
383   IRB->CreateIntrinsic(Intrinsic::spv_unreachable, {}, {});
384   return &I;
385 }
386 
387 void SPIRVEmitIntrinsics::processGlobalValue(GlobalVariable &GV) {
388   // Skip special artifical variable llvm.global.annotations.
389   if (GV.getName() == "llvm.global.annotations")
390     return;
391   if (GV.hasInitializer() && !isa<UndefValue>(GV.getInitializer())) {
392     Constant *Init = GV.getInitializer();
393     Type *Ty = isAggrToReplace(Init) ? IRB->getInt32Ty() : Init->getType();
394     Constant *Const = isAggrToReplace(Init) ? IRB->getInt32(1) : Init;
395     auto *InitInst = IRB->CreateIntrinsic(Intrinsic::spv_init_global,
396                                           {GV.getType(), Ty}, {&GV, Const});
397     InitInst->setArgOperand(1, Init);
398   }
399   if ((!GV.hasInitializer() || isa<UndefValue>(GV.getInitializer())) &&
400       GV.getNumUses() == 0)
401     IRB->CreateIntrinsic(Intrinsic::spv_unref_global, GV.getType(), &GV);
402 }
403 
404 void SPIRVEmitIntrinsics::insertAssignPtrTypeIntrs(Instruction *I) {
405   if (I->getType()->isVoidTy() || !requireAssignPtrType(I))
406     return;
407 
408   setInsertPointSkippingPhis(*IRB, I->getNextNode());
409 
410   Constant *EltTyConst;
411   unsigned AddressSpace = 0;
412   if (auto *AI = dyn_cast<AllocaInst>(I)) {
413     EltTyConst = Constant::getNullValue(AI->getAllocatedType());
414     AddressSpace = AI->getAddressSpace();
415   } else if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
416     EltTyConst = Constant::getNullValue(GEP->getResultElementType());
417     AddressSpace = GEP->getPointerAddressSpace();
418   } else {
419     llvm_unreachable("Unexpected instruction!");
420   }
421 
422   buildIntrWithMD(Intrinsic::spv_assign_ptr_type, {I->getType()}, EltTyConst, I,
423                   {IRB->getInt32(AddressSpace)});
424 }
425 
426 void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I) {
427   Type *Ty = I->getType();
428   if (!Ty->isVoidTy() && requireAssignType(I) && !requireAssignPtrType(I)) {
429     setInsertPointSkippingPhis(*IRB, I->getNextNode());
430     Type *TypeToAssign = Ty;
431     if (auto *II = dyn_cast<IntrinsicInst>(I)) {
432       if (II->getIntrinsicID() == Intrinsic::spv_const_composite ||
433           II->getIntrinsicID() == Intrinsic::spv_undef) {
434         auto t = AggrConsts.find(II);
435         assert(t != AggrConsts.end());
436         TypeToAssign = t->second->getType();
437       }
438     }
439     Constant *Const = Constant::getNullValue(TypeToAssign);
440     buildIntrWithMD(Intrinsic::spv_assign_type, {Ty}, Const, I, {});
441   }
442   for (const auto &Op : I->operands()) {
443     if (isa<ConstantPointerNull>(Op) || isa<UndefValue>(Op) ||
444         // Check GetElementPtrConstantExpr case.
445         (isa<ConstantExpr>(Op) && isa<GEPOperator>(Op))) {
446       setInsertPointSkippingPhis(*IRB, I);
447       if (isa<UndefValue>(Op) && Op->getType()->isAggregateType())
448         buildIntrWithMD(Intrinsic::spv_assign_type, {IRB->getInt32Ty()}, Op,
449                         UndefValue::get(IRB->getInt32Ty()), {});
450       else
451         buildIntrWithMD(Intrinsic::spv_assign_type, {Op->getType()}, Op, Op,
452                         {});
453     }
454   }
455 }
456 
457 void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I) {
458   auto *II = dyn_cast<IntrinsicInst>(I);
459   if (II && II->getIntrinsicID() == Intrinsic::spv_const_composite &&
460       TrackConstants) {
461     IRB->SetInsertPoint(I->getNextNode());
462     Type *Ty = IRB->getInt32Ty();
463     auto t = AggrConsts.find(I);
464     assert(t != AggrConsts.end());
465     auto *NewOp = buildIntrWithMD(Intrinsic::spv_track_constant, {Ty, Ty},
466                                   t->second, I, {});
467     I->replaceAllUsesWith(NewOp);
468     NewOp->setArgOperand(0, I);
469   }
470   for (const auto &Op : I->operands()) {
471     if ((isa<ConstantAggregateZero>(Op) && Op->getType()->isVectorTy()) ||
472         isa<PHINode>(I) || isa<SwitchInst>(I))
473       TrackConstants = false;
474     if ((isa<ConstantData>(Op) || isa<ConstantExpr>(Op)) && TrackConstants) {
475       unsigned OpNo = Op.getOperandNo();
476       if (II && ((II->getIntrinsicID() == Intrinsic::spv_gep && OpNo == 0) ||
477                  (II->paramHasAttr(OpNo, Attribute::ImmArg))))
478         continue;
479       IRB->SetInsertPoint(I);
480       auto *NewOp = buildIntrWithMD(Intrinsic::spv_track_constant,
481                                     {Op->getType(), Op->getType()}, Op, Op, {});
482       I->setOperand(OpNo, NewOp);
483     }
484   }
485   if (I->hasName()) {
486     setInsertPointSkippingPhis(*IRB, I->getNextNode());
487     std::vector<Value *> Args = {I};
488     addStringImm(I->getName(), *IRB, Args);
489     IRB->CreateIntrinsic(Intrinsic::spv_assign_name, {I->getType()}, Args);
490   }
491 }
492 
493 bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) {
494   if (Func.isDeclaration())
495     return false;
496   F = &Func;
497   IRB = new IRBuilder<>(Func.getContext());
498   AggrConsts.clear();
499   AggrStores.clear();
500 
501   // StoreInst's operand type can be changed during the next transformations,
502   // so we need to store it in the set. Also store already transformed types.
503   for (auto &I : instructions(Func)) {
504     StoreInst *SI = dyn_cast<StoreInst>(&I);
505     if (!SI)
506       continue;
507     Type *ElTy = SI->getValueOperand()->getType();
508     if (ElTy->isAggregateType() || ElTy->isVectorTy())
509       AggrStores.insert(&I);
510   }
511 
512   IRB->SetInsertPoint(&Func.getEntryBlock(), Func.getEntryBlock().begin());
513   for (auto &GV : Func.getParent()->globals())
514     processGlobalValue(GV);
515 
516   preprocessUndefs();
517   preprocessCompositeConstants();
518   SmallVector<Instruction *> Worklist;
519   for (auto &I : instructions(Func))
520     Worklist.push_back(&I);
521 
522   for (auto &I : Worklist) {
523     insertAssignPtrTypeIntrs(I);
524     insertAssignTypeIntrs(I);
525   }
526 
527   for (auto *I : Worklist) {
528     TrackConstants = true;
529     if (!I->getType()->isVoidTy() || isa<StoreInst>(I))
530       IRB->SetInsertPoint(I->getNextNode());
531     I = visit(*I);
532     processInstrAfterVisit(I);
533   }
534   return true;
535 }
536 
537 FunctionPass *llvm::createSPIRVEmitIntrinsicsPass(SPIRVTargetMachine *TM) {
538   return new SPIRVEmitIntrinsics(TM);
539 }
540