LLVM  10.0.0svn
AMDGPUPrintfRuntimeBinding.cpp
Go to the documentation of this file.
1 //=== AMDGPUPrintfRuntimeBinding.cpp - OpenCL printf implementation -------===//
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 // \file
9 //
10 // The pass bind printfs to a kernel arg pointer that will be bound to a buffer
11 // later by the runtime.
12 //
13 // This pass traverses the functions in the module and converts
14 // each call to printf to a sequence of operations that
15 // store the following into the printf buffer:
16 // - format string (passed as a module's metadata unique ID)
17 // - bitwise copies of printf arguments
18 // The backend passes will need to store metadata in the kernel
19 //===----------------------------------------------------------------------===//
20 
21 #include "AMDGPU.h"
22 #include "llvm/ADT/SmallString.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/ADT/Triple.h"
27 #include "llvm/CodeGen/Passes.h"
28 #include "llvm/IR/Constants.h"
29 #include "llvm/IR/DataLayout.h"
30 #include "llvm/IR/Dominators.h"
31 #include "llvm/IR/GlobalVariable.h"
32 #include "llvm/IR/IRBuilder.h"
33 #include "llvm/IR/InstVisitor.h"
34 #include "llvm/IR/Instructions.h"
35 #include "llvm/IR/Module.h"
36 #include "llvm/IR/Type.h"
38 #include "llvm/Support/Debug.h"
41 using namespace llvm;
42 
43 #define DEBUG_TYPE "printfToRuntime"
44 #define DWORD_ALIGN 4
45 
46 namespace {
47 class LLVM_LIBRARY_VISIBILITY AMDGPUPrintfRuntimeBinding final
48  : public ModulePass,
49  public InstVisitor<AMDGPUPrintfRuntimeBinding> {
50 
51 public:
52  static char ID;
53 
54  explicit AMDGPUPrintfRuntimeBinding();
55 
56  void visitCallSite(CallSite CS) {
58  if (F && F->hasName() && F->getName() == "printf")
59  Printfs.push_back(CS.getInstruction());
60  }
61 
62 private:
63  bool runOnModule(Module &M) override;
64  void getConversionSpecifiers(SmallVectorImpl<char> &OpConvSpecifiers,
65  StringRef fmt, size_t num_ops) const;
66 
67  bool shouldPrintAsStr(char Specifier, Type *OpType) const;
68  bool
69  lowerPrintfForGpu(Module &M,
70  function_ref<const TargetLibraryInfo &(Function &)> GetTLI);
71 
72  void getAnalysisUsage(AnalysisUsage &AU) const override {
75  }
76 
78  return SimplifyInstruction(I, {*TD, TLI, DT});
79  }
80 
81  const DataLayout *TD;
82  const DominatorTree *DT;
84 };
85 } // namespace
86 
88 
89 INITIALIZE_PASS_BEGIN(AMDGPUPrintfRuntimeBinding,
90  "amdgpu-printf-runtime-binding", "AMDGPU Printf lowering",
91  false, false)
94 INITIALIZE_PASS_END(AMDGPUPrintfRuntimeBinding, "amdgpu-printf-runtime-binding",
96 
97 char &llvm::AMDGPUPrintfRuntimeBindingID = AMDGPUPrintfRuntimeBinding::ID;
98 
99 namespace llvm {
101  return new AMDGPUPrintfRuntimeBinding();
102 }
103 } // namespace llvm
104 
105 AMDGPUPrintfRuntimeBinding::AMDGPUPrintfRuntimeBinding()
106  : ModulePass(ID), TD(nullptr), DT(nullptr) {
108 }
109 
110 void AMDGPUPrintfRuntimeBinding::getConversionSpecifiers(
111  SmallVectorImpl<char> &OpConvSpecifiers, StringRef Fmt,
112  size_t NumOps) const {
113  // not all format characters are collected.
114  // At this time the format characters of interest
115  // are %p and %s, which use to know if we
116  // are either storing a literal string or a
117  // pointer to the printf buffer.
118  static const char ConvSpecifiers[] = "cdieEfgGaosuxXp";
119  size_t CurFmtSpecifierIdx = 0;
120  size_t PrevFmtSpecifierIdx = 0;
121 
122  while ((CurFmtSpecifierIdx = Fmt.find_first_of(
123  ConvSpecifiers, CurFmtSpecifierIdx)) != StringRef::npos) {
124  bool ArgDump = false;
125  StringRef CurFmt = Fmt.substr(PrevFmtSpecifierIdx,
126  CurFmtSpecifierIdx - PrevFmtSpecifierIdx);
127  size_t pTag = CurFmt.find_last_of("%");
128  if (pTag != StringRef::npos) {
129  ArgDump = true;
130  while (pTag && CurFmt[--pTag] == '%') {
131  ArgDump = !ArgDump;
132  }
133  }
134 
135  if (ArgDump)
136  OpConvSpecifiers.push_back(Fmt[CurFmtSpecifierIdx]);
137 
138  PrevFmtSpecifierIdx = ++CurFmtSpecifierIdx;
139  }
140 }
141 
142 bool AMDGPUPrintfRuntimeBinding::shouldPrintAsStr(char Specifier,
143  Type *OpType) const {
144  if (Specifier != 's')
145  return false;
146  const PointerType *PT = dyn_cast<PointerType>(OpType);
147  if (!PT || PT->getAddressSpace() != AMDGPUAS::CONSTANT_ADDRESS)
148  return false;
149  Type *ElemType = PT->getContainedType(0);
150  if (ElemType->getTypeID() != Type::IntegerTyID)
151  return false;
152  IntegerType *ElemIType = cast<IntegerType>(ElemType);
153  return ElemIType->getBitWidth() == 8;
154 }
155 
156 bool AMDGPUPrintfRuntimeBinding::lowerPrintfForGpu(
157  Module &M, function_ref<const TargetLibraryInfo &(Function &)> GetTLI) {
158  LLVMContext &Ctx = M.getContext();
159  IRBuilder<> Builder(Ctx);
160  Type *I32Ty = Type::getInt32Ty(Ctx);
161  unsigned UniqID = 0;
162  // NB: This is important for this string size to be divizable by 4
163  const char NonLiteralStr[4] = "???";
164 
165  for (auto P : Printfs) {
166  CallInst *CI = dyn_cast<CallInst>(P);
167 
168  unsigned NumOps = CI->getNumArgOperands();
169 
170  SmallString<16> OpConvSpecifiers;
171  Value *Op = CI->getArgOperand(0);
172 
173  if (auto LI = dyn_cast<LoadInst>(Op)) {
174  Op = LI->getPointerOperand();
175  for (auto Use : Op->users()) {
176  if (auto SI = dyn_cast<StoreInst>(Use)) {
177  Op = SI->getValueOperand();
178  break;
179  }
180  }
181  }
182 
183  if (auto I = dyn_cast<Instruction>(Op)) {
184  Value *Op_simplified = simplify(I, &GetTLI(*I->getFunction()));
185  if (Op_simplified)
186  Op = Op_simplified;
187  }
188 
189  ConstantExpr *ConstExpr = dyn_cast<ConstantExpr>(Op);
190 
191  if (ConstExpr) {
192  GlobalVariable *GVar = dyn_cast<GlobalVariable>(ConstExpr->getOperand(0));
193 
194  StringRef Str("unknown");
195  if (GVar && GVar->hasInitializer()) {
196  auto Init = GVar->getInitializer();
197  if (auto CA = dyn_cast<ConstantDataArray>(Init)) {
198  if (CA->isString())
199  Str = CA->getAsCString();
200  } else if (isa<ConstantAggregateZero>(Init)) {
201  Str = "";
202  }
203  //
204  // we need this call to ascertain
205  // that we are printing a string
206  // or a pointer. It takes out the
207  // specifiers and fills up the first
208  // arg
209  getConversionSpecifiers(OpConvSpecifiers, Str, NumOps - 1);
210  }
211  // Add metadata for the string
212  std::string AStreamHolder;
213  raw_string_ostream Sizes(AStreamHolder);
214  int Sum = DWORD_ALIGN;
215  Sizes << CI->getNumArgOperands() - 1;
216  Sizes << ':';
217  for (unsigned ArgCount = 1; ArgCount < CI->getNumArgOperands() &&
218  ArgCount <= OpConvSpecifiers.size();
219  ArgCount++) {
220  Value *Arg = CI->getArgOperand(ArgCount);
221  Type *ArgType = Arg->getType();
222  unsigned ArgSize = TD->getTypeAllocSizeInBits(ArgType);
223  ArgSize = ArgSize / 8;
224  //
225  // ArgSize by design should be a multiple of DWORD_ALIGN,
226  // expand the arguments that do not follow this rule.
227  //
228  if (ArgSize % DWORD_ALIGN != 0) {
229  llvm::Type *ResType = llvm::Type::getInt32Ty(Ctx);
230  VectorType *LLVMVecType = llvm::dyn_cast<llvm::VectorType>(ArgType);
231  int NumElem = LLVMVecType ? LLVMVecType->getNumElements() : 1;
232  if (LLVMVecType && NumElem > 1)
233  ResType = llvm::VectorType::get(ResType, NumElem);
234  Builder.SetInsertPoint(CI);
235  Builder.SetCurrentDebugLocation(CI->getDebugLoc());
236  if (OpConvSpecifiers[ArgCount - 1] == 'x' ||
237  OpConvSpecifiers[ArgCount - 1] == 'X' ||
238  OpConvSpecifiers[ArgCount - 1] == 'u' ||
239  OpConvSpecifiers[ArgCount - 1] == 'o')
240  Arg = Builder.CreateZExt(Arg, ResType);
241  else
242  Arg = Builder.CreateSExt(Arg, ResType);
243  ArgType = Arg->getType();
244  ArgSize = TD->getTypeAllocSizeInBits(ArgType);
245  ArgSize = ArgSize / 8;
246  CI->setOperand(ArgCount, Arg);
247  }
248  if (OpConvSpecifiers[ArgCount - 1] == 'f') {
249  ConstantFP *FpCons = dyn_cast<ConstantFP>(Arg);
250  if (FpCons)
251  ArgSize = 4;
252  else {
253  FPExtInst *FpExt = dyn_cast<FPExtInst>(Arg);
254  if (FpExt && FpExt->getType()->isDoubleTy() &&
255  FpExt->getOperand(0)->getType()->isFloatTy())
256  ArgSize = 4;
257  }
258  }
259  if (shouldPrintAsStr(OpConvSpecifiers[ArgCount - 1], ArgType)) {
260  if (ConstantExpr *ConstExpr = dyn_cast<ConstantExpr>(Arg)) {
261  GlobalVariable *GV =
262  dyn_cast<GlobalVariable>(ConstExpr->getOperand(0));
263  if (GV && GV->hasInitializer()) {
264  Constant *Init = GV->getInitializer();
266  if (Init->isZeroValue() || CA->isString()) {
267  size_t SizeStr = Init->isZeroValue()
268  ? 1
269  : (strlen(CA->getAsCString().data()) + 1);
270  size_t Rem = SizeStr % DWORD_ALIGN;
271  size_t NSizeStr = 0;
272  LLVM_DEBUG(dbgs() << "Printf string original size = " << SizeStr
273  << '\n');
274  if (Rem) {
275  NSizeStr = SizeStr + (DWORD_ALIGN - Rem);
276  } else {
277  NSizeStr = SizeStr;
278  }
279  ArgSize = NSizeStr;
280  }
281  } else {
282  ArgSize = sizeof(NonLiteralStr);
283  }
284  } else {
285  ArgSize = sizeof(NonLiteralStr);
286  }
287  }
288  LLVM_DEBUG(dbgs() << "Printf ArgSize (in buffer) = " << ArgSize
289  << " for type: " << *ArgType << '\n');
290  Sizes << ArgSize << ':';
291  Sum += ArgSize;
292  }
293  LLVM_DEBUG(dbgs() << "Printf format string in source = " << Str.str()
294  << '\n');
295  for (size_t I = 0; I < Str.size(); ++I) {
296  // Rest of the C escape sequences (e.g. \') are handled correctly
297  // by the MDParser
298  switch (Str[I]) {
299  case '\a':
300  Sizes << "\\a";
301  break;
302  case '\b':
303  Sizes << "\\b";
304  break;
305  case '\f':
306  Sizes << "\\f";
307  break;
308  case '\n':
309  Sizes << "\\n";
310  break;
311  case '\r':
312  Sizes << "\\r";
313  break;
314  case '\v':
315  Sizes << "\\v";
316  break;
317  case ':':
318  // ':' cannot be scanned by Flex, as it is defined as a delimiter
319  // Replace it with it's octal representation \72
320  Sizes << "\\72";
321  break;
322  default:
323  Sizes << Str[I];
324  break;
325  }
326  }
327 
328  // Insert the printf_alloc call
329  Builder.SetInsertPoint(CI);
330  Builder.SetCurrentDebugLocation(CI->getDebugLoc());
331 
333  Attribute::NoUnwind);
334 
335  Type *SizetTy = Type::getInt32Ty(Ctx);
336 
337  Type *Tys_alloc[1] = {SizetTy};
338  Type *I8Ptr = PointerType::get(Type::getInt8Ty(Ctx), 1);
339  FunctionType *FTy_alloc = FunctionType::get(I8Ptr, Tys_alloc, false);
340  FunctionCallee PrintfAllocFn =
341  M.getOrInsertFunction(StringRef("__printf_alloc"), FTy_alloc, Attr);
342 
343  LLVM_DEBUG(dbgs() << "Printf metadata = " << Sizes.str() << '\n');
344  std::string fmtstr = itostr(++UniqID) + ":" + Sizes.str().c_str();
345  MDString *fmtStrArray = MDString::get(Ctx, fmtstr);
346 
347  // Instead of creating global variables, the
348  // printf format strings are extracted
349  // and passed as metadata. This avoids
350  // polluting llvm's symbol tables in this module.
351  // Metadata is going to be extracted
352  // by the backend passes and inserted
353  // into the OpenCL binary as appropriate.
354  StringRef amd("llvm.printf.fmts");
355  NamedMDNode *metaD = M.getOrInsertNamedMetadata(amd);
356  MDNode *myMD = MDNode::get(Ctx, fmtStrArray);
357  metaD->addOperand(myMD);
358  Value *sumC = ConstantInt::get(SizetTy, Sum, false);
359  SmallVector<Value *, 1> alloc_args;
360  alloc_args.push_back(sumC);
361  CallInst *pcall =
362  CallInst::Create(PrintfAllocFn, alloc_args, "printf_alloc_fn", CI);
363 
364  //
365  // Insert code to split basicblock with a
366  // piece of hammock code.
367  // basicblock splits after buffer overflow check
368  //
369  ConstantPointerNull *zeroIntPtr =
371  ICmpInst *cmp =
372  dyn_cast<ICmpInst>(Builder.CreateICmpNE(pcall, zeroIntPtr, ""));
373  if (!CI->use_empty()) {
374  Value *result =
375  Builder.CreateSExt(Builder.CreateNot(cmp), I32Ty, "printf_res");
376  CI->replaceAllUsesWith(result);
377  }
378  SplitBlock(CI->getParent(), cmp);
379  Instruction *Brnch =
380  SplitBlockAndInsertIfThen(cmp, cmp->getNextNode(), false);
381 
382  Builder.SetInsertPoint(Brnch);
383 
384  // store unique printf id in the buffer
385  //
386  SmallVector<Value *, 1> ZeroIdxList;
387  ConstantInt *zeroInt =
388  ConstantInt::get(Ctx, APInt(32, StringRef("0"), 10));
389  ZeroIdxList.push_back(zeroInt);
390 
391  GetElementPtrInst *BufferIdx =
393  nullptr, pcall, ZeroIdxList, "PrintBuffID", Brnch));
394 
395  Type *idPointer = PointerType::get(I32Ty, AMDGPUAS::GLOBAL_ADDRESS);
396  Value *id_gep_cast =
397  new BitCastInst(BufferIdx, idPointer, "PrintBuffIdCast", Brnch);
398 
399  StoreInst *stbuff =
400  new StoreInst(ConstantInt::get(I32Ty, UniqID), id_gep_cast);
401  stbuff->insertBefore(Brnch); // to Remove unused variable warning
402 
403  SmallVector<Value *, 2> FourthIdxList;
404  ConstantInt *fourInt =
405  ConstantInt::get(Ctx, APInt(32, StringRef("4"), 10));
406 
407  FourthIdxList.push_back(fourInt); // 1st 4 bytes hold the printf_id
408  // the following GEP is the buffer pointer
409  BufferIdx = cast<GetElementPtrInst>(GetElementPtrInst::Create(
410  nullptr, pcall, FourthIdxList, "PrintBuffGep", Brnch));
411 
412  Type *Int32Ty = Type::getInt32Ty(Ctx);
413  Type *Int64Ty = Type::getInt64Ty(Ctx);
414  for (unsigned ArgCount = 1; ArgCount < CI->getNumArgOperands() &&
415  ArgCount <= OpConvSpecifiers.size();
416  ArgCount++) {
417  Value *Arg = CI->getArgOperand(ArgCount);
418  Type *ArgType = Arg->getType();
419  SmallVector<Value *, 32> WhatToStore;
420  if (ArgType->isFPOrFPVectorTy() &&
421  (ArgType->getTypeID() != Type::VectorTyID)) {
422  Type *IType = (ArgType->isFloatTy()) ? Int32Ty : Int64Ty;
423  if (OpConvSpecifiers[ArgCount - 1] == 'f') {
424  ConstantFP *fpCons = dyn_cast<ConstantFP>(Arg);
425  if (fpCons) {
426  APFloat Val(fpCons->getValueAPF());
427  bool Lost = false;
429  &Lost);
430  Arg = ConstantFP::get(Ctx, Val);
431  IType = Int32Ty;
432  } else {
433  FPExtInst *FpExt = dyn_cast<FPExtInst>(Arg);
434  if (FpExt && FpExt->getType()->isDoubleTy() &&
435  FpExt->getOperand(0)->getType()->isFloatTy()) {
436  Arg = FpExt->getOperand(0);
437  IType = Int32Ty;
438  }
439  }
440  }
441  Arg = new BitCastInst(Arg, IType, "PrintArgFP", Brnch);
442  WhatToStore.push_back(Arg);
443  } else if (ArgType->getTypeID() == Type::PointerTyID) {
444  if (shouldPrintAsStr(OpConvSpecifiers[ArgCount - 1], ArgType)) {
445  const char *S = NonLiteralStr;
446  if (ConstantExpr *ConstExpr = dyn_cast<ConstantExpr>(Arg)) {
447  GlobalVariable *GV =
448  dyn_cast<GlobalVariable>(ConstExpr->getOperand(0));
449  if (GV && GV->hasInitializer()) {
450  Constant *Init = GV->getInitializer();
452  if (Init->isZeroValue() || CA->isString()) {
453  S = Init->isZeroValue() ? "" : CA->getAsCString().data();
454  }
455  }
456  }
457  size_t SizeStr = strlen(S) + 1;
458  size_t Rem = SizeStr % DWORD_ALIGN;
459  size_t NSizeStr = 0;
460  if (Rem) {
461  NSizeStr = SizeStr + (DWORD_ALIGN - Rem);
462  } else {
463  NSizeStr = SizeStr;
464  }
465  if (S[0]) {
466  char *MyNewStr = new char[NSizeStr]();
467  strcpy(MyNewStr, S);
468  int NumInts = NSizeStr / 4;
469  int CharC = 0;
470  while (NumInts) {
471  int ANum = *(int *)(MyNewStr + CharC);
472  CharC += 4;
473  NumInts--;
474  Value *ANumV = ConstantInt::get(Int32Ty, ANum, false);
475  WhatToStore.push_back(ANumV);
476  }
477  delete[] MyNewStr;
478  } else {
479  // Empty string, give a hint to RT it is no NULL
480  Value *ANumV = ConstantInt::get(Int32Ty, 0xFFFFFF00, false);
481  WhatToStore.push_back(ANumV);
482  }
483  } else {
484  uint64_t Size = TD->getTypeAllocSizeInBits(ArgType);
485  assert((Size == 32 || Size == 64) && "unsupported size");
486  Type *DstType = (Size == 32) ? Int32Ty : Int64Ty;
487  Arg = new PtrToIntInst(Arg, DstType, "PrintArgPtr", Brnch);
488  WhatToStore.push_back(Arg);
489  }
490  } else if (ArgType->getTypeID() == Type::VectorTyID) {
491  Type *IType = NULL;
492  uint32_t EleCount = cast<VectorType>(ArgType)->getNumElements();
493  uint32_t EleSize = ArgType->getScalarSizeInBits();
494  uint32_t TotalSize = EleCount * EleSize;
495  if (EleCount == 3) {
496  IntegerType *Int32Ty = Type::getInt32Ty(ArgType->getContext());
497  Constant *Indices[4] = {
498  ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, 1),
499  ConstantInt::get(Int32Ty, 2), ConstantInt::get(Int32Ty, 2)};
500  Constant *Mask = ConstantVector::get(Indices);
501  ShuffleVectorInst *Shuffle = new ShuffleVectorInst(Arg, Arg, Mask);
502  Shuffle->insertBefore(Brnch);
503  Arg = Shuffle;
504  ArgType = Arg->getType();
505  TotalSize += EleSize;
506  }
507  switch (EleSize) {
508  default:
509  EleCount = TotalSize / 64;
510  IType = dyn_cast<Type>(Type::getInt64Ty(ArgType->getContext()));
511  break;
512  case 8:
513  if (EleCount >= 8) {
514  EleCount = TotalSize / 64;
515  IType = dyn_cast<Type>(Type::getInt64Ty(ArgType->getContext()));
516  } else if (EleCount >= 3) {
517  EleCount = 1;
518  IType = dyn_cast<Type>(Type::getInt32Ty(ArgType->getContext()));
519  } else {
520  EleCount = 1;
521  IType = dyn_cast<Type>(Type::getInt16Ty(ArgType->getContext()));
522  }
523  break;
524  case 16:
525  if (EleCount >= 3) {
526  EleCount = TotalSize / 64;
527  IType = dyn_cast<Type>(Type::getInt64Ty(ArgType->getContext()));
528  } else {
529  EleCount = 1;
530  IType = dyn_cast<Type>(Type::getInt32Ty(ArgType->getContext()));
531  }
532  break;
533  }
534  if (EleCount > 1) {
535  IType = dyn_cast<Type>(VectorType::get(IType, EleCount));
536  }
537  Arg = new BitCastInst(Arg, IType, "PrintArgVect", Brnch);
538  WhatToStore.push_back(Arg);
539  } else {
540  WhatToStore.push_back(Arg);
541  }
542  for (unsigned I = 0, E = WhatToStore.size(); I != E; ++I) {
543  Value *TheBtCast = WhatToStore[I];
544  unsigned ArgSize =
545  TD->getTypeAllocSizeInBits(TheBtCast->getType()) / 8;
546  SmallVector<Value *, 1> BuffOffset;
547  BuffOffset.push_back(ConstantInt::get(I32Ty, ArgSize));
548 
549  Type *ArgPointer = PointerType::get(TheBtCast->getType(), 1);
550  Value *CastedGEP =
551  new BitCastInst(BufferIdx, ArgPointer, "PrintBuffPtrCast", Brnch);
552  StoreInst *StBuff = new StoreInst(TheBtCast, CastedGEP, Brnch);
553  LLVM_DEBUG(dbgs() << "inserting store to printf buffer:\n"
554  << *StBuff << '\n');
555  (void)StBuff;
556  if (I + 1 == E && ArgCount + 1 == CI->getNumArgOperands())
557  break;
559  nullptr, BufferIdx, BuffOffset, "PrintBuffNextPtr", Brnch));
560  LLVM_DEBUG(dbgs() << "inserting gep to the printf buffer:\n"
561  << *BufferIdx << '\n');
562  }
563  }
564  }
565  }
566 
567  // erase the printf calls
568  for (auto P : Printfs) {
569  CallInst *CI = dyn_cast<CallInst>(P);
570  CI->eraseFromParent();
571  }
572 
573  Printfs.clear();
574  return true;
575 }
576 
577 bool AMDGPUPrintfRuntimeBinding::runOnModule(Module &M) {
579  if (TT.getArch() == Triple::r600)
580  return false;
581 
582  visit(M);
583 
584  if (Printfs.empty())
585  return false;
586 
587  TD = &M.getDataLayout();
588  auto DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
589  DT = DTWP ? &DTWP->getDomTree() : nullptr;
590  auto GetTLI = [this](Function &F) -> TargetLibraryInfo & {
591  return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
592  };
593 
594  return lowerPrintfForGpu(M, GetTLI);
595 }
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks &#39;this&#39; from the containing basic block and deletes it.
Definition: Instruction.cpp:67
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:111
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
Definition: Module.h:240
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Base class for instruction visitors.
Definition: InstVisitor.h:80
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2106
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition: ilist_node.h:288
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
static MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:453
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
void push_back(const T &Elt)
Definition: SmallVector.h:211
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value *> IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Definition: Instructions.h:901
void addOperand(MDNode *M)
Definition: Metadata.cpp:1086
This class represents a function call, abstracting a target machine&#39;s calling convention.
StringRef getAsCString() const
If this array is isCString(), then this method returns the array (without the trailing null byte) as ...
Definition: Constants.h:662
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space...
Definition: Type.cpp:632
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:104
This instruction constructs a fixed permutation of two input vectors.
NamedMDNode * getOrInsertNamedMetadata(StringRef Name)
Return the named MDNode in the module with the specified name.
Definition: Module.cpp:259
LLVM_NODISCARD size_t find_last_of(char C, size_t From=npos) const
Find the last character in the string that is C, or npos if not found.
Definition: StringRef.h:420
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1882
Metadata node.
Definition: Metadata.h:863
F(f)
FunTy * getCalledFunction() const
Return the function being called if this is a direct call, otherwise return null (if it&#39;s an indirect...
Definition: CallSite.h:111
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:176
15: Pointers
Definition: Type.h:74
BasicBlock * SplitBlock(BasicBlock *Old, Instruction *SplitPt, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction - everything before SplitPt stays in Old and e...
static IntegerType * getInt16Ty(LLVMContext &C)
Definition: Type.cpp:174
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Type.h:129
Value * CreateNot(Value *V, const Twine &Name="")
Definition: IRBuilder.h:1524
amdgpu printf runtime binding
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1241
ModulePass * createAMDGPUPrintfRuntimeBinding()
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:50
A tuple of MDNodes.
Definition: Metadata.h:1325
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:369
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:137
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:244
constexpr char Printf[]
Key for HSA::Metadata::mPrintf.
A Use represents the edge between a Value definition and its users.
Definition: Use.h:55
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:779
Address space for global memory (RAT0, VTX0).
Definition: AMDGPU.h:270
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:592
uint64_t getNumElements() const
For scalable vectors, this will return the minimum number of elements in the vector.
Definition: DerivedTypes.h:393
This class represents a cast from a pointer to an integer.
InstrTy * getInstruction() const
Definition: CallSite.h:96
Class to represent function types.
Definition: DerivedTypes.h:103
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:888
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:245
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Definition: APFloat.cpp:4483
std::string itostr(int64_t X)
Definition: StringExtras.h:238
This class represents a no-op cast from one type to another.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:25
An instruction for storing to memory.
Definition: Instructions.h:320
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
Definition: IRBuilder.h:156
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:429
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1878
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
Definition: DerivedTypes.h:66
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Definition: Dominators.h:144
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
Definition: IRBuilder.h:132
Value * getOperand(unsigned i) const
Definition: User.h:169
#define DWORD_ALIGN
Class to represent pointers.
Definition: DerivedTypes.h:544
bool isZeroValue() const
Return true if the value is negative zero or null value.
Definition: Constants.cpp:65
11: Arbitrary bit width integers
Definition: Type.h:70
bool isFloatTy() const
Return true if this is &#39;float&#39;, a 32-bit IEEE fp type.
Definition: Type.h:146
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
Definition: Instructions.h:875
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
Definition: Metadata.h:1165
#define P(N)
char & AMDGPUPrintfRuntimeBindingID
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
Definition: Constants.cpp:1432
An array constant whose element type is a simple 1/2/4/8-byte integer or float/double, and whose elements are just simple data values (i.e.
Definition: Constants.h:689
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction...
Definition: Instruction.cpp:73
bool hasName() const
Definition: Value.h:251
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:64
INITIALIZE_PASS_BEGIN(AMDGPUPrintfRuntimeBinding, "amdgpu-printf-runtime-binding", "AMDGPU Printf lowering", false, false) INITIALIZE_PASS_END(AMDGPUPrintfRuntimeBinding
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
Definition: Constant.h:41
void initializeAMDGPUPrintfRuntimeBindingPass(PassRegistry &)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:263
Represent the analysis usage information of a pass.
This instruction compares its operands according to the predicate given to the constructor.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:296
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Definition: DerivedTypes.h:572
#define LLVM_LIBRARY_VISIBILITY
LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked into a shared library...
Definition: Compiler.h:124
Class to represent integer types.
Definition: DerivedTypes.h:40
size_t size() const
Definition: SmallVector.h:52
std::string & str()
Flushes the stream contents to the target string and returns the string&#39;s reference.
Definition: raw_ostream.h:519
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
const APFloat & getValueAPF() const
Definition: Constants.h:302
static const fltSemantics & IEEEsingle() LLVM_READNONE
Definition: APFloat.cpp:155
hexagon bit simplify
This is the shared class of boolean and integer constants.
Definition: Constants.h:83
16: SIMD &#39;packed&#39; format, or other vector type
Definition: Type.h:75
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type...
Definition: Type.cpp:129
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
Module.h This file contains the declarations for the Module class.
Provides information about what library functions are available for the current target.
A constant pointer value that points to null.
Definition: Constants.h:538
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:653
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
Definition: Module.cpp:143
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
Definition: Constants.cpp:716
void setOperand(unsigned i, Value *Val)
Definition: User.h:174
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
Class to represent vector types.
Definition: DerivedTypes.h:427
Class for arbitrary precision integers.
Definition: APInt.h:69
iterator_range< user_iterator > users()
Definition: Value.h:419
Address space for constant memory (VTX2).
Definition: AMDGPU.h:273
unsigned getNumArgOperands() const
Definition: InstrTypes.h:1239
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:331
static const size_t npos
Definition: StringRef.h:50
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:175
void clear()
Definition: ilist.h:307
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Definition: Type.cpp:609
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:214
LLVM_NODISCARD size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
Definition: StringRef.h:394
#define I(x, y, z)
Definition: MD5.cpp:58
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:224
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:332
uint32_t Size
Definition: Profile.cpp:46
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition: Type.h:184
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:136
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:503
LLVM Value Representation.
Definition: Value.h:73
bool hasInitializer() const
Definitions have initializers, declarations don&#39;t.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:80
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
A single uniqued string.
Definition: Metadata.h:603
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:259
#define LLVM_DEBUG(X)
Definition: Debug.h:122
This class represents an extension of floating point types.
amdgpu printf runtime AMDGPU Printf lowering
bool isDoubleTy() const
Return true if this is &#39;double&#39;, a 64-bit IEEE fp type.
Definition: Type.h:149
Value * SimplifyInstruction(Instruction *I, const SimplifyQuery &Q, OptimizationRemarkEmitter *ORE=nullptr)
See if we can compute a simplified version of this instruction.
static IntegerType * getInt8Ty(LLVMContext &C)
Definition: Type.cpp:173
bool use_empty() const
Definition: Value.h:342
static Constant * get(ArrayRef< Constant *> V)
Definition: Constants.cpp:1110
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute >> Attrs)
Create an AttributeList with the specified parameters in it.
Definition: Attributes.cpp:973
IntegerType * Int32Ty
Type * getContainedType(unsigned i) const
This method is used to implement the type iterator (defined at the end of the file).
Definition: Type.h:332
const BasicBlock * getParent() const
Definition: Instruction.h:66
bool isString(unsigned CharSize=8) const
This method returns true if this is an array of CharSize integers.
Definition: Constants.cpp:2781