16 #include "llvm/IR/DataLayout.h"
17 #include "llvm/IR/Instruction.h"
18 #include "llvm/Support/MathExtras.h"
19 #include "llvm/Transforms/Utils/AMDGPUEmitPrintf.h"
21 using namespace clang;
22 using namespace CodeGen;
25 llvm::Function *GetVprintfDeclaration(llvm::Module &M) {
26 llvm::Type *ArgTypes[] = {llvm::Type::getInt8PtrTy(M.getContext()),
27 llvm::Type::getInt8PtrTy(M.getContext())};
28 llvm::FunctionType *VprintfFuncType = llvm::FunctionType::get(
29 llvm::Type::getInt32Ty(M.getContext()), ArgTypes,
false);
31 if (
auto *F = M.getFunction(
"vprintf")) {
35 assert(F->getFunctionType() == VprintfFuncType);
41 return llvm::Function::Create(
45 llvm::Function *GetOpenMPVprintfDeclaration(
CodeGenModule &CGM) {
46 const char *Name =
"__llvm_omp_vprintf";
48 llvm::Type *ArgTypes[] = {llvm::Type::getInt8PtrTy(M.getContext()),
49 llvm::Type::getInt8PtrTy(M.getContext()),
50 llvm::Type::getInt32Ty(M.getContext())};
51 llvm::FunctionType *VprintfFuncType = llvm::FunctionType::get(
52 llvm::Type::getInt32Ty(M.getContext()), ArgTypes,
false);
54 if (
auto *F = M.getFunction(Name)) {
55 if (F->getFunctionType() != VprintfFuncType) {
57 "Invalid type declaration for __llvm_omp_vprintf");
63 return llvm::Function::Create(
93 std::pair<llvm::Value *, llvm::TypeSize>
100 if (Args.size() <= 1) {
102 llvm::Value * BufferPtr = llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(Ctx));
103 return {BufferPtr, llvm::TypeSize::Fixed(0)};
106 for (
unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I)
107 ArgTypes.push_back(Args[I].getRValue(*CGF).getScalarVal()->getType());
117 for (
unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I) {
118 llvm::Value *
P = Builder.CreateStructGEP(AllocaTy, Alloca, I - 1);
119 llvm::Value *Arg = Args[I].getRValue(*CGF).getScalarVal();
120 Builder.CreateAlignedStore(Arg,
P, DL.getPrefTypeAlign(Arg->getType()));
122 llvm::Value *BufferPtr =
123 Builder.CreatePointerCast(Alloca, llvm::Type::getInt8PtrTy(Ctx));
124 return {BufferPtr, DL.getTypeAllocSize(AllocaTy)};
129 return llvm::any_of(llvm::drop_begin(Args), [&](
const CallArg &A) {
135 llvm::Function *
Decl,
bool WithSizeArg) {
150 if (containsNonScalarVarargs(CGF, Args)) {
155 auto r = packArgsIntoNVPTXFormatBuffer(CGF, Args);
156 llvm::Value *BufferPtr = r.first;
159 Args[0].getRValue(*CGF).getScalarVal(), BufferPtr};
163 llvm::Constant *
Size =
164 llvm::ConstantInt::get(llvm::Type::getInt32Ty(CGM.
getLLVMContext()),
165 static_cast<uint32_t
>(r.second.getFixedSize()));
174 assert(
getTarget().getTriple().isNVPTX());
175 return EmitDevicePrintfCallExpr(
176 E,
this, GetVprintfDeclaration(
CGM.
getModule()),
false);
180 assert(
getTarget().getTriple().getArch() == llvm::Triple::amdgcn);
192 for (
auto A : CallArgs) {
194 if (!A.getRValue(*this).isScalar()) {
199 llvm::Value *Arg = A.getRValue(*this).getScalarVal();
203 llvm::IRBuilder<> IRB(
Builder.GetInsertBlock(),
Builder.GetInsertPoint());
204 IRB.SetCurrentDebugLocation(
Builder.getCurrentDebugLocation());
205 auto Printf = llvm::emitAMDGPUPrintfCall(IRB, Args);
206 Builder.SetInsertPoint(IRB.GetInsertBlock(), IRB.GetInsertPoint());
211 assert(
getTarget().getTriple().isNVPTX() ||
213 return EmitDevicePrintfCallExpr(E,
this, GetOpenMPVprintfDeclaration(
CGM),