LLVM  16.0.0git
SPIRVEmitIntrinsics.cpp
Go to the documentation of this file.
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 {
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;
57  DenseSet<Instruction *> AggrStores;
58  void preprocessCompositeConstants();
59  CallInst *buildIntrWithMD(Intrinsic::ID IntrID, ArrayRef<Type *> Types,
60  Value *Arg, Value *Arg2) {
62  MDTuple *TyMD = MDNode::get(F->getContext(), CM);
63  MetadataAsValue *VMD = MetadataAsValue::get(F->getContext(), TyMD);
64  return IRB->CreateIntrinsic(IntrID, {Types}, {Arg2, VMD});
65  }
66  void replaceMemInstrUses(Instruction *Old, Instruction *New);
67  void processInstrAfterVisit(Instruction *I);
68  void insertAssignTypeIntrs(Instruction *I);
69  void processGlobalValue(GlobalVariable &GV);
70 
71 public:
72  static char ID;
73  SPIRVEmitIntrinsics() : FunctionPass(ID) {
75  }
76  SPIRVEmitIntrinsics(SPIRVTargetMachine *_TM) : FunctionPass(ID), TM(_TM) {
78  }
79  Instruction *visitInstruction(Instruction &I) { return &I; }
80  Instruction *visitSwitchInst(SwitchInst &I);
81  Instruction *visitGetElementPtrInst(GetElementPtrInst &I);
82  Instruction *visitBitCastInst(BitCastInst &I);
83  Instruction *visitInsertElementInst(InsertElementInst &I);
84  Instruction *visitExtractElementInst(ExtractElementInst &I);
85  Instruction *visitInsertValueInst(InsertValueInst &I);
86  Instruction *visitExtractValueInst(ExtractValueInst &I);
87  Instruction *visitLoadInst(LoadInst &I);
88  Instruction *visitStoreInst(StoreInst &I);
89  Instruction *visitAllocaInst(AllocaInst &I);
90  Instruction *visitAtomicCmpXchgInst(AtomicCmpXchgInst &I);
91  Instruction *visitUnreachableInst(UnreachableInst &I);
92  bool runOnFunction(Function &F) override;
93 };
94 } // namespace
95 
97 
98 INITIALIZE_PASS(SPIRVEmitIntrinsics, "emit-intrinsics", "SPIRV emit intrinsics",
99  false, false)
100 
101 static inline bool isAssignTypeInstr(const Instruction *I) {
102  return isa<IntrinsicInst>(I) &&
103  cast<IntrinsicInst>(I)->getIntrinsicID() == Intrinsic::spv_assign_type;
104 }
105 
107  return isa<StoreInst>(I) || isa<LoadInst>(I) || isa<InsertValueInst>(I) ||
108  isa<ExtractValueInst>(I) || isa<AtomicCmpXchgInst>(I);
109 }
110 
111 static bool isAggrToReplace(const Value *V) {
112  return isa<ConstantAggregate>(V) || isa<ConstantDataArray>(V) ||
113  (isa<ConstantAggregateZero>(V) && !V->getType()->isVectorTy());
114 }
115 
117  if (isa<PHINode>(I))
118  B.SetInsertPoint(I->getParent(), I->getParent()->getFirstInsertionPt());
119  else
120  B.SetInsertPoint(I);
121 }
122 
124  IntrinsicInst *Intr = dyn_cast<IntrinsicInst>(I);
125  if (Intr) {
126  switch (Intr->getIntrinsicID()) {
127  case Intrinsic::invariant_start:
128  case Intrinsic::invariant_end:
129  return false;
130  }
131  }
132  return true;
133 }
134 
135 void SPIRVEmitIntrinsics::replaceMemInstrUses(Instruction *Old,
136  Instruction *New) {
137  while (!Old->user_empty()) {
138  auto *U = Old->user_back();
139  if (isAssignTypeInstr(U)) {
140  IRB->SetInsertPoint(U);
141  SmallVector<Value *, 2> Args = {New, U->getOperand(1)};
142  IRB->CreateIntrinsic(Intrinsic::spv_assign_type, {New->getType()}, Args);
143  U->eraseFromParent();
144  } else if (isMemInstrToReplace(U) || isa<ReturnInst>(U) ||
145  isa<CallInst>(U)) {
146  U->replaceUsesOfWith(Old, New);
147  } else {
148  llvm_unreachable("illegal aggregate intrinsic user");
149  }
150  }
151  Old->eraseFromParent();
152 }
153 
154 void SPIRVEmitIntrinsics::preprocessCompositeConstants() {
155  std::queue<Instruction *> Worklist;
156  for (auto &I : instructions(F))
157  Worklist.push(&I);
158 
159  while (!Worklist.empty()) {
160  auto *I = Worklist.front();
161  assert(I);
162  bool KeepInst = false;
163  for (const auto &Op : I->operands()) {
164  auto BuildCompositeIntrinsic = [&KeepInst, &Worklist, &I, &Op,
165  this](Constant *AggrC,
167  IRB->SetInsertPoint(I);
168  auto *CCI =
169  IRB->CreateIntrinsic(Intrinsic::spv_const_composite, {}, {Args});
170  Worklist.push(CCI);
171  I->replaceUsesOfWith(Op, CCI);
172  KeepInst = true;
173  AggrConsts[CCI] = AggrC;
174  };
175 
176  if (auto *AggrC = dyn_cast<ConstantAggregate>(Op)) {
177  SmallVector<Value *> Args(AggrC->op_begin(), AggrC->op_end());
178  BuildCompositeIntrinsic(AggrC, Args);
179  } else if (auto *AggrC = dyn_cast<ConstantDataArray>(Op)) {
181  for (unsigned i = 0; i < AggrC->getNumElements(); ++i)
182  Args.push_back(AggrC->getElementAsConstant(i));
183  BuildCompositeIntrinsic(AggrC, Args);
184  } else if (isa<ConstantAggregateZero>(Op) &&
185  !Op->getType()->isVectorTy()) {
186  auto *AggrC = cast<ConstantAggregateZero>(Op);
187  SmallVector<Value *> Args(AggrC->op_begin(), AggrC->op_end());
188  BuildCompositeIntrinsic(AggrC, Args);
189  }
190  }
191  if (!KeepInst)
192  Worklist.pop();
193  }
194 }
195 
196 Instruction *SPIRVEmitIntrinsics::visitSwitchInst(SwitchInst &I) {
198  for (auto &Op : I.operands())
199  if (Op.get()->getType()->isSized())
200  Args.push_back(Op);
201  IRB->CreateIntrinsic(Intrinsic::spv_switch, {I.getOperand(0)->getType()},
202  {Args});
203  return &I;
204 }
205 
206 Instruction *SPIRVEmitIntrinsics::visitGetElementPtrInst(GetElementPtrInst &I) {
207  SmallVector<Type *, 2> Types = {I.getType(), I.getOperand(0)->getType()};
209  Args.push_back(IRB->getInt1(I.isInBounds()));
210  for (auto &Op : I.operands())
211  Args.push_back(Op);
212  auto *NewI = IRB->CreateIntrinsic(Intrinsic::spv_gep, {Types}, {Args});
213  I.replaceAllUsesWith(NewI);
214  I.eraseFromParent();
215  return NewI;
216 }
217 
218 Instruction *SPIRVEmitIntrinsics::visitBitCastInst(BitCastInst &I) {
219  SmallVector<Type *, 2> Types = {I.getType(), I.getOperand(0)->getType()};
220  SmallVector<Value *> Args(I.op_begin(), I.op_end());
221  auto *NewI = IRB->CreateIntrinsic(Intrinsic::spv_bitcast, {Types}, {Args});
222  std::string InstName = I.hasName() ? I.getName().str() : "";
223  I.replaceAllUsesWith(NewI);
224  I.eraseFromParent();
225  NewI->setName(InstName);
226  return NewI;
227 }
228 
229 Instruction *SPIRVEmitIntrinsics::visitInsertElementInst(InsertElementInst &I) {
230  SmallVector<Type *, 4> Types = {I.getType(), I.getOperand(0)->getType(),
231  I.getOperand(1)->getType(),
232  I.getOperand(2)->getType()};
233  SmallVector<Value *> Args(I.op_begin(), I.op_end());
234  auto *NewI = IRB->CreateIntrinsic(Intrinsic::spv_insertelt, {Types}, {Args});
235  std::string InstName = I.hasName() ? I.getName().str() : "";
236  I.replaceAllUsesWith(NewI);
237  I.eraseFromParent();
238  NewI->setName(InstName);
239  return NewI;
240 }
241 
242 Instruction *
243 SPIRVEmitIntrinsics::visitExtractElementInst(ExtractElementInst &I) {
244  SmallVector<Type *, 3> Types = {I.getType(), I.getVectorOperandType(),
245  I.getIndexOperand()->getType()};
246  SmallVector<Value *, 2> Args = {I.getVectorOperand(), I.getIndexOperand()};
247  auto *NewI = IRB->CreateIntrinsic(Intrinsic::spv_extractelt, {Types}, {Args});
248  std::string InstName = I.hasName() ? I.getName().str() : "";
249  I.replaceAllUsesWith(NewI);
250  I.eraseFromParent();
251  NewI->setName(InstName);
252  return NewI;
253 }
254 
255 Instruction *SPIRVEmitIntrinsics::visitInsertValueInst(InsertValueInst &I) {
256  SmallVector<Type *, 1> Types = {I.getInsertedValueOperand()->getType()};
258  for (auto &Op : I.operands())
259  if (isa<UndefValue>(Op))
260  Args.push_back(UndefValue::get(IRB->getInt32Ty()));
261  else
262  Args.push_back(Op);
263  for (auto &Op : I.indices())
264  Args.push_back(IRB->getInt32(Op));
265  Instruction *NewI =
266  IRB->CreateIntrinsic(Intrinsic::spv_insertv, {Types}, {Args});
267  replaceMemInstrUses(&I, NewI);
268  return NewI;
269 }
270 
271 Instruction *SPIRVEmitIntrinsics::visitExtractValueInst(ExtractValueInst &I) {
273  for (auto &Op : I.operands())
274  Args.push_back(Op);
275  for (auto &Op : I.indices())
276  Args.push_back(IRB->getInt32(Op));
277  auto *NewI =
278  IRB->CreateIntrinsic(Intrinsic::spv_extractv, {I.getType()}, {Args});
279  I.replaceAllUsesWith(NewI);
280  I.eraseFromParent();
281  return NewI;
282 }
283 
284 Instruction *SPIRVEmitIntrinsics::visitLoadInst(LoadInst &I) {
285  if (!I.getType()->isAggregateType())
286  return &I;
287  TrackConstants = false;
288  const auto *TLI = TM->getSubtargetImpl()->getTargetLowering();
290  TLI->getLoadMemOperandFlags(I, F->getParent()->getDataLayout());
291  auto *NewI =
292  IRB->CreateIntrinsic(Intrinsic::spv_load, {I.getOperand(0)->getType()},
293  {I.getPointerOperand(), IRB->getInt16(Flags),
294  IRB->getInt8(I.getAlign().value())});
295  replaceMemInstrUses(&I, NewI);
296  return NewI;
297 }
298 
299 Instruction *SPIRVEmitIntrinsics::visitStoreInst(StoreInst &I) {
300  if (!AggrStores.contains(&I))
301  return &I;
302  TrackConstants = false;
303  const auto *TLI = TM->getSubtargetImpl()->getTargetLowering();
305  TLI->getStoreMemOperandFlags(I, F->getParent()->getDataLayout());
306  auto *PtrOp = I.getPointerOperand();
307  auto *NewI = IRB->CreateIntrinsic(
308  Intrinsic::spv_store, {I.getValueOperand()->getType(), PtrOp->getType()},
309  {I.getValueOperand(), PtrOp, IRB->getInt16(Flags),
310  IRB->getInt8(I.getAlign().value())});
311  I.eraseFromParent();
312  return NewI;
313 }
314 
315 Instruction *SPIRVEmitIntrinsics::visitAllocaInst(AllocaInst &I) {
316  TrackConstants = false;
317  Type *PtrTy = I.getType();
318  auto *NewI = IRB->CreateIntrinsic(Intrinsic::spv_alloca, {PtrTy}, {});
319  std::string InstName = I.hasName() ? I.getName().str() : "";
320  I.replaceAllUsesWith(NewI);
321  I.eraseFromParent();
322  NewI->setName(InstName);
323  return NewI;
324 }
325 
326 Instruction *SPIRVEmitIntrinsics::visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
327  assert(I.getType()->isAggregateType() && "Aggregate result is expected");
329  for (auto &Op : I.operands())
330  Args.push_back(Op);
331  Args.push_back(IRB->getInt32(I.getSyncScopeID()));
332  Args.push_back(IRB->getInt32(
333  static_cast<uint32_t>(getMemSemantics(I.getSuccessOrdering()))));
334  Args.push_back(IRB->getInt32(
335  static_cast<uint32_t>(getMemSemantics(I.getFailureOrdering()))));
336  auto *NewI = IRB->CreateIntrinsic(Intrinsic::spv_cmpxchg,
337  {I.getPointerOperand()->getType()}, {Args});
338  replaceMemInstrUses(&I, NewI);
339  return NewI;
340 }
341 
342 Instruction *SPIRVEmitIntrinsics::visitUnreachableInst(UnreachableInst &I) {
343  IRB->SetInsertPoint(&I);
344  IRB->CreateIntrinsic(Intrinsic::spv_unreachable, {}, {});
345  return &I;
346 }
347 
348 void SPIRVEmitIntrinsics::processGlobalValue(GlobalVariable &GV) {
349  // Skip special artifical variable llvm.global.annotations.
350  if (GV.getName() == "llvm.global.annotations")
351  return;
352  if (GV.hasInitializer() && !isa<UndefValue>(GV.getInitializer())) {
353  Constant *Init = GV.getInitializer();
354  Type *Ty = isAggrToReplace(Init) ? IRB->getInt32Ty() : Init->getType();
356  auto *InitInst = IRB->CreateIntrinsic(Intrinsic::spv_init_global,
357  {GV.getType(), Ty}, {&GV, Const});
358  InitInst->setArgOperand(1, Init);
359  }
360  if ((!GV.hasInitializer() || isa<UndefValue>(GV.getInitializer())) &&
361  GV.getNumUses() == 0)
362  IRB->CreateIntrinsic(Intrinsic::spv_unref_global, GV.getType(), &GV);
363 }
364 
365 void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I) {
366  Type *Ty = I->getType();
367  if (!Ty->isVoidTy() && requireAssignType(I)) {
368  setInsertPointSkippingPhis(*IRB, I->getNextNode());
369  Type *TypeToAssign = Ty;
370  if (auto *II = dyn_cast<IntrinsicInst>(I)) {
371  if (II->getIntrinsicID() == Intrinsic::spv_const_composite) {
372  auto t = AggrConsts.find(II);
373  assert(t != AggrConsts.end());
374  TypeToAssign = t->second->getType();
375  }
376  }
377  Constant *Const = Constant::getNullValue(TypeToAssign);
378  buildIntrWithMD(Intrinsic::spv_assign_type, {Ty}, Const, I);
379  }
380  for (const auto &Op : I->operands()) {
381  if (isa<ConstantPointerNull>(Op) || isa<UndefValue>(Op) ||
382  // Check GetElementPtrConstantExpr case.
383  (isa<ConstantExpr>(Op) && isa<GEPOperator>(Op))) {
385  if (isa<UndefValue>(Op) && Op->getType()->isAggregateType())
386  buildIntrWithMD(Intrinsic::spv_assign_type, {IRB->getInt32Ty()}, Op,
387  UndefValue::get(IRB->getInt32Ty()));
388  else
389  buildIntrWithMD(Intrinsic::spv_assign_type, {Op->getType()}, Op, Op);
390  }
391  }
392 }
393 
394 void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I) {
395  auto *II = dyn_cast<IntrinsicInst>(I);
396  if (II && II->getIntrinsicID() == Intrinsic::spv_const_composite &&
397  TrackConstants) {
398  IRB->SetInsertPoint(I->getNextNode());
399  Type *Ty = IRB->getInt32Ty();
400  auto t = AggrConsts.find(I);
401  assert(t != AggrConsts.end());
402  auto *NewOp =
403  buildIntrWithMD(Intrinsic::spv_track_constant, {Ty, Ty}, t->second, I);
404  I->replaceAllUsesWith(NewOp);
405  NewOp->setArgOperand(0, I);
406  }
407  for (const auto &Op : I->operands()) {
408  if ((isa<ConstantAggregateZero>(Op) && Op->getType()->isVectorTy()) ||
409  isa<PHINode>(I) || isa<SwitchInst>(I))
410  TrackConstants = false;
411  if ((isa<ConstantData>(Op) || isa<ConstantExpr>(Op)) && TrackConstants) {
412  unsigned OpNo = Op.getOperandNo();
413  if (II && ((II->getIntrinsicID() == Intrinsic::spv_gep && OpNo == 0) ||
414  (II->paramHasAttr(OpNo, Attribute::ImmArg))))
415  continue;
416  IRB->SetInsertPoint(I);
417  auto *NewOp = buildIntrWithMD(Intrinsic::spv_track_constant,
418  {Op->getType(), Op->getType()}, Op, Op);
419  I->setOperand(OpNo, NewOp);
420  }
421  }
422  if (I->hasName()) {
423  setInsertPointSkippingPhis(*IRB, I->getNextNode());
424  std::vector<Value *> Args = {I};
425  addStringImm(I->getName(), *IRB, Args);
426  IRB->CreateIntrinsic(Intrinsic::spv_assign_name, {I->getType()}, Args);
427  }
428 }
429 
431  if (Func.isDeclaration())
432  return false;
433  F = &Func;
434  IRB = new IRBuilder<>(Func.getContext());
435  AggrConsts.clear();
436  AggrStores.clear();
437 
438  // StoreInst's operand type can be changed during the next transformations,
439  // so we need to store it in the set. Also store already transformed types.
440  for (auto &I : instructions(Func)) {
441  StoreInst *SI = dyn_cast<StoreInst>(&I);
442  if (!SI)
443  continue;
444  Type *ElTy = SI->getValueOperand()->getType();
445  PointerType *PTy = cast<PointerType>(SI->getOperand(1)->getType());
446  if (ElTy->isAggregateType() || ElTy->isVectorTy() ||
447  !PTy->isOpaqueOrPointeeTypeMatches(ElTy))
448  AggrStores.insert(&I);
449  }
450 
451  IRB->SetInsertPoint(&Func.getEntryBlock().front());
452  for (auto &GV : Func.getParent()->globals())
453  processGlobalValue(GV);
454 
455  preprocessCompositeConstants();
457  for (auto &I : instructions(Func))
458  Worklist.push_back(&I);
459 
460  for (auto &I : Worklist)
461  insertAssignTypeIntrs(I);
462 
463  for (auto *I : Worklist) {
464  TrackConstants = true;
465  if (!I->getType()->isVoidTy() || isa<StoreInst>(I))
466  IRB->SetInsertPoint(I->getNextNode());
467  I = visit(*I);
468  processInstrAfterVisit(I);
469  }
470  return true;
471 }
472 
474  return new SPIRVEmitIntrinsics(TM);
475 }
isAggrToReplace
static bool isAggrToReplace(const Value *V)
Definition: SPIRVEmitIntrinsics.cpp:111
i
i
Definition: README.txt:29
llvm::IRBuilderBase::getInt32Ty
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition: IRBuilder.h:509
llvm::IRBuilderBase::SetInsertPoint
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition: IRBuilder.h:179
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::AArch64PACKey::ID
ID
Definition: AArch64BaseInfo.h:818
InstIterator.h
llvm::ExtractElementInst
This instruction extracts a single (scalar) element from a VectorType value.
Definition: Instructions.h:1872
llvm::Function
Definition: Function.h:60
llvm::BitCastInst
This class represents a no-op cast from one type to another.
Definition: Instructions.h:5256
isMemInstrToReplace
static bool isMemInstrToReplace(Instruction *I)
Definition: SPIRVEmitIntrinsics.cpp:106
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::IRBuilder<>
llvm::GlobalVariable
Definition: GlobalVariable.h:39
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::MetadataAsValue
Metadata wrapper in the Value hierarchy.
Definition: Metadata.h:176
setInsertPointSkippingPhis
static void setInsertPointSkippingPhis(IRBuilder<> &B, Instruction *I)
Definition: SPIRVEmitIntrinsics.cpp:116
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
llvm::IRBuilderBase::getInt1
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
Definition: IRBuilder.h:444
llvm::MDNode::get
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1400
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::GlobalVariable::hasInitializer
bool hasInitializer() const
Definitions have initializers, declarations don't.
Definition: GlobalVariable.h:91
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:187
llvm::PointerType::isOpaqueOrPointeeTypeMatches
bool isOpaqueOrPointeeTypeMatches(Type *Ty)
Return true if either this is an opaque pointer type or if this pointee type matches Ty.
Definition: DerivedTypes.h:688
llvm::addStringImm
void addStringImm(const StringRef &Str, MCInst &Inst)
Definition: SPIRVUtils.cpp:49
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:24
Intr
unsigned Intr
Definition: AMDGPUBaseInfo.cpp:2555
SI
@ SI
Definition: SIInstrInfo.cpp:7966
llvm::MDTuple
Tuple of metadata.
Definition: Metadata.h:1329
t
bitcast float %x to i32 %s=and i32 %t, 2147483647 %d=bitcast i32 %s to float ret float %d } declare float @fabsf(float %n) define float @bar(float %x) nounwind { %d=call float @fabsf(float %x) ret float %d } This IR(from PR6194):target datalayout="e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple="x86_64-apple-darwin10.0.0" %0=type { double, double } %struct.float3=type { float, float, float } define void @test(%0, %struct.float3 *nocapture %res) nounwind noinline ssp { entry:%tmp18=extractvalue %0 %0, 0 t
Definition: README-SSE.txt:788
llvm::Type::isVectorTy
bool isVectorTy() const
True if this is an instance of VectorType.
Definition: Type.h:246
llvm::InsertElementInst
This instruction inserts a single (scalar) element into a VectorType value.
Definition: Instructions.h:1936
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::Instruction
Definition: Instruction.h:42
SPIRVUtils.h
llvm::PassRegistry
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
llvm::Value::setName
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:375
llvm::UndefValue::get
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1713
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
SPIRVTargetMachine.h
llvm::DenseSet
Implements a dense probed hash-table based set.
Definition: DenseSet.h:268
llvm::instructions
inst_range instructions(Function *F)
Definition: InstIterator.h:133
llvm::StoreInst
An instruction for storing to memory.
Definition: Instructions.h:298
llvm::getMemSemantics
SPIRV::MemorySemantics::MemorySemantics getMemSemantics(AtomicOrdering Ord)
Definition: SPIRVUtils.cpp:196
llvm::GlobalVariable::getInitializer
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
Definition: GlobalVariable.h:135
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::Instruction::eraseFromParent
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:81
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::clear
void clear()
Definition: DenseMap.h:110
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
llvm::Instruction::user_back
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
Definition: Instruction.h:88
llvm::IRBuilderBase::getInt32
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition: IRBuilder.h:469
llvm::DenseMap
Definition: DenseMap.h:714
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::GetElementPtrInst
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:929
requireAssignType
static bool requireAssignType(Instruction *I)
Definition: SPIRVEmitIntrinsics.cpp:123
llvm::PointerType
Class to represent pointers.
Definition: DerivedTypes.h:632
inline
into xmm2 addss xmm2 xmm1 xmm3 addss xmm3 movaps xmm0 unpcklps xmm0 ret seems silly when it could just be one addps Expand libm rounding functions inline
Definition: README-SSE.txt:72
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
llvm::MachineMemOperand::Flags
Flags
Flags values. These may be or'd together.
Definition: MachineMemOperand.h:130
SPIRV.h
IRBuilder.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::Value::user_empty
bool user_empty() const
Definition: Value.h:385
llvm::Type::isVoidTy
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:139
llvm::IRBuilderBase::CreateIntrinsic
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Definition: IRBuilder.cpp:962
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::clear
void clear()
Definition: DenseSet.h:92
getType
static M68kRelType getType(unsigned Kind, MCSymbolRefExpr::VariantKind &Modifier, bool &IsPCRel)
Definition: M68kELFObjectWriter.cpp:48
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::logicalview::LVCompareKind::Types
@ Types
InstVisitor.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::Value::getNumUses
unsigned getNumUses() const
This method computes the number of uses of this Value.
Definition: Value.cpp:254
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::contains
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition: DenseSet.h:185
llvm::ms_demangle::IntrinsicFunctionKind::New
@ New
uint32_t
llvm::createSPIRVEmitIntrinsicsPass
FunctionPass * createSPIRVEmitIntrinsicsPass(SPIRVTargetMachine *TM)
Definition: SPIRVEmitIntrinsics.cpp:473
llvm::ValueAsMetadata::getConstant
static ConstantAsMetadata * getConstant(Value *C)
Definition: Metadata.h:367
llvm::InstVisitor
Base class for instruction visitors.
Definition: InstVisitor.h:78
llvm::initializeSPIRVEmitIntrinsicsPass
void initializeSPIRVEmitIntrinsicsPass(PassRegistry &)
llvm::ifs::IFSSymbolType::Func
@ Func
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:308
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:174
llvm::CallBase::setArgOperand
void setArgOperand(unsigned i, Value *v)
Definition: InstrTypes.h:1347
llvm::Init
Definition: Record.h:281
llvm::SPIRVTargetMachine
Definition: SPIRVTargetMachine.h:20
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:85
llvm::ConstantAsMetadata
Definition: Metadata.h:413
llvm::Constant::getNullValue
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:350
llvm::MetadataAsValue::get
static MetadataAsValue * get(LLVMContext &Context, Metadata *MD)
Definition: Metadata.cpp:103
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::end
iterator end()
Definition: DenseMap.h:84
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:348
llvm::ExtractValueInst
This instruction extracts a struct member or array element value from an aggregate value.
Definition: Instructions.h:2446
INITIALIZE_PASS
INITIALIZE_PASS(SPIRVEmitIntrinsics, "emit-intrinsics", "SPIRV emit intrinsics", false, false) static inline bool isAssignTypeInstr(const Instruction *I)
Definition: SPIRVEmitIntrinsics.cpp:98
llvm::codeview::ModifierOptions::Const
@ Const
llvm::IntrinsicInst
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:46
llvm::IRBuilderBase::getInt16
ConstantInt * getInt16(uint16_t C)
Get a constant 16-bit value.
Definition: IRBuilder.h:464
llvm::IRBuilderBase::getInt8
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
Definition: IRBuilder.h:459
llvm::GlobalValue::getType
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:290
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1474
llvm::omp::RTLDependInfoFields::Flags
@ Flags
llvm::UnreachableInst
This function has undefined behavior.
Definition: Instructions.h:4771
llvm::Type::isAggregateType
bool isAggregateType() const
Return true if the type is an aggregate type.
Definition: Type.h:276
llvm::SwitchInst
Multiway switch.
Definition: Instructions.h:3278
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
llvm::AllocaInst
an instruction to allocate memory on the stack
Definition: Instructions.h:59
llvm::InsertValueInst
This instruction inserts a struct field of array element value into an aggregate value.
Definition: Instructions.h:2557
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::AtomicCmpXchgInst
An instruction that atomically checks whether a specified value is in a memory location,...
Definition: Instructions.h:510
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:39