diff options
author | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
---|---|---|
committer | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
commit | 06e5c21a835c0e923506c4ff27929f34e00761c2 (patch) | |
tree | 75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /contrib/libs/llvm12/tools/polly/lib/CodeGen/RuntimeDebugBuilder.cpp | |
parent | 03f024c4412e3aa613bb543cf1660176320ba8f4 (diff) | |
download | ydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz |
fix ya.make
Diffstat (limited to 'contrib/libs/llvm12/tools/polly/lib/CodeGen/RuntimeDebugBuilder.cpp')
-rw-r--r-- | contrib/libs/llvm12/tools/polly/lib/CodeGen/RuntimeDebugBuilder.cpp | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/contrib/libs/llvm12/tools/polly/lib/CodeGen/RuntimeDebugBuilder.cpp b/contrib/libs/llvm12/tools/polly/lib/CodeGen/RuntimeDebugBuilder.cpp new file mode 100644 index 0000000000..2a349fe0f2 --- /dev/null +++ b/contrib/libs/llvm12/tools/polly/lib/CodeGen/RuntimeDebugBuilder.cpp @@ -0,0 +1,288 @@ +//===--- RuntimeDebugBuilder.cpp - Helper to insert prints into LLVM-IR ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#include "polly/CodeGen/RuntimeDebugBuilder.h" +#include "llvm/IR/IntrinsicsNVPTX.h" +#include "llvm/IR/Module.h" +#include <string> +#include <vector> + +using namespace llvm; +using namespace polly; + +Function *RuntimeDebugBuilder::getVPrintF(PollyIRBuilder &Builder) { + Module *M = Builder.GetInsertBlock()->getParent()->getParent(); + const char *Name = "vprintf"; + Function *F = M->getFunction(Name); + + if (!F) { + GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage; + FunctionType *Ty = FunctionType::get( + Builder.getInt32Ty(), {Builder.getInt8PtrTy(), Builder.getInt8PtrTy()}, + false); + F = Function::Create(Ty, Linkage, Name, M); + } + + return F; +} + +Function *RuntimeDebugBuilder::getAddressSpaceCast(PollyIRBuilder &Builder, + unsigned Src, unsigned Dst, + unsigned SrcBits, + unsigned DstBits) { + Module *M = Builder.GetInsertBlock()->getParent()->getParent(); + auto Name = std::string("llvm.nvvm.ptr.constant.to.gen.p") + + std::to_string(Dst) + "i" + std::to_string(DstBits) + ".p" + + std::to_string(Src) + "i" + std::to_string(SrcBits); + Function *F = M->getFunction(Name); + + if (!F) { + GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage; + FunctionType *Ty = FunctionType::get( + PointerType::get(Builder.getIntNTy(DstBits), Dst), + PointerType::get(Builder.getIntNTy(SrcBits), Src), false); + F = Function::Create(Ty, Linkage, Name, M); + } + + return F; +} + +std::vector<Value *> +RuntimeDebugBuilder::getGPUThreadIdentifiers(PollyIRBuilder &Builder) { + std::vector<Value *> Identifiers; + + auto M = Builder.GetInsertBlock()->getParent()->getParent(); + + std::vector<Function *> BlockIDs = { + Intrinsic::getDeclaration(M, Intrinsic::nvvm_read_ptx_sreg_ctaid_x), + Intrinsic::getDeclaration(M, Intrinsic::nvvm_read_ptx_sreg_ctaid_y), + Intrinsic::getDeclaration(M, Intrinsic::nvvm_read_ptx_sreg_ctaid_z), + }; + + Identifiers.push_back(Builder.CreateGlobalStringPtr("> block-id: ", "", 4)); + for (auto GetID : BlockIDs) { + Value *Id = Builder.CreateCall(GetID, {}); + Id = Builder.CreateIntCast(Id, Builder.getInt64Ty(), false); + Identifiers.push_back(Id); + Identifiers.push_back(Builder.CreateGlobalStringPtr(" ", "", 4)); + } + + Identifiers.push_back(Builder.CreateGlobalStringPtr("| ", "", 4)); + + std::vector<Function *> ThreadIDs = { + Intrinsic::getDeclaration(M, Intrinsic::nvvm_read_ptx_sreg_tid_x), + Intrinsic::getDeclaration(M, Intrinsic::nvvm_read_ptx_sreg_tid_y), + Intrinsic::getDeclaration(M, Intrinsic::nvvm_read_ptx_sreg_tid_z), + }; + + Identifiers.push_back(Builder.CreateGlobalStringPtr("thread-id: ", "", 4)); + for (auto GetId : ThreadIDs) { + Value *Id = Builder.CreateCall(GetId, {}); + Id = Builder.CreateIntCast(Id, Builder.getInt64Ty(), false); + Identifiers.push_back(Id); + Identifiers.push_back(Builder.CreateGlobalStringPtr(" ", "", 4)); + } + + return Identifiers; +} + +void RuntimeDebugBuilder::createPrinter(PollyIRBuilder &Builder, bool IsGPU, + ArrayRef<Value *> Values) { + if (IsGPU) + createGPUPrinterT(Builder, Values); + else + createCPUPrinterT(Builder, Values); +} + +bool RuntimeDebugBuilder::isPrintable(Type *Ty) { + if (Ty->isFloatingPointTy()) + return true; + + if (Ty->isIntegerTy()) + return Ty->getIntegerBitWidth() <= 64; + + if (isa<PointerType>(Ty)) + return true; + + return false; +} + +static std::tuple<std::string, std::vector<Value *>> +prepareValuesForPrinting(PollyIRBuilder &Builder, ArrayRef<Value *> Values) { + std::string FormatString; + std::vector<Value *> ValuesToPrint; + + for (auto Val : Values) { + Type *Ty = Val->getType(); + + if (Ty->isFloatingPointTy()) { + if (!Ty->isDoubleTy()) + Val = Builder.CreateFPExt(Val, Builder.getDoubleTy()); + } else if (Ty->isIntegerTy()) { + if (Ty->getIntegerBitWidth() < 64) + Val = Builder.CreateSExt(Val, Builder.getInt64Ty()); + else + assert(Ty->getIntegerBitWidth() && + "Integer types larger 64 bit not supported"); + } else if (isa<PointerType>(Ty)) { + if (Ty->getPointerElementType() == Builder.getInt8Ty() && + Ty->getPointerAddressSpace() == 4) { + Val = Builder.CreateGEP(Val, Builder.getInt64(0)); + } else { + Val = Builder.CreatePtrToInt(Val, Builder.getInt64Ty()); + } + } else { + llvm_unreachable("Unknown type"); + } + + Ty = Val->getType(); + + if (Ty->isFloatingPointTy()) + FormatString += "%f"; + else if (Ty->isIntegerTy()) + FormatString += "%ld"; + else + FormatString += "%s"; + + ValuesToPrint.push_back(Val); + } + + return std::make_tuple(FormatString, ValuesToPrint); +} + +void RuntimeDebugBuilder::createCPUPrinterT(PollyIRBuilder &Builder, + ArrayRef<Value *> Values) { + + std::string FormatString; + std::vector<Value *> ValuesToPrint; + + std::tie(FormatString, ValuesToPrint) = + prepareValuesForPrinting(Builder, Values); + + createPrintF(Builder, FormatString, ValuesToPrint); + createFlush(Builder); +} + +void RuntimeDebugBuilder::createGPUPrinterT(PollyIRBuilder &Builder, + ArrayRef<Value *> Values) { + std::string str; + + auto *Zero = Builder.getInt64(0); + + auto ToPrint = getGPUThreadIdentifiers(Builder); + + ToPrint.push_back(Builder.CreateGlobalStringPtr("\n ", "", 4)); + ToPrint.insert(ToPrint.end(), Values.begin(), Values.end()); + + const DataLayout &DL = Builder.GetInsertBlock()->getModule()->getDataLayout(); + + // Allocate print buffer (assuming 2*32 bit per element) + auto T = ArrayType::get(Builder.getInt32Ty(), ToPrint.size() * 2); + Value *Data = new AllocaInst( + T, DL.getAllocaAddrSpace(), "polly.vprint.buffer", + &Builder.GetInsertBlock()->getParent()->getEntryBlock().front()); + auto *DataPtr = Builder.CreateGEP(Data, {Zero, Zero}); + + int Offset = 0; + for (auto Val : ToPrint) { + auto Ptr = Builder.CreateGEP(DataPtr, Builder.getInt64(Offset)); + Type *Ty = Val->getType(); + + if (Ty->isFloatingPointTy()) { + if (!Ty->isDoubleTy()) + Val = Builder.CreateFPExt(Val, Builder.getDoubleTy()); + } else if (Ty->isIntegerTy()) { + if (Ty->getIntegerBitWidth() < 64) { + Val = Builder.CreateSExt(Val, Builder.getInt64Ty()); + } else { + assert(Ty->getIntegerBitWidth() == 64 && + "Integer types larger 64 bit not supported"); + // fallthrough + } + } else if (auto PtTy = dyn_cast<PointerType>(Ty)) { + if (PtTy->getAddressSpace() == 4) { + // Pointers in constant address space are printed as strings + Val = Builder.CreateGEP(Val, Builder.getInt64(0)); + auto F = RuntimeDebugBuilder::getAddressSpaceCast(Builder, 4, 0); + Val = Builder.CreateCall(F, Val); + } else { + Val = Builder.CreatePtrToInt(Val, Builder.getInt64Ty()); + } + } else { + llvm_unreachable("Unknown type"); + } + + Ty = Val->getType(); + Ptr = Builder.CreatePointerBitCastOrAddrSpaceCast(Ptr, Ty->getPointerTo(5)); + Builder.CreateAlignedStore(Val, Ptr, Align(4)); + + if (Ty->isFloatingPointTy()) + str += "%f"; + else if (Ty->isIntegerTy()) + str += "%ld"; + else + str += "%s"; + + Offset += 2; + } + + Value *Format = Builder.CreateGlobalStringPtr(str, "polly.vprintf.buffer", 4); + Format = Builder.CreateCall(getAddressSpaceCast(Builder, 4, 0), Format); + + Data = Builder.CreateBitCast(Data, Builder.getInt8PtrTy()); + + Builder.CreateCall(getVPrintF(Builder), {Format, Data}); +} + +Function *RuntimeDebugBuilder::getPrintF(PollyIRBuilder &Builder) { + Module *M = Builder.GetInsertBlock()->getParent()->getParent(); + const char *Name = "printf"; + Function *F = M->getFunction(Name); + + if (!F) { + GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage; + FunctionType *Ty = FunctionType::get(Builder.getInt32Ty(), true); + F = Function::Create(Ty, Linkage, Name, M); + } + + return F; +} + +void RuntimeDebugBuilder::createPrintF(PollyIRBuilder &Builder, + std::string Format, + ArrayRef<Value *> Values) { + Value *FormatString = Builder.CreateGlobalStringPtr(Format); + std::vector<Value *> Arguments; + + Arguments.push_back(FormatString); + Arguments.insert(Arguments.end(), Values.begin(), Values.end()); + Builder.CreateCall(getPrintF(Builder), Arguments); +} + +void RuntimeDebugBuilder::createFlush(PollyIRBuilder &Builder) { + Module *M = Builder.GetInsertBlock()->getParent()->getParent(); + const char *Name = "fflush"; + Function *F = M->getFunction(Name); + + if (!F) { + GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage; + FunctionType *Ty = + FunctionType::get(Builder.getInt32Ty(), Builder.getInt8PtrTy(), false); + F = Function::Create(Ty, Linkage, Name, M); + } + + // fflush(NULL) flushes _all_ open output streams. + // + // fflush is declared as 'int fflush(FILE *stream)'. As we only pass on a NULL + // pointer, the type we point to does conceptually not matter. However, if + // fflush is already declared in this translation unit, we use the very same + // type to ensure that LLVM does not complain about mismatching types. + Builder.CreateCall(F, Constant::getNullValue(F->arg_begin()->getType())); +} |