Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===--- RuntimeDebugBuilder.h --- Helper to insert prints into LLVM-IR ---===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//===----------------------------------------------------------------------===//
10
 
11
#ifndef RUNTIME_DEBUG_BUILDER_H
12
#define RUNTIME_DEBUG_BUILDER_H
13
 
14
#include "polly/CodeGen/IRBuilder.h"
15
#include "llvm/ADT/ArrayRef.h"
16
#include "llvm/ADT/StringRef.h"
17
#include <vector>
18
 
19
namespace llvm {
20
class Value;
21
class Function;
22
} // namespace llvm
23
 
24
namespace polly {
25
 
26
/// Insert function calls that print certain LLVM values at run time.
27
///
28
/// This class inserts libc function calls to print certain LLVM values at
29
/// run time.
30
struct RuntimeDebugBuilder {
31
 
32
  /// Generate a constant string into the builder's llvm::Module which can be
33
  /// passed to createGPUPrinter() or createGPUPrinter().
34
  ///
35
  /// @param Builder The builder used to emit the printer calls.
36
  /// @param Str     The string to be printed.
37
 
38
  /// @return        A global containing @p Str.
39
  static llvm::Value *getPrintableString(PollyIRBuilder &Builder,
40
                                         llvm::StringRef Str) {
41
    // TODO: Get rid of magic number 4. It it NVPTX's constant address space and
42
    // works on X86 (CPU) only because its backend ignores the address space.
43
    return Builder.CreateGlobalStringPtr(Str, "", 4);
44
  }
45
 
46
  /// Return whether an llvm::Value of the type @p Ty is printable for
47
  /// debugging.
48
  ///
49
  /// That is, whether such a value can be passed to createGPUPrinter() or
50
  /// createGPUPrinter() to be dumped as runtime.  If false is returned, those
51
  /// functions will fail.
52
  static bool isPrintable(llvm::Type *Ty);
53
 
54
  /// Print a set of LLVM-IR Values or StringRefs via printf
55
  ///
56
  ///  This function emits a call to printf that will print the given arguments.
57
  ///  It is useful for debugging CPU programs. All arguments given in this list
58
  ///  will be automatically concatenated and the resulting string will be
59
  ///  printed atomically. We also support ArrayRef arguments, which can be used
60
  ///  to provide of id values.
61
  ///
62
  ///  @param Builder The builder used to emit the printer calls.
63
  ///  @param Args    The list of values to print.
64
  template <typename... Args>
65
  static void createCPUPrinter(PollyIRBuilder &Builder, Args... args) {
66
    std::vector<llvm::Value *> Vector;
67
    createPrinter(Builder, /* CPU */ false, Vector, args...);
68
  }
69
 
70
  /// Print a set of LLVM-IR Values or StringRefs on an NVIDIA GPU.
71
  ///
72
  ///  This function emits a call to vprintf that will print the given
73
  ///  arguments from within a kernel thread. It is useful for debugging
74
  ///  CUDA program kernels. All arguments given in this list will be
75
  ///  automatically concatenated and the resulting string will be printed
76
  ///  atomically. We also support ArrayRef arguments, which can be used to
77
  ///  provide for example a list of thread-id values.
78
  ///
79
  ///  @param Builder The builder used to emit the printer calls.
80
  ///  @param Args    The list of values to print.
81
  template <typename... Args>
82
  static void createGPUPrinter(PollyIRBuilder &Builder, Args... args) {
83
    std::vector<llvm::Value *> Vector;
84
    createPrinter(Builder, /* GPU */ true, Vector, args...);
85
  }
86
 
87
private:
88
  /// Handle Values.
89
  template <typename... Args>
90
  static void createPrinter(PollyIRBuilder &Builder, bool UseGPU,
91
                            std::vector<llvm::Value *> &Values,
92
                            llvm::Value *Value, Args... args) {
93
    Values.push_back(Value);
94
    createPrinter(Builder, UseGPU, Values, args...);
95
  }
96
 
97
  /// Handle StringRefs.
98
  template <typename... Args>
99
  static void createPrinter(PollyIRBuilder &Builder, bool UseGPU,
100
                            std::vector<llvm::Value *> &Values,
101
                            llvm::StringRef String, Args... args) {
102
    Values.push_back(getPrintableString(Builder, String));
103
    createPrinter(Builder, UseGPU, Values, args...);
104
  }
105
 
106
  /// Handle ArrayRefs.
107
  template <typename... Args>
108
  static void createPrinter(PollyIRBuilder &Builder, bool UseGPU,
109
                            std::vector<llvm::Value *> &Values,
110
                            llvm::ArrayRef<llvm::Value *> Array, Args... args) {
111
    Values.insert(Values.end(), Array.begin(), Array.end());
112
    createPrinter(Builder, UseGPU, Values, args...);
113
  }
114
 
115
  /// Print a list of Values.
116
  static void createPrinter(PollyIRBuilder &Builder, bool UseGPU,
117
                            llvm::ArrayRef<llvm::Value *> Values);
118
 
119
  /// Print a list of Values on a GPU.
120
  static void createGPUPrinterT(PollyIRBuilder &Builder,
121
                                llvm::ArrayRef<llvm::Value *> Values);
122
 
123
  /// Print a list of Values on a CPU.
124
  static void createCPUPrinterT(PollyIRBuilder &Builder,
125
                                llvm::ArrayRef<llvm::Value *> Values);
126
 
127
  /// Get a reference to the 'printf' function.
128
  ///
129
  /// If the current module does not yet contain a reference to printf, we
130
  /// insert a reference to it. Otherwise the existing reference is returned.
131
  static llvm::Function *getPrintF(PollyIRBuilder &Builder);
132
 
133
  /// Call printf
134
  ///
135
  /// @param Builder The builder used to insert the code.
136
  /// @param Format  The format string.
137
  /// @param Values  The set of values to print.
138
  static void createPrintF(PollyIRBuilder &Builder, std::string Format,
139
                           llvm::ArrayRef<llvm::Value *> Values);
140
 
141
  /// Get (and possibly insert) a vprintf declaration into the module.
142
  static llvm::Function *getVPrintF(PollyIRBuilder &Builder);
143
 
144
  /// Call fflush
145
  ///
146
  /// @parma Builder The builder used to insert the code.
147
  static void createFlush(PollyIRBuilder &Builder);
148
 
149
  /// Get (and possibly insert) a NVIDIA address space cast call.
150
  static llvm::Function *getAddressSpaceCast(PollyIRBuilder &Builder,
151
                                             unsigned Src, unsigned Dst,
152
                                             unsigned SrcBits = 8,
153
                                             unsigned DstBits = 8);
154
 
155
  /// Get identifiers that describe the currently executed GPU thread.
156
  ///
157
  /// The result will be a vector that if passed to the GPU printer will result
158
  /// into a string (initialized to values corresponding to the printing
159
  /// thread):
160
  ///
161
  ///   "> block-id: bidx bid1y bidz | thread-id: tidx tidy tidz "
162
  static std::vector<llvm::Value *>
163
  getGPUThreadIdentifiers(PollyIRBuilder &Builder);
164
};
165
} // namespace polly
166
 
167
extern bool PollyDebugPrinting;
168
 
169
#endif