You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
6.6 KiB
170 lines
6.6 KiB
//===--- RuntimeDebugBuilder.h --- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef RUNTIME_DEBUG_BUILDER_H
|
|
#define RUNTIME_DEBUG_BUILDER_H
|
|
|
|
#include "polly/CodeGen/IRBuilder.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include <vector>
|
|
|
|
namespace llvm {
|
|
class Value;
|
|
class Function;
|
|
} // namespace llvm
|
|
|
|
namespace polly {
|
|
|
|
/// Insert function calls that print certain LLVM values at run time.
|
|
///
|
|
/// This class inserts libc function calls to print certain LLVM values at
|
|
/// run time.
|
|
struct RuntimeDebugBuilder {
|
|
|
|
/// Generate a constant string into the builder's llvm::Module which can be
|
|
/// passed to createGPUPrinter() or createGPUPrinter().
|
|
///
|
|
/// @param Builder The builder used to emit the printer calls.
|
|
/// @param Str The string to be printed.
|
|
|
|
/// @return A global containing @p Str.
|
|
static llvm::Value *getPrintableString(PollyIRBuilder &Builder,
|
|
llvm::StringRef Str) {
|
|
// TODO: Get rid of magic number 4. It it NVPTX's constant address space and
|
|
// works on X86 (CPU) only because its backend ignores the address space.
|
|
return Builder.CreateGlobalStringPtr(Str, "", 4);
|
|
}
|
|
|
|
/// Return whether an llvm::Value of the type @p Ty is printable for
|
|
/// debugging.
|
|
///
|
|
/// That is, whether such a value can be passed to createGPUPrinter() or
|
|
/// createGPUPrinter() to be dumped as runtime. If false is returned, those
|
|
/// functions will fail.
|
|
static bool isPrintable(llvm::Type *Ty);
|
|
|
|
/// Print a set of LLVM-IR Values or StringRefs via printf
|
|
///
|
|
/// This function emits a call to printf that will print the given arguments.
|
|
/// It is useful for debugging CPU programs. 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 of 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 createCPUPrinter(PollyIRBuilder &Builder, Args... args) {
|
|
std::vector<llvm::Value *> Vector;
|
|
createPrinter(Builder, /* CPU */ false, Vector, args...);
|
|
}
|
|
|
|
/// 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;
|
|
createPrinter(Builder, /* GPU */ true, Vector, args...);
|
|
}
|
|
|
|
private:
|
|
/// Handle Values.
|
|
template <typename... Args>
|
|
static void createPrinter(PollyIRBuilder &Builder, bool UseGPU,
|
|
std::vector<llvm::Value *> &Values,
|
|
llvm::Value *Value, Args... args) {
|
|
Values.push_back(Value);
|
|
createPrinter(Builder, UseGPU, Values, args...);
|
|
}
|
|
|
|
/// Handle StringRefs.
|
|
template <typename... Args>
|
|
static void createPrinter(PollyIRBuilder &Builder, bool UseGPU,
|
|
std::vector<llvm::Value *> &Values,
|
|
llvm::StringRef String, Args... args) {
|
|
Values.push_back(getPrintableString(Builder, String));
|
|
createPrinter(Builder, UseGPU, Values, args...);
|
|
}
|
|
|
|
/// Handle ArrayRefs.
|
|
template <typename... Args>
|
|
static void createPrinter(PollyIRBuilder &Builder, bool UseGPU,
|
|
std::vector<llvm::Value *> &Values,
|
|
llvm::ArrayRef<llvm::Value *> Array, Args... args) {
|
|
Values.insert(Values.end(), Array.begin(), Array.end());
|
|
createPrinter(Builder, UseGPU, Values, args...);
|
|
}
|
|
|
|
/// Print a list of Values.
|
|
static void createPrinter(PollyIRBuilder &Builder, bool UseGPU,
|
|
llvm::ArrayRef<llvm::Value *> Values);
|
|
|
|
/// Print a list of Values on a GPU.
|
|
static void createGPUPrinterT(PollyIRBuilder &Builder,
|
|
llvm::ArrayRef<llvm::Value *> Values);
|
|
|
|
/// Print a list of Values on a CPU.
|
|
static void createCPUPrinterT(PollyIRBuilder &Builder,
|
|
llvm::ArrayRef<llvm::Value *> Values);
|
|
|
|
/// Get a reference to the 'printf' function.
|
|
///
|
|
/// 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);
|
|
|
|
/// Call printf
|
|
///
|
|
/// @param Builder The builder used to insert the code.
|
|
/// @param Format The format string.
|
|
/// @param Values The set of values to print.
|
|
static void createPrintF(PollyIRBuilder &Builder, std::string Format,
|
|
llvm::ArrayRef<llvm::Value *> Values);
|
|
|
|
/// Get (and possibly insert) a vprintf declaration into the module.
|
|
static llvm::Function *getVPrintF(PollyIRBuilder &Builder);
|
|
|
|
/// Call fflush
|
|
///
|
|
/// @parma Builder The builder used to insert the code.
|
|
static void createFlush(PollyIRBuilder &Builder);
|
|
|
|
/// 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);
|
|
|
|
/// Get identifiers that describe the currently executed GPU thread.
|
|
///
|
|
/// The result will be a vector that if passed to the GPU printer will result
|
|
/// into a string (initialized to values corresponding to the printing
|
|
/// thread):
|
|
///
|
|
/// "> block-id: bidx bid1y bidz | thread-id: tidx tidy tidz "
|
|
static std::vector<llvm::Value *>
|
|
getGPUThreadIdentifiers(PollyIRBuilder &Builder);
|
|
};
|
|
} // namespace polly
|
|
|
|
extern bool PollyDebugPrinting;
|
|
|
|
#endif
|