LLVM 24.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
20#include "llvm/IR/Module.h"
23
24using namespace llvm;
25
26#define DEBUG_TYPE "amdgpu-emit-printf"
27
28static Value *fitArgInto64Bits(IRBuilder<> &Builder, Value *Arg) {
29 auto Int64Ty = Builder.getInt64Ty();
30 auto Ty = Arg->getType();
31
32 if (auto IntTy = dyn_cast<IntegerType>(Ty)) {
33 switch (IntTy->getBitWidth()) {
34 case 32:
35 return Builder.CreateZExt(Arg, Int64Ty);
36 case 64:
37 return Arg;
38 }
39 }
40
41 if (Ty->getTypeID() == Type::DoubleTyID) {
42 return Builder.CreateBitCast(Arg, Int64Ty);
43 }
44
45 if (isa<PointerType>(Ty)) {
46 return Builder.CreatePtrToInt(Arg, Int64Ty);
47 }
48
49 llvm_unreachable("unexpected type");
50}
51
52static Value *callPrintfBegin(IRBuilder<> &Builder, Value *Version) {
53 auto Int64Ty = Builder.getInt64Ty();
54 auto M = Builder.getModule();
55 auto Fn = M->getOrInsertFunction("__ockl_printf_begin", Int64Ty, Int64Ty);
56 return Builder.CreateCall(Fn, Version);
57}
58
59static Value *callAppendArgs(IRBuilder<> &Builder, Value *Desc, int NumArgs,
60 Value *Arg0, Value *Arg1, Value *Arg2, Value *Arg3,
61 Value *Arg4, Value *Arg5, Value *Arg6,
62 bool IsLast) {
63 auto Int64Ty = Builder.getInt64Ty();
64 auto Int32Ty = Builder.getInt32Ty();
65 auto M = Builder.getModule();
66 auto Fn = M->getOrInsertFunction("__ockl_printf_append_args", Int64Ty,
67 Int64Ty, Int32Ty, Int64Ty, Int64Ty, Int64Ty,
68 Int64Ty, Int64Ty, Int64Ty, Int64Ty, Int32Ty);
69 auto IsLastValue = Builder.getInt32(IsLast);
70 auto NumArgsValue = Builder.getInt32(NumArgs);
71 return Builder.CreateCall(Fn, {Desc, NumArgsValue, Arg0, Arg1, Arg2, Arg3,
72 Arg4, Arg5, Arg6, IsLastValue});
73}
74
75static Value *appendArg(IRBuilder<> &Builder, Value *Desc, Value *Arg,
76 bool IsLast) {
77 auto Arg0 = fitArgInto64Bits(Builder, Arg);
78 auto Zero = Builder.getInt64(0);
79 return callAppendArgs(Builder, Desc, 1, Arg0, Zero, Zero, Zero, Zero, Zero,
80 Zero, IsLast);
81}
82
83// The device library does not provide strlen, so we build our own loop
84// here. While we are at it, we also include the terminating null in the length.
85static Value *getStrlenWithNull(IRBuilder<> &Builder, Value *Str) {
86 auto *Prev = Builder.GetInsertBlock();
87 Module *M = Prev->getModule();
88
89 auto CharZero = Builder.getInt8(0);
90 auto One = Builder.getInt64(1);
91 auto Zero = Builder.getInt64(0);
92 auto Int64Ty = Builder.getInt64Ty();
93
94 // The length is either zero for a null pointer, or the computed value for an
95 // actual string. We need a join block for a phi that represents the final
96 // value.
97 //
98 // Strictly speaking, the zero does not matter since
99 // __ockl_printf_append_string_n ignores the length if the pointer is null.
100 BasicBlock *Join = nullptr;
101 if (Prev->hasTerminator()) {
102 Join = Prev->splitBasicBlock(Builder.GetInsertPoint(),
103 "strlen.join");
105 } else {
106 Join = BasicBlock::Create(M->getContext(), "strlen.join",
107 Prev->getParent());
108 }
109 BasicBlock *While =
110 BasicBlock::Create(M->getContext(), "strlen.while",
111 Prev->getParent(), Join);
112 BasicBlock *WhileDone = BasicBlock::Create(
113 M->getContext(), "strlen.while.done",
114 Prev->getParent(), Join);
115
116 // Emit an early return for when the pointer is null.
117 Builder.SetInsertPoint(Prev);
118 auto CmpNull =
119 Builder.CreateICmpEQ(Str, Constant::getNullValue(Str->getType()));
120 Builder.CreateCondBr(CmpNull, Join, While);
121
122 // Entry to the while loop.
123 Builder.SetInsertPoint(While);
124
125 auto PtrPhi = Builder.CreatePHI(Str->getType(), 2);
126 PtrPhi->addIncoming(Str, Prev);
127 auto PtrNext = Builder.CreateGEP(Builder.getInt8Ty(), PtrPhi, One);
128 PtrPhi->addIncoming(PtrNext, While);
129
130 // Condition for the while loop.
131 auto Data = Builder.CreateLoad(Builder.getInt8Ty(), PtrPhi);
132 auto Cmp = Builder.CreateICmpEQ(Data, CharZero);
133 Builder.CreateCondBr(Cmp, WhileDone, While);
134
135 // Add one to the computed length.
136 Builder.SetInsertPoint(WhileDone->begin());
137 auto Len = Builder.CreatePtrDiff(PtrPhi, Str);
138 Len = Builder.CreateZExt(Len, Int64Ty);
139 Len = Builder.CreateAdd(Len, One);
140
141 // Final join.
142 UncondBrInst::Create(Join, WhileDone);
143 Builder.SetInsertPoint(Join->begin());
144 auto LenPhi = Builder.CreatePHI(Len->getType(), 2);
145 LenPhi->addIncoming(Len, WhileDone);
146 LenPhi->addIncoming(Zero, Prev);
147
148 return LenPhi;
149}
150
152 Value *Length, bool isLast) {
153 auto Int64Ty = Builder.getInt64Ty();
154 auto IsLastInt32 = Builder.getInt32(isLast);
155 auto M = Builder.getModule();
156 auto Fn = M->getOrInsertFunction("__ockl_printf_append_string_n", Int64Ty,
157 Desc->getType(), Str->getType(),
158 Length->getType(), IsLastInt32->getType());
159 return Builder.CreateCall(Fn, {Desc, Str, Length, IsLastInt32});
160}
161
162static Value *appendString(IRBuilder<> &Builder, Value *Desc, Value *Arg,
163 bool IsLast) {
164 auto Length = getStrlenWithNull(Builder, Arg);
165 return callAppendStringN(Builder, Desc, Arg, Length, IsLast);
166}
167
168static Value *processArg(IRBuilder<> &Builder, Value *Desc, Value *Arg,
169 bool SpecIsCString, bool IsLast) {
170 if (SpecIsCString && isa<PointerType>(Arg->getType())) {
171 return appendString(Builder, Desc, Arg, IsLast);
172 }
173 // If the format specifies a string but the argument is not, the frontend will
174 // have printed a warning. We just rely on undefined behaviour and send the
175 // argument anyway.
176 return appendArg(Builder, Desc, Arg, IsLast);
177}
178
179// helper struct to package the string related data
182 Value *RealSize = nullptr;
183 Value *AlignedSize = nullptr;
184 bool IsConst = true;
185
186 StringData(StringRef ST, Value *RS, Value *AS, bool IC)
187 : Str(ST), RealSize(RS), AlignedSize(AS), IsConst(IC) {}
188};
189
190// Calculates frame size required for current printf expansion and allocates
191// space on printf buffer. Printf frame includes following contents
192// [ ControlDWord , format string/Hash , Arguments (each aligned to 8 byte) ]
194 IRBuilder<> &Builder, ArrayRef<Value *> Args, Value *Fmt,
195 bool isConstFmtStr, SparseBitVector<8> &SpecIsCString,
196 SmallVectorImpl<StringData> &StringContents, Value *&ArgSize) {
197 Module *M = Builder.getModule();
198 Value *NonConstStrLen = nullptr;
199 Value *LenWithNull = nullptr;
200 Value *LenWithNullAligned = nullptr;
201 Value *TempAdd = nullptr;
202
203 // First 4 bytes to be reserved for control dword
204 size_t BufSize = 4;
205 if (isConstFmtStr)
206 // First 8 bytes of MD5 hash
207 BufSize += 8;
208 else {
209 LenWithNull = getStrlenWithNull(Builder, Fmt);
210
211 // Align the computed length to next 8 byte boundary
212 TempAdd = Builder.CreateAdd(LenWithNull,
213 ConstantInt::get(LenWithNull->getType(), 7U));
214 NonConstStrLen = Builder.CreateAnd(
215 TempAdd, ConstantInt::get(LenWithNull->getType(), ~7U));
216
217 StringContents.push_back(
218 StringData(StringRef(), LenWithNull, NonConstStrLen, false));
219 }
220
221 for (size_t i = 1; i < Args.size(); i++) {
222 if (SpecIsCString.test(i)) {
223 StringRef ArgStr;
224 if (getConstantStringInfo(Args[i], ArgStr)) {
225 auto alignedLen = alignTo(ArgStr.size() + 1, 8);
226 StringContents.push_back(StringData(
227 ArgStr,
228 /*RealSize*/ nullptr, /*AlignedSize*/ nullptr, /*IsConst*/ true));
229 BufSize += alignedLen;
230 } else {
231 LenWithNull = getStrlenWithNull(Builder, Args[i]);
232
233 // Align the computed length to next 8 byte boundary
234 TempAdd = Builder.CreateAdd(
235 LenWithNull, ConstantInt::get(LenWithNull->getType(), 7U));
236 LenWithNullAligned = Builder.CreateAnd(
237 TempAdd, ConstantInt::get(LenWithNull->getType(), ~7U));
238
239 if (NonConstStrLen) {
240 auto Val = Builder.CreateAdd(LenWithNullAligned, NonConstStrLen,
241 "cumulativeAdd");
242 NonConstStrLen = Val;
243 } else
244 NonConstStrLen = LenWithNullAligned;
245
246 StringContents.push_back(
247 StringData(StringRef(), LenWithNull, LenWithNullAligned, false));
248 }
249 } else {
250 int AllocSize = M->getDataLayout().getTypeAllocSize(Args[i]->getType());
251 // We end up expanding non string arguments to 8 bytes
252 // (args smaller than 8 bytes)
253 BufSize += std::max(AllocSize, 8);
254 }
255 }
256
257 // calculate final size value to be passed to printf_alloc
258 Value *SizeToReserve = ConstantInt::get(Builder.getInt64Ty(), BufSize, false);
259 SmallVector<Value *, 1> Alloc_args;
260 if (NonConstStrLen)
261 SizeToReserve = Builder.CreateAdd(NonConstStrLen, SizeToReserve);
262
263 ArgSize = Builder.CreateTrunc(SizeToReserve, Builder.getInt32Ty());
264 Alloc_args.push_back(ArgSize);
265
266 // call the printf_alloc function
267 AttributeList Attr = AttributeList::get(
268 Builder.getContext(), AttributeList::FunctionIndex, Attribute::NoUnwind);
269
270 Type *Tys_alloc[1] = {Builder.getInt32Ty()};
271 Type *PtrTy =
272 Builder.getPtrTy(M->getDataLayout().getDefaultGlobalsAddressSpace());
273 FunctionType *FTy_alloc = FunctionType::get(PtrTy, Tys_alloc, false);
274 auto PrintfAllocFn =
275 M->getOrInsertFunction(StringRef("__printf_alloc"), FTy_alloc, Attr);
276
277 return Builder.CreateCall(PrintfAllocFn, Alloc_args, "printf_alloc_fn");
278}
279
280// Prepare constant string argument to push onto the buffer
282 SmallVectorImpl<Value *> &WhatToStore) {
285 for (uint32_t Word : Words)
286 WhatToStore.push_back(Builder.getInt32(Word));
287}
288
290 const DataLayout &DL = Builder.getDataLayout();
291 auto Ty = Arg->getType();
292
293 if (auto IntTy = dyn_cast<IntegerType>(Ty)) {
294 if (IntTy->getBitWidth() < 64) {
295 return Builder.CreateZExt(Arg, Builder.getInt64Ty());
296 }
297 }
298
299 if (Ty->isFloatingPointTy()) {
300 if (DL.getTypeAllocSize(Ty) < 8) {
301 return Builder.CreateFPExt(Arg, Builder.getDoubleTy());
302 }
303 }
304
305 return Arg;
306}
307
308static void
310 Value *PtrToStore, SparseBitVector<8> &SpecIsCString,
311 SmallVectorImpl<StringData> &StringContents,
312 bool IsConstFmtStr) {
313 Module *M = Builder.getModule();
314 const DataLayout &DL = M->getDataLayout();
315 auto StrIt = StringContents.begin();
316 size_t i = IsConstFmtStr ? 1 : 0;
317 for (; i < Args.size(); i++) {
318 SmallVector<Value *, 32> WhatToStore;
319 if ((i == 0) || SpecIsCString.test(i)) {
320 if (StrIt->IsConst) {
321 processConstantStringArg(StrIt, Builder, WhatToStore);
322 StrIt++;
323 } else {
324 // This copies the contents of the string, however the next offset
325 // is at aligned length, the extra space that might be created due
326 // to alignment padding is not populated with any specific value
327 // here. This would be safe as long as runtime is sync with
328 // the offsets.
329 Builder.CreateMemCpy(PtrToStore, /*DstAlign*/ Align(1), Args[i],
330 /*SrcAlign*/ Args[i]->getPointerAlignment(DL),
331 StrIt->RealSize);
332
333 PtrToStore =
334 Builder.CreateInBoundsGEP(Builder.getInt8Ty(), PtrToStore,
335 {StrIt->AlignedSize}, "PrintBuffNextPtr");
336 LLVM_DEBUG(dbgs() << "inserting gep to the printf buffer:"
337 << *PtrToStore << '\n');
338
339 // done with current argument, move to next
340 StrIt++;
341 continue;
342 }
343 } else {
344 WhatToStore.push_back(processNonStringArg(Args[i], Builder));
345 }
346
347 for (Value *toStore : WhatToStore) {
348 StoreInst *StBuff = Builder.CreateStore(toStore, PtrToStore);
349 LLVM_DEBUG(dbgs() << "inserting store to printf buffer:" << *StBuff
350 << '\n');
351 (void)StBuff;
352 PtrToStore = Builder.CreateConstInBoundsGEP1_32(
353 Builder.getInt8Ty(), PtrToStore,
354 M->getDataLayout().getTypeAllocSize(toStore->getType()),
355 "PrintBuffNextPtr");
356 LLVM_DEBUG(dbgs() << "inserting gep to the printf buffer:" << *PtrToStore
357 << '\n');
358 }
359 }
360}
361
363 bool IsBuffered) {
364 auto NumOps = Args.size();
365 assert(NumOps >= 1);
366
367 auto Fmt = Args[0];
368 SparseBitVector<8> SpecIsCString;
369 StringRef FmtStr;
370
371 if (getConstantStringInfo(Fmt, FmtStr))
372 locateAMDGPUPrintfCStrings(SpecIsCString, FmtStr);
373
374 if (IsBuffered) {
375 SmallVector<StringData, 8> StringContents;
376 Module *M = Builder.getModule();
377 LLVMContext &Ctx = Builder.getContext();
378 auto Int8Ty = Builder.getInt8Ty();
379 auto Int32Ty = Builder.getInt32Ty();
380 bool IsConstFmtStr = !FmtStr.empty();
381
382 Value *ArgSize = nullptr;
383 Value *Ptr =
384 callBufferedPrintfStart(Builder, Args, Fmt, IsConstFmtStr,
385 SpecIsCString, StringContents, ArgSize);
386
387 // The buffered version still follows OpenCL printf standards for
388 // printf return value, i.e 0 on success, -1 on failure.
389 ConstantPointerNull *zeroIntPtr =
391
392 auto *Cmp = cast<ICmpInst>(Builder.CreateICmpNE(Ptr, zeroIntPtr, ""));
393
394 BasicBlock *End = BasicBlock::Create(Ctx, "end.block",
395 Builder.GetInsertBlock()->getParent());
397 Ctx, "argpush.block", Builder.GetInsertBlock()->getParent());
398
399 CondBrInst::Create(Cmp, ArgPush, End, Builder.GetInsertBlock());
400 Builder.SetInsertPoint(ArgPush);
401
402 // Create controlDWord and store as the first entry, format as follows
403 // Bit 0 (LSB) -> stream (1 if stderr, 0 if stdout, printf always outputs to
404 // stdout) Bit 1 -> constant format string (1 if constant) Bits 2-31 -> size
405 // of printf data frame
406 auto ConstantTwo = Builder.getInt32(2);
407 auto ControlDWord = Builder.CreateShl(ArgSize, ConstantTwo);
408 if (IsConstFmtStr)
409 ControlDWord = Builder.CreateOr(ControlDWord, ConstantTwo);
410
411 Builder.CreateStore(ControlDWord, Ptr);
412
413 Ptr = Builder.CreateConstInBoundsGEP1_32(Int8Ty, Ptr, 4);
414
415 // Create MD5 hash for constant format string, push low 64 bits of the
416 // same onto buffer and metadata.
417 NamedMDNode *metaD = M->getOrInsertNamedMetadata("llvm.printf.fmts");
418 if (IsConstFmtStr) {
419 MDString *fmtStrArray =
421 MDNode *myMD = MDNode::get(Ctx, fmtStrArray);
422 metaD->addOperand(myMD);
423
424 Builder.CreateStore(Builder.getInt64(getAMDGPUPrintfFormatHash(FmtStr)),
425 Ptr);
426 Ptr = Builder.CreateConstInBoundsGEP1_32(Int8Ty, Ptr, 8);
427 } else {
428 // Include a dummy metadata instance in case of only non constant
429 // format string usage, This might be an absurd usecase but needs to
430 // be done for completeness
431 if (metaD->getNumOperands() == 0) {
432 MDString *fmtStrArray =
434 MDNode *myMD = MDNode::get(Ctx, fmtStrArray);
435 metaD->addOperand(myMD);
436 }
437 }
438
439 // Push The printf arguments onto buffer
440 callBufferedPrintfArgPush(Builder, Args, Ptr, SpecIsCString, StringContents,
441 IsConstFmtStr);
442
443 // End block, returns -1 on failure
444 UncondBrInst::Create(End, ArgPush);
445 Builder.SetInsertPoint(End);
446 return Builder.CreateSExt(Builder.CreateNot(Cmp), Int32Ty, "printf_result");
447 }
448
449 auto Desc = callPrintfBegin(Builder, Builder.getIntN(64, 0));
450 Desc = appendString(Builder, Desc, Fmt, NumOps == 1);
451
452 // FIXME: This invokes hostcall once for each argument. We can pack up to
453 // seven scalar printf arguments in a single hostcall. See the signature of
454 // callAppendArgs().
455 for (unsigned int i = 1; i != NumOps; ++i) {
456 bool IsLast = i == NumOps - 1;
457 bool IsCString = SpecIsCString.test(i);
458 Desc = processArg(Builder, Desc, Args[i], IsCString, IsLast);
459 }
460
461 return Builder.CreateTrunc(Desc, Builder.getInt32Ty());
462}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 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)
Helpers for the AMDGPU printf runtime interface, shared by the lowerings of printf calls on the AMDGP...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Module.h This file contains the declarations for the Module class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
This file defines the SparseBitVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator begin()
Instruction iterator methods.
Definition BasicBlock.h:440
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
A constant pointer value that points to null.
Definition Constants.h:716
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2909
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
Metadata node.
Definition Metadata.h:1081
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1579
A single uniqued string.
Definition Metadata.h:733
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Definition Metadata.cpp:597
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
A tuple of MDNodes.
Definition Metadata.h:1797
LLVM_ABI unsigned getNumOperands() const
LLVM_ABI void addOperand(MDNode *M)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
bool test(unsigned Idx) const
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
@ DoubleTyID
64-bit floating point type
Definition Type.h:60
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
#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.
@ Length
Definition DWP.cpp:577
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI 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.
LLVM_ABI std::string getAMDGPUPrintfFormatMetadata(StringRef Fmt)
Returns the llvm.printf.fmts entry that maps the ID of the constant format string Fmt back to the str...
Op::Description Desc
LLVM_ABI Value * emitAMDGPUPrintfCall(IRBuilder<> &Builder, ArrayRef< Value * > Args, bool isBuffered)
LLVM_ABI uint64_t getAMDGPUPrintfFormatHash(StringRef Fmt)
Returns the ID that buffered printf stores in place of the constant format string Fmt the low 64 bits...
LLVM_ABI void locateAMDGPUPrintfCStrings(SparseBitVector< 8 > &BV, StringRef Fmt)
Marks the printf arguments that the format string Fmt specifies as strings, i.e.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI void packAMDGPUPrintfConstantString(StringRef Str, SmallVectorImpl< uint32_t > &Words)
Splits the constant string argument Str, including its terminating NUL, into the little-endian 32-bit...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
constexpr StringLiteral AMDGPUPrintfNonConstFormatMetadata
The llvm.printf.fmts entry added when a module only uses buffered printf with non-constant format str...
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