forked from OSchip/llvm-project
Revert "Add NVIDIA vprintf printing to RuntimeDebugBuilder"
This reverts commit 239219 which requires some LLVM changes I forgot to commit. Reported-by: Marshall Clow llvm-svn: 239306
This commit is contained in:
parent
4791f6d89b
commit
039955a44c
|
@ -13,8 +13,7 @@
|
|||
#define RUNTIME_DEBUG_BUILDER_H
|
||||
|
||||
#include "polly/CodeGen/IRBuilder.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class Value;
|
||||
|
@ -53,70 +52,6 @@ struct RuntimeDebugBuilder {
|
|||
/// If the current module does not yet contain a reference to printf, we
|
||||
/// insert a reference to it. Otherwise the existing reference is returned.
|
||||
static llvm::Function *getPrintF(PollyIRBuilder &Builder);
|
||||
|
||||
/// @brief Print a set of LLVM-IR Values or StringRefs on an NVIDIA GPU.
|
||||
///
|
||||
/// This function emits a call to vprintf that will print the given
|
||||
/// arguments from within a kernel thread. It is useful for debugging
|
||||
/// CUDA program kernels. All arguments given in this list will be
|
||||
/// automatically concatenated and the resulting string will be printed
|
||||
/// atomically. We also support ArrayRef arguments, which can be used to
|
||||
/// provide for example a list of thread-id values.
|
||||
///
|
||||
/// @param Builder The builder used to emit the printer calls.
|
||||
/// @param Args The list of values to print.
|
||||
template <typename... Args>
|
||||
static void createGPUPrinter(PollyIRBuilder &Builder, Args... args) {
|
||||
std::vector<llvm::Value *> Vector;
|
||||
createGPUVAPrinter(Builder, Vector, args...);
|
||||
}
|
||||
|
||||
private:
|
||||
/// @brief GPU printing - Print a list of LLVM Values.
|
||||
///
|
||||
static void createGPUVAPrinter(PollyIRBuilder &Builder,
|
||||
llvm::ArrayRef<llvm::Value *> Values);
|
||||
|
||||
/// @brief GPU printing - Handle Values.
|
||||
template <typename... Args>
|
||||
static void createGPUVAPrinter(PollyIRBuilder &Builder,
|
||||
std::vector<llvm::Value *> &Values,
|
||||
llvm::Value *Value, Args... args) {
|
||||
Values.push_back(Value);
|
||||
createGPUVAPrinter(Builder, Values, args...);
|
||||
}
|
||||
|
||||
/// @brief GPU printing - Handle StringRefs.
|
||||
template <typename... Args>
|
||||
static void createGPUVAPrinter(PollyIRBuilder &Builder,
|
||||
std::vector<llvm::Value *> &Values,
|
||||
llvm::StringRef String, Args... args) {
|
||||
Values.push_back(Builder.CreateGlobalStringPtr(String, "", 4));
|
||||
createGPUVAPrinter(Builder, Values, args...);
|
||||
}
|
||||
|
||||
/// @brief GPU printing - Handle ArrayRefs.
|
||||
template <typename... Args>
|
||||
static void createGPUVAPrinter(PollyIRBuilder &Builder,
|
||||
std::vector<llvm::Value *> &Values,
|
||||
llvm::ArrayRef<llvm::Value *> Array,
|
||||
Args... args) {
|
||||
if (Array.size() >= 2)
|
||||
createGPUVAPrinter(
|
||||
Builder, Values, Array[0], " ",
|
||||
llvm::ArrayRef<llvm::Value *>(&Array[1], Array.size() - 1), args...);
|
||||
else
|
||||
createGPUVAPrinter(Builder, Values, Array[0], args...);
|
||||
}
|
||||
|
||||
/// @brief Get (and possibly insert) a vprintf declaration into the module.
|
||||
static llvm::Function *getVPrintF(PollyIRBuilder &Builder);
|
||||
|
||||
/// @brief Get (and possibly insert) a NVIDIA address space cast call.
|
||||
static llvm::Function *getAddressSpaceCast(PollyIRBuilder &Builder,
|
||||
unsigned Src, unsigned Dst,
|
||||
unsigned SrcBits = 8,
|
||||
unsigned DstBits = 8);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -11,111 +11,10 @@
|
|||
|
||||
#include "polly/CodeGen/RuntimeDebugBuilder.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/Debug.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;
|
||||
}
|
||||
|
||||
void RuntimeDebugBuilder::createGPUVAPrinter(PollyIRBuilder &Builder,
|
||||
ArrayRef<Value *> Values) {
|
||||
std::string str;
|
||||
|
||||
// Allocate print buffer (assuming 2*32 bit per element)
|
||||
auto T = ArrayType::get(Builder.getInt32Ty(), Values.size() * 2);
|
||||
Value *Data = new AllocaInst(
|
||||
T, "polly.vprint.buffer",
|
||||
Builder.GetInsertBlock()->getParent()->getEntryBlock().begin());
|
||||
|
||||
auto *Zero = Builder.getInt64(0);
|
||||
auto *DataPtr = Builder.CreateGEP(Data, {Zero, Zero});
|
||||
|
||||
int Offset = 0;
|
||||
for (auto Val : Values) {
|
||||
auto Ptr = Builder.CreateGEP(DataPtr, {Builder.getInt64(Offset)});
|
||||
Type *Ty = Val->getType();
|
||||
|
||||
if (Ty->isFloatingPointTy()) {
|
||||
if (!Ty->isDoubleTy()) {
|
||||
Ty = Builder.getDoubleTy();
|
||||
Val = Builder.CreateFPExt(Val, Ty);
|
||||
}
|
||||
} else if (Ty->isIntegerTy()) {
|
||||
auto Int64Bitwidth = Builder.getInt64Ty()->getIntegerBitWidth();
|
||||
assert(Ty->getIntegerBitWidth() <= Int64Bitwidth);
|
||||
if (Ty->getIntegerBitWidth() < Int64Bitwidth) {
|
||||
Ty = Builder.getInt64Ty();
|
||||
Val = Builder.CreateSExt(Val, Ty);
|
||||
}
|
||||
} else {
|
||||
// If it is not a number, it must be a string type.
|
||||
Val = Builder.CreateGEP(Val, Builder.getInt64(0));
|
||||
assert((Val->getType() == Builder.getInt8PtrTy(4)) &&
|
||||
"Expected i8 ptr placed in constant address space");
|
||||
auto F = RuntimeDebugBuilder::getAddressSpaceCast(Builder, 4, 0);
|
||||
Val = Builder.CreateCall(F, Val);
|
||||
Ty = Val->getType();
|
||||
}
|
||||
|
||||
Ptr = Builder.CreatePointerBitCastOrAddrSpaceCast(Ptr, Ty->getPointerTo(5));
|
||||
Builder.CreateAlignedStore(Val, Ptr, 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";
|
||||
|
|
Loading…
Reference in New Issue