LLVM 18.0.0git
AMDGPUEmitPrintf.cpp
Go to the documentation of this file.
1//===- AMDGPUEmitPrintf.cpp -----------------------------------------------===//
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// Utility function to lower a printf call into a series of device
10// library calls on the AMDGPU target.
11//
12// WARNING: This file knows about certain library functions. It recognizes them
13// by name, and hardwires knowledge of their semantics.
14//
15//===----------------------------------------------------------------------===//
16
22#include "llvm/Support/MD5.h"
24
25using namespace llvm;
26
27#define DEBUG_TYPE "amdgpu-emit-printf"
28
29static Value *fitArgInto64Bits(IRBuilder<> &Builder, Value *Arg) {
30 auto Int64Ty = Builder.getInt64Ty();
31 auto Ty = Arg->getType();
32
33 if (auto IntTy = dyn_cast<IntegerType>(Ty)) {
34 switch (IntTy->getBitWidth()) {
35 case 32:
36 return Builder.CreateZExt(Arg, Int64Ty);
37 case 64:
38 return Arg;
39 }
40 }
41
42 if (Ty->getTypeID() == Type::DoubleTyID) {
43 return Builder.CreateBitCast(Arg, Int64Ty);
44 }
45
46 if (isa<PointerType>(Ty)) {
47 return Builder.CreatePtrToInt(Arg, Int64Ty);
48 }
49
50 llvm_unreachable("unexpected type");
51}
52
53static Value *callPrintfBegin(IRBuilder<> &Builder, Value *Version) {
54 auto Int64Ty = Builder.getInt64Ty();
55 auto M = Builder.GetInsertBlock()->getModule();
56 auto Fn = M->getOrInsertFunction("__ockl_printf_begin", Int64Ty, Int64Ty);
57 return Builder.CreateCall(Fn, Version);
58}
59
60static Value *callAppendArgs(IRBuilder<> &Builder, Value *Desc, int NumArgs,
61 Value *Arg0, Value *Arg1, Value *Arg2, Value *Arg3,
62 Value *Arg4, Value *Arg5, Value *Arg6,
63 bool IsLast) {
64 auto Int64Ty = Builder.getInt64Ty();
65 auto Int32Ty = Builder.getInt32Ty();
66 auto M = Builder.GetInsertBlock()->getModule();
67 auto Fn = M->getOrInsertFunction("__ockl_printf_append_args", Int64Ty,
68 Int64Ty, Int32Ty, Int64Ty, Int64Ty, Int64Ty,
69 Int64Ty, Int64Ty, Int64Ty, Int64Ty, Int32Ty);
70 auto IsLastValue = Builder.getInt32(IsLast);
71 auto NumArgsValue = Builder.getInt32(NumArgs);
72 return Builder.CreateCall(Fn, {Desc, NumArgsValue, Arg0, Arg1, Arg2, Arg3,
73 Arg4, Arg5, Arg6, IsLastValue});
74}
75
76static Value *appendArg(IRBuilder<> &Builder, Value *Desc, Value *Arg,
77 bool IsLast) {
78 auto Arg0 = fitArgInto64Bits(Builder, Arg);
79 auto Zero = Builder.getInt64(0);
80 return callAppendArgs(Builder, Desc, 1, Arg0, Zero, Zero, Zero, Zero, Zero,
81 Zero, IsLast);
82}
83
84// The device library does not provide strlen, so we build our own loop
85// here. While we are at it, we also include the terminating null in the length.
86static Value *getStrlenWithNull(IRBuilder<> &Builder, Value *Str) {
87 auto *Prev = Builder.GetInsertBlock();
88 Module *M = Prev->getModule();
89
90 auto CharZero = Builder.getInt8(0);
91 auto One = Builder.getInt64(1);
92 auto Zero = Builder.getInt64(0);
93 auto Int64Ty = Builder.getInt64Ty();
94
95 // The length is either zero for a null pointer, or the computed value for an
96 // actual string. We need a join block for a phi that represents the final
97 // value.
98 //
99 // Strictly speaking, the zero does not matter since
100 // __ockl_printf_append_string_n ignores the length if the pointer is null.
101 BasicBlock *Join = nullptr;
102 if (Prev->getTerminator()) {
103 Join = Prev->splitBasicBlock(Builder.GetInsertPoint(),
104 "strlen.join");
106 } else {
107 Join = BasicBlock::Create(M->getContext(), "strlen.join",
108 Prev->getParent());
109 }
110 BasicBlock *While =
111 BasicBlock::Create(M->getContext(), "strlen.while",
112 Prev->getParent(), Join);
113 BasicBlock *WhileDone = BasicBlock::Create(
114 M->getContext(), "strlen.while.done",
115 Prev->getParent(), Join);
116
117 // Emit an early return for when the pointer is null.
118 Builder.SetInsertPoint(Prev);
119 auto CmpNull =
120 Builder.CreateICmpEQ(Str, Constant::getNullValue(Str->getType()));
121 BranchInst::Create(Join, While, CmpNull, Prev);
122
123 // Entry to the while loop.
124 Builder.SetInsertPoint(While);
125
126 auto PtrPhi = Builder.CreatePHI(Str->getType(), 2);
127 PtrPhi->addIncoming(Str, Prev);
128 auto PtrNext = Builder.CreateGEP(Builder.getInt8Ty(), PtrPhi, One);
129 PtrPhi->addIncoming(PtrNext, While);
130
131 // Condition for the while loop.
132 auto Data = Builder.CreateLoad(Builder.getInt8Ty(), PtrPhi);
133 auto Cmp = Builder.CreateICmpEQ(Data, CharZero);
134 Builder.CreateCondBr(Cmp, WhileDone, While);
135
136 // Add one to the computed length.
137 Builder.SetInsertPoint(WhileDone, WhileDone->begin());
138 auto Begin = Builder.CreatePtrToInt(Str, Int64Ty);
139 auto End = Builder.CreatePtrToInt(PtrPhi, Int64Ty);
140 auto Len = Builder.CreateSub(End, Begin);
141 Len = Builder.CreateAdd(Len, One);
142
143 // Final join.
144 BranchInst::Create(Join, WhileDone);
145 Builder.SetInsertPoint(Join, Join->begin());
146 auto LenPhi = Builder.CreatePHI(Len->getType(), 2);
147 LenPhi->addIncoming(Len, WhileDone);
148 LenPhi->addIncoming(Zero, Prev);
149
150 return LenPhi;
151}
152
154 Value *Length, bool isLast) {
155 auto Int64Ty = Builder.getInt64Ty();
156 auto CharPtrTy = Builder.getInt8PtrTy();
157 auto Int32Ty = Builder.getInt32Ty();
158 auto M = Builder.GetInsertBlock()->getModule();
159 auto Fn = M->getOrInsertFunction("__ockl_printf_append_string_n", Int64Ty,
160 Int64Ty, CharPtrTy, Int64Ty, Int32Ty);
161 auto IsLastInt32 = Builder.getInt32(isLast);
162 return Builder.CreateCall(Fn, {Desc, Str, Length, IsLastInt32});
163}
164
165static Value *appendString(IRBuilder<> &Builder, Value *Desc, Value *Arg,
166 bool IsLast) {
167 Arg = Builder.CreateBitCast(
168 Arg, Builder.getInt8PtrTy(Arg->getType()->getPointerAddressSpace()));
169 auto Length = getStrlenWithNull(Builder, Arg);
170 return callAppendStringN(Builder, Desc, Arg, Length, IsLast);
171}
172
173static Value *processArg(IRBuilder<> &Builder, Value *Desc, Value *Arg,
174 bool SpecIsCString, bool IsLast) {
175 if (SpecIsCString && isa<PointerType>(Arg->getType())) {
176 return appendString(Builder, Desc, Arg, IsLast);
177 }
178 // If the format specifies a string but the argument is not, the frontend will
179 // have printed a warning. We just rely on undefined behaviour and send the
180 // argument anyway.
181 return appendArg(Builder, Desc, Arg, IsLast);
182}
183
184// Scan the format string to locate all specifiers, and mark the ones that
185// specify a string, i.e, the "%s" specifier with optional '*' characters.
187 static const char ConvSpecifiers[] = "diouxXfFeEgGaAcspn";
188 size_t SpecPos = 0;
189 // Skip the first argument, the format string.
190 unsigned ArgIdx = 1;
191
192 while ((SpecPos = Str.find_first_of('%', SpecPos)) != StringRef::npos) {
193 if (Str[SpecPos + 1] == '%') {
194 SpecPos += 2;
195 continue;
196 }
197 auto SpecEnd = Str.find_first_of(ConvSpecifiers, SpecPos);
198 if (SpecEnd == StringRef::npos)
199 return;
200 auto Spec = Str.slice(SpecPos, SpecEnd + 1);
201 ArgIdx += Spec.count('*');
202 if (Str[SpecEnd] == 's') {
203 BV.set(ArgIdx);
204 }
205 SpecPos = SpecEnd + 1;
206 ++ArgIdx;
207 }
208}
209
210// helper struct to package the string related data
213 Value *RealSize = nullptr;
214 Value *AlignedSize = nullptr;
215 bool IsConst = true;
216
217 StringData(StringRef ST, Value *RS, Value *AS, bool IC)
218 : Str(ST), RealSize(RS), AlignedSize(AS), IsConst(IC) {}
219};
220
221// Calculates frame size required for current printf expansion and allocates
222// space on printf buffer. Printf frame includes following contents
223// [ ControlDWord , format string/Hash , Arguments (each aligned to 8 byte) ]
225 IRBuilder<> &Builder, ArrayRef<Value *> Args, Value *Fmt,
226 bool isConstFmtStr, SparseBitVector<8> &SpecIsCString,
227 SmallVectorImpl<StringData> &StringContents, Value *&ArgSize) {
228 Module *M = Builder.GetInsertBlock()->getModule();
229 Value *NonConstStrLen = nullptr;
230 Value *LenWithNull = nullptr;
231 Value *LenWithNullAligned = nullptr;
232 Value *TempAdd = nullptr;
233
234 // First 4 bytes to be reserved for control dword
235 size_t BufSize = 4;
236 if (isConstFmtStr)
237 // First 8 bytes of MD5 hash
238 BufSize += 8;
239 else {
240 LenWithNull = getStrlenWithNull(Builder, Fmt);
241
242 // Align the computed length to next 8 byte boundary
243 TempAdd = Builder.CreateAdd(LenWithNull,
244 ConstantInt::get(LenWithNull->getType(), 7U));
245 NonConstStrLen = Builder.CreateAnd(
246 TempAdd, ConstantInt::get(LenWithNull->getType(), ~7U));
247
248 StringContents.push_back(
249 StringData(StringRef(), LenWithNull, NonConstStrLen, false));
250 }
251
252 for (size_t i = 1; i < Args.size(); i++) {
253 if (SpecIsCString.test(i)) {
254 StringRef ArgStr;
255 if (getConstantStringInfo(Args[i], ArgStr)) {
256 auto alignedLen = alignTo(ArgStr.size() + 1, 8);
257 StringContents.push_back(StringData(
258 ArgStr,
259 /*RealSize*/ nullptr, /*AlignedSize*/ nullptr, /*IsConst*/ true));
260 BufSize += alignedLen;
261 } else {
262 LenWithNull = getStrlenWithNull(Builder, Args[i]);
263
264 // Align the computed length to next 8 byte boundary
265 TempAdd = Builder.CreateAdd(
266 LenWithNull, ConstantInt::get(LenWithNull->getType(), 7U));
267 LenWithNullAligned = Builder.CreateAnd(
268 TempAdd, ConstantInt::get(LenWithNull->getType(), ~7U));
269
270 if (NonConstStrLen) {
271 auto Val = Builder.CreateAdd(LenWithNullAligned, NonConstStrLen,
272 "cumulativeAdd");
273 NonConstStrLen = Val;
274 } else
275 NonConstStrLen = LenWithNullAligned;
276
277 StringContents.push_back(
278 StringData(StringRef(), LenWithNull, LenWithNullAligned, false));
279 }
280 } else {
281 int AllocSize = M->getDataLayout().getTypeAllocSize(Args[i]->getType());
282 // We end up expanding non string arguments to 8 bytes
283 // (args smaller than 8 bytes)
284 BufSize += std::max(AllocSize, 8);
285 }
286 }
287
288 // calculate final size value to be passed to printf_alloc
289 Value *SizeToReserve = ConstantInt::get(Builder.getInt64Ty(), BufSize, false);
290 SmallVector<Value *, 1> Alloc_args;
291 if (NonConstStrLen)
292 SizeToReserve = Builder.CreateAdd(NonConstStrLen, SizeToReserve);
293
294 ArgSize = Builder.CreateTrunc(SizeToReserve, Builder.getInt32Ty());
295 Alloc_args.push_back(ArgSize);
296
297 // call the printf_alloc function
299 Builder.getContext(), AttributeList::FunctionIndex, Attribute::NoUnwind);
300
301 Type *Tys_alloc[1] = {Builder.getInt32Ty()};
302 Type *I8Ptr =
303 Builder.getInt8PtrTy(M->getDataLayout().getDefaultGlobalsAddressSpace());
304 FunctionType *FTy_alloc = FunctionType::get(I8Ptr, Tys_alloc, false);
305 auto PrintfAllocFn =
306 M->getOrInsertFunction(StringRef("__printf_alloc"), FTy_alloc, Attr);
307
308 return Builder.CreateCall(PrintfAllocFn, Alloc_args, "printf_alloc_fn");
309}
310
311// Prepare constant string argument to push onto the buffer
313 SmallVectorImpl<Value *> &WhatToStore) {
314 std::string Str(SD->Str.str() + '\0');
315
316 DataExtractor Extractor(Str, /*IsLittleEndian=*/true, 8);
318 while (Offset && Offset.tell() < Str.size()) {
319 const uint64_t ReadSize = 4;
320 uint64_t ReadNow = std::min(ReadSize, Str.size() - Offset.tell());
321 uint64_t ReadBytes = 0;
322 switch (ReadNow) {
323 default:
324 llvm_unreachable("min(4, X) > 4?");
325 case 1:
326 ReadBytes = Extractor.getU8(Offset);
327 break;
328 case 2:
329 ReadBytes = Extractor.getU16(Offset);
330 break;
331 case 3:
332 ReadBytes = Extractor.getU24(Offset);
333 break;
334 case 4:
335 ReadBytes = Extractor.getU32(Offset);
336 break;
337 }
338 cantFail(Offset.takeError(), "failed to read bytes from constant array");
339
340 APInt IntVal(8 * ReadSize, ReadBytes);
341
342 // TODO: Should not bother aligning up.
343 if (ReadNow < ReadSize)
344 IntVal = IntVal.zext(8 * ReadSize);
345
346 Type *IntTy = Type::getIntNTy(Builder.getContext(), IntVal.getBitWidth());
347 WhatToStore.push_back(ConstantInt::get(IntTy, IntVal));
348 }
349 // Additional padding for 8 byte alignment
350 int Rem = (Str.size() % 8);
351 if (Rem > 0 && Rem <= 4)
352 WhatToStore.push_back(ConstantInt::get(Builder.getInt32Ty(), 0));
353}
354
356 const DataLayout &DL = Builder.GetInsertBlock()->getModule()->getDataLayout();
357 auto Ty = Arg->getType();
358
359 if (auto IntTy = dyn_cast<IntegerType>(Ty)) {
360 if (IntTy->getBitWidth() < 64) {
361 return Builder.CreateZExt(Arg, Builder.getInt64Ty());
362 }
363 }
364
365 if (Ty->isFloatingPointTy()) {
366 if (DL.getTypeAllocSize(Ty) < 8) {
367 return Builder.CreateFPExt(Arg, Builder.getDoubleTy());
368 }
369 }
370
371 return Arg;
372}
373
374static void
376 Value *PtrToStore, SparseBitVector<8> &SpecIsCString,
377 SmallVectorImpl<StringData> &StringContents,
378 bool IsConstFmtStr) {
379 Module *M = Builder.GetInsertBlock()->getModule();
380 const DataLayout &DL = M->getDataLayout();
381 auto StrIt = StringContents.begin();
382 size_t i = IsConstFmtStr ? 1 : 0;
383 for (; i < Args.size(); i++) {
384 SmallVector<Value *, 32> WhatToStore;
385 if ((i == 0) || SpecIsCString.test(i)) {
386 if (StrIt->IsConst) {
387 processConstantStringArg(StrIt, Builder, WhatToStore);
388 StrIt++;
389 } else {
390 // This copies the contents of the string, however the next offset
391 // is at aligned length, the extra space that might be created due
392 // to alignment padding is not populated with any specific value
393 // here. This would be safe as long as runtime is sync with
394 // the offsets.
395 Builder.CreateMemCpy(PtrToStore, /*DstAlign*/ Align(1), Args[i],
396 /*SrcAlign*/ Args[i]->getPointerAlignment(DL),
397 StrIt->RealSize);
398
399 PtrToStore =
400 Builder.CreateInBoundsGEP(Builder.getInt8Ty(), PtrToStore,
401 {StrIt->AlignedSize}, "PrintBuffNextPtr");
402 LLVM_DEBUG(dbgs() << "inserting gep to the printf buffer:"
403 << *PtrToStore << '\n');
404
405 // done with current argument, move to next
406 StrIt++;
407 continue;
408 }
409 } else {
410 WhatToStore.push_back(processNonStringArg(Args[i], Builder));
411 }
412
413 for (unsigned I = 0, E = WhatToStore.size(); I != E; ++I) {
414 Value *toStore = WhatToStore[I];
415
416 StoreInst *StBuff = Builder.CreateStore(toStore, PtrToStore);
417 LLVM_DEBUG(dbgs() << "inserting store to printf buffer:" << *StBuff
418 << '\n');
419 (void)StBuff;
420 PtrToStore = Builder.CreateConstInBoundsGEP1_32(
421 Builder.getInt8Ty(), PtrToStore,
422 M->getDataLayout().getTypeAllocSize(toStore->getType()),
423 "PrintBuffNextPtr");
424 LLVM_DEBUG(dbgs() << "inserting gep to the printf buffer:" << *PtrToStore
425 << '\n');
426 }
427 }
428}
429
431 bool IsBuffered) {
432 auto NumOps = Args.size();
433 assert(NumOps >= 1);
434
435 auto Fmt = Args[0];
436 SparseBitVector<8> SpecIsCString;
437 StringRef FmtStr;
438
439 if (getConstantStringInfo(Fmt, FmtStr))
440 locateCStrings(SpecIsCString, FmtStr);
441
442 if (IsBuffered) {
443 SmallVector<StringData, 8> StringContents;
444 Module *M = Builder.GetInsertBlock()->getModule();
445 LLVMContext &Ctx = Builder.getContext();
446 auto Int8Ty = Builder.getInt8Ty();
447 auto Int32Ty = Builder.getInt32Ty();
448 bool IsConstFmtStr = !FmtStr.empty();
449
450 Value *ArgSize = nullptr;
451 Value *Ptr =
452 callBufferedPrintfStart(Builder, Args, Fmt, IsConstFmtStr,
453 SpecIsCString, StringContents, ArgSize);
454
455 // The buffered version still follows OpenCL printf standards for
456 // printf return value, i.e 0 on success, -1 on failure.
457 ConstantPointerNull *zeroIntPtr =
458 ConstantPointerNull::get(cast<PointerType>(Ptr->getType()));
459
460 auto *Cmp = cast<ICmpInst>(Builder.CreateICmpNE(Ptr, zeroIntPtr, ""));
461
462 BasicBlock *End = BasicBlock::Create(Ctx, "end.block",
463 Builder.GetInsertBlock()->getParent());
465 Ctx, "argpush.block", Builder.GetInsertBlock()->getParent());
466
467 BranchInst::Create(ArgPush, End, Cmp, Builder.GetInsertBlock());
468 Builder.SetInsertPoint(ArgPush);
469
470 // Create controlDWord and store as the first entry, format as follows
471 // Bit 0 (LSB) -> stream (1 if stderr, 0 if stdout, printf always outputs to
472 // stdout) Bit 1 -> constant format string (1 if constant) Bits 2-31 -> size
473 // of printf data frame
474 auto ConstantTwo = Builder.getInt32(2);
475 auto ControlDWord = Builder.CreateShl(ArgSize, ConstantTwo);
476 if (IsConstFmtStr)
477 ControlDWord = Builder.CreateOr(ControlDWord, ConstantTwo);
478
479 Builder.CreateStore(ControlDWord, Ptr);
480
481 Ptr = Builder.CreateConstInBoundsGEP1_32(Int8Ty, Ptr, 4);
482
483 // Create MD5 hash for costant format string, push low 64 bits of the
484 // same onto buffer and metadata.
485 NamedMDNode *metaD = M->getOrInsertNamedMetadata("llvm.printf.fmts");
486 if (IsConstFmtStr) {
487 MD5 Hasher;
488 MD5::MD5Result Hash;
489 Hasher.update(FmtStr);
490 Hasher.final(Hash);
491
492 // Try sticking to llvm.printf.fmts format, although we are not going to
493 // use the ID and argument size fields while printing,
494 std::string MetadataStr =
495 "0:0:" + llvm::utohexstr(Hash.low(), /*LowerCase=*/true) + "," +
496 FmtStr.str();
497 MDString *fmtStrArray = MDString::get(Ctx, MetadataStr);
498 MDNode *myMD = MDNode::get(Ctx, fmtStrArray);
499 metaD->addOperand(myMD);
500
501 Builder.CreateStore(Builder.getInt64(Hash.low()), Ptr);
502 Ptr = Builder.CreateConstInBoundsGEP1_32(Int8Ty, Ptr, 8);
503 } else {
504 // Include a dummy metadata instance in case of only non constant
505 // format string usage, This might be an absurd usecase but needs to
506 // be done for completeness
507 if (metaD->getNumOperands() == 0) {
508 MDString *fmtStrArray =
509 MDString::get(Ctx, "0:0:ffffffff,\"Non const format string\"");
510 MDNode *myMD = MDNode::get(Ctx, fmtStrArray);
511 metaD->addOperand(myMD);
512 }
513 }
514
515 // Push The printf arguments onto buffer
516 callBufferedPrintfArgPush(Builder, Args, Ptr, SpecIsCString, StringContents,
517 IsConstFmtStr);
518
519 // End block, returns -1 on failure
520 BranchInst::Create(End, ArgPush);
521 Builder.SetInsertPoint(End);
522 return Builder.CreateSExt(Builder.CreateNot(Cmp), Int32Ty, "printf_result");
523 }
524
525 auto Desc = callPrintfBegin(Builder, Builder.getIntN(64, 0));
526 Desc = appendString(Builder, Desc, Fmt, NumOps == 1);
527
528 // FIXME: This invokes hostcall once for each argument. We can pack up to
529 // seven scalar printf arguments in a single hostcall. See the signature of
530 // callAppendArgs().
531 for (unsigned int i = 1; i != NumOps; ++i) {
532 bool IsLast = i == NumOps - 1;
533 bool IsCString = SpecIsCString.test(i);
534 Desc = processArg(Builder, Desc, Args[i], IsCString, IsLast);
535 }
536
537 return Builder.CreateTrunc(Desc, Builder.getInt32Ty());
538}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static Value * appendString(IRBuilder<> &Builder, Value *Desc, Value *Arg, bool IsLast)
static void callBufferedPrintfArgPush(IRBuilder<> &Builder, ArrayRef< Value * > Args, Value *PtrToStore, SparseBitVector< 8 > &SpecIsCString, SmallVectorImpl< StringData > &StringContents, bool IsConstFmtStr)
static void processConstantStringArg(StringData *SD, IRBuilder<> &Builder, SmallVectorImpl< Value * > &WhatToStore)
static Value * callBufferedPrintfStart(IRBuilder<> &Builder, ArrayRef< Value * > Args, Value *Fmt, bool isConstFmtStr, SparseBitVector< 8 > &SpecIsCString, SmallVectorImpl< StringData > &StringContents, Value *&ArgSize)
static Value * callAppendArgs(IRBuilder<> &Builder, Value *Desc, int NumArgs, Value *Arg0, Value *Arg1, Value *Arg2, Value *Arg3, Value *Arg4, Value *Arg5, Value *Arg6, bool IsLast)
static Value * callPrintfBegin(IRBuilder<> &Builder, Value *Version)
static Value * fitArgInto64Bits(IRBuilder<> &Builder, Value *Arg)
static void locateCStrings(SparseBitVector< 8 > &BV, StringRef Str)
static Value * callAppendStringN(IRBuilder<> &Builder, Value *Desc, Value *Str, Value *Length, bool isLast)
static Value * appendArg(IRBuilder<> &Builder, Value *Desc, Value *Arg, bool IsLast)
static Value * processNonStringArg(Value *Arg, IRBuilder<> &Builder)
static Value * processArg(IRBuilder<> &Builder, Value *Desc, Value *Arg, bool SpecIsCString, bool IsLast)
static Value * getStrlenWithNull(IRBuilder<> &Builder, Value *Str)
assume Assume Builder
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DEBUG(X)
Definition: Debug.h:101
bool End
Definition: ELF_riscv.cpp:469
#define I(x, y, z)
Definition: MD5.cpp:58
IntegerType * Int32Ty
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SparseBitVector class.
This file contains some functions that are useful when dealing with strings.
static SymbolRef::Type getType(const Symbol *Sym)
Definition: TapiFile.cpp:40
Class for arbitrary precision integers.
Definition: APInt.h:76
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
LLVM Basic Block Representation.
Definition: BasicBlock.h:56
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:335
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:105
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
Definition: BasicBlock.cpp:414
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.h:127
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
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:888
A constant pointer value that points to null.
Definition: Constants.h:533
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
Definition: Constants.cpp:1691
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:356
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
Definition: DataExtractor.h:54
uint32_t getU32(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint32_t value from *offset_ptr.
uint8_t getU8(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint8_t value from *offset_ptr.
uint16_t getU16(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint16_t value from *offset_ptr.
uint32_t getU24(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a 24-bit unsigned value from *offset_ptr and return it in a uint32_t.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:110
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2625
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:83
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
Definition: MD5.h:41
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
Definition: MD5.cpp:189
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
Definition: MD5.cpp:234
Metadata node.
Definition: Metadata.h:950
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1416
A single uniqued string.
Definition: Metadata.h:611
static MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:499
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
A tuple of MDNodes.
Definition: Metadata.h:1604
unsigned getNumOperands() const
Definition: Metadata.cpp:1277
void addOperand(MDNode *M)
Definition: Metadata.cpp:1287
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
void set(unsigned Idx)
bool test(unsigned Idx) const
An instruction for storing to memory.
Definition: Instructions.h:301
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:222
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
static constexpr size_t npos
Definition: StringRef.h:52
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
@ DoubleTyID
64-bit floating point type
Definition: Type.h:59
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
@ Length
Definition: DWP.cpp:440
bool getConstantStringInfo(const Value *V, StringRef &Str, bool TrimAtNul=true)
This function computes the length of a null-terminated C string pointed to by V.
Op::Description Desc
Value * emitAMDGPUPrintfCall(IRBuilder<> &Builder, ArrayRef< Value * > Args, bool isBuffered)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:749
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
StringData(StringRef ST, Value *RS, Value *AS, bool IC)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Description of the encoding of one expression Op.
uint64_t low() const
Definition: MD5.h:46