23#define DEBUG_TYPE "amdgpu-emit-printf"
26 auto Int64Ty =
Builder.getInt64Ty();
27 auto Ty =
Arg->getType();
29 if (
auto IntTy = dyn_cast<IntegerType>(Ty)) {
30 switch (IntTy->getBitWidth()) {
42 if (isa<PointerType>(Ty)) {
50 auto Int64Ty =
Builder.getInt64Ty();
51 auto M =
Builder.GetInsertBlock()->getModule();
52 auto Fn = M->getOrInsertFunction(
"__ockl_printf_begin", Int64Ty, Int64Ty);
53 return Builder.CreateCall(Fn, Version);
60 auto Int64Ty =
Builder.getInt64Ty();
62 auto M =
Builder.GetInsertBlock()->getModule();
63 auto Fn = M->getOrInsertFunction(
"__ockl_printf_append_args", Int64Ty,
64 Int64Ty,
Int32Ty, Int64Ty, Int64Ty, Int64Ty,
65 Int64Ty, Int64Ty, Int64Ty, Int64Ty,
Int32Ty);
66 auto IsLastValue =
Builder.getInt32(IsLast);
67 auto NumArgsValue =
Builder.getInt32(NumArgs);
68 return Builder.CreateCall(Fn, {Desc, NumArgsValue, Arg0, Arg1, Arg2, Arg3,
69 Arg4, Arg5, Arg6, IsLastValue});
75 auto Zero =
Builder.getInt64(0);
83 auto *Prev =
Builder.GetInsertBlock();
84 Module *M = Prev->getModule();
86 auto CharZero =
Builder.getInt8(0);
88 auto Zero =
Builder.getInt64(0);
89 auto Int64Ty =
Builder.getInt64Ty();
98 if (Prev->getTerminator()) {
108 Prev->getParent(), Join);
110 M->getContext(),
"strlen.while.done",
111 Prev->getParent(), Join);
122 auto PtrPhi =
Builder.CreatePHI(Str->getType(), 2);
123 PtrPhi->addIncoming(Str, Prev);
124 auto PtrNext =
Builder.CreateGEP(
Builder.getInt8Ty(), PtrPhi, One);
125 PtrPhi->addIncoming(PtrNext, While);
130 Builder.CreateCondBr(Cmp, WhileDone, While);
134 auto Begin =
Builder.CreatePtrToInt(Str, Int64Ty);
135 auto End =
Builder.CreatePtrToInt(PtrPhi, Int64Ty);
137 Len =
Builder.CreateAdd(Len, One);
142 auto LenPhi =
Builder.CreatePHI(Len->getType(), 2);
143 LenPhi->addIncoming(Len, WhileDone);
144 LenPhi->addIncoming(Zero, Prev);
151 auto Int64Ty =
Builder.getInt64Ty();
152 auto CharPtrTy =
Builder.getInt8PtrTy();
154 auto M =
Builder.GetInsertBlock()->getModule();
155 auto Fn = M->getOrInsertFunction(
"__ockl_printf_append_string_n", Int64Ty,
156 Int64Ty, CharPtrTy, Int64Ty,
Int32Ty);
157 auto IsLastInt32 =
Builder.getInt32(isLast);
158 return Builder.CreateCall(Fn, {Desc, Str,
Length, IsLastInt32});
164 Arg,
Builder.getInt8PtrTy(
Arg->getType()->getPointerAddressSpace()));
170 bool SpecIsCString,
bool IsLast) {
171 if (SpecIsCString && isa<PointerType>(
Arg->getType())) {
187 static const char ConvSpecifiers[] =
"diouxXfFeEgGaAcspn";
192 while ((SpecPos = Str.find_first_of(
'%', SpecPos)) !=
StringRef::npos) {
193 if (Str[SpecPos + 1] ==
'%') {
197 auto SpecEnd = Str.find_first_of(ConvSpecifiers, SpecPos);
200 auto Spec = Str.slice(SpecPos, SpecEnd + 1);
201 ArgIdx +=
Spec.count(
'*');
202 if (Str[SpecEnd] ==
's') {
205 SpecPos = SpecEnd + 1;
212 auto NumOps = Args.size();
225 for (
unsigned int i = 1; i != NumOps; ++i) {
226 bool IsLast = i == NumOps - 1;
227 bool IsCString = SpecIsCString.
test(i);
static Value * appendString(IRBuilder<> &Builder, Value *Desc, Value *Arg, bool IsLast)
static void locateCStrings(SparseBitVector< 8 > &BV, Value *Fmt)
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 * processArg(IRBuilder<> &Builder, Value *Desc, Value *Arg, bool SpecIsCString, bool IsLast)
static Value * getStrlenWithNull(IRBuilder<> &Builder, Value *Str)
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SparseBitVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
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...
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A Module instance is used to store all the information related to an LLVM module.
bool test(unsigned Idx) const
StringRef - Represent a constant reference to a string, i.e.
static constexpr size_t npos
@ DoubleTyID
64-bit floating point type
LLVM Value Representation.
#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.
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.
Value * emitAMDGPUPrintfCall(IRBuilder<> &Builder, ArrayRef< Value * > Args)