/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/include/polly/CodeGen/RuntimeDebugBuilder.h
Line | Count | Source |
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 | 92 | llvm::StringRef Str) { |
41 | 92 | // TODO: Get rid of magic number 4. It it NVPTX's constant address space and |
42 | 92 | // works on X86 (CPU) only because its backend ignores the address space. |
43 | 92 | return Builder.CreateGlobalStringPtr(Str, "", 4); |
44 | 92 | } |
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 | 36 | static void createCPUPrinter(PollyIRBuilder &Builder, Args... args) { |
66 | 36 | std::vector<llvm::Value *> Vector; |
67 | 36 | createPrinter(Builder, /* CPU */ false, Vector, args...); |
68 | 36 | } void polly::RuntimeDebugBuilder::createCPUPrinter<char const*, llvm::Value*, char const*, llvm::Value*, char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, char const*, llvm::Value*, char const*, llvm::Value*, char const*) Line | Count | Source | 65 | 6 | static void createCPUPrinter(PollyIRBuilder &Builder, Args... args) { | 66 | 6 | std::vector<llvm::Value *> Vector; | 67 | 6 | createPrinter(Builder, /* CPU */ false, Vector, args...); | 68 | 6 | } |
void polly::RuntimeDebugBuilder::createCPUPrinter<llvm::ArrayRef<llvm::Value*> >(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, llvm::ArrayRef<llvm::Value*>) Line | Count | Source | 65 | 1 | static void createCPUPrinter(PollyIRBuilder &Builder, Args... args) { | 66 | 1 | std::vector<llvm::Value *> Vector; | 67 | 1 | createPrinter(Builder, /* CPU */ false, Vector, args...); | 68 | 1 | } |
void polly::RuntimeDebugBuilder::createCPUPrinter<char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, char const*) Line | Count | Source | 65 | 18 | static void createCPUPrinter(PollyIRBuilder &Builder, Args... args) { | 66 | 18 | std::vector<llvm::Value *> Vector; | 67 | 18 | createPrinter(Builder, /* CPU */ false, Vector, args...); | 68 | 18 | } |
void polly::RuntimeDebugBuilder::createCPUPrinter<char const*, llvm::Value*, char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, char const*, llvm::Value*, char const*) Line | Count | Source | 65 | 6 | static void createCPUPrinter(PollyIRBuilder &Builder, Args... args) { | 66 | 6 | std::vector<llvm::Value *> Vector; | 67 | 6 | createPrinter(Builder, /* CPU */ false, Vector, args...); | 68 | 6 | } |
Unexecuted instantiation: void polly::RuntimeDebugBuilder::createCPUPrinter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, llvm::Value*, char const*, llvm::Value*, char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, llvm::Value*, char const*, llvm::Value*, char const*) void polly::RuntimeDebugBuilder::createCPUPrinter<llvm::StringRef, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, llvm::Value*, char const*, llvm::Value*, char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, llvm::StringRef, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, llvm::Value*, char const*, llvm::Value*, char const*) Line | Count | Source | 65 | 5 | static void createCPUPrinter(PollyIRBuilder &Builder, Args... args) { | 66 | 5 | std::vector<llvm::Value *> Vector; | 67 | 5 | createPrinter(Builder, /* CPU */ false, Vector, args...); | 68 | 5 | } |
|
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 | 28 | llvm::Value *Value, Args... args) { |
93 | 28 | Values.push_back(Value); |
94 | 28 | createPrinter(Builder, UseGPU, Values, args...); |
95 | 28 | } void polly::RuntimeDebugBuilder::createPrinter<char const*, llvm::Value*, char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, bool, std::__1::vector<llvm::Value*, std::__1::allocator<llvm::Value*> >&, llvm::Value*, char const*, llvm::Value*, char const*) Line | Count | Source | 92 | 11 | llvm::Value *Value, Args... args) { | 93 | 11 | Values.push_back(Value); | 94 | 11 | createPrinter(Builder, UseGPU, Values, args...); | 95 | 11 | } |
void polly::RuntimeDebugBuilder::createPrinter<char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, bool, std::__1::vector<llvm::Value*, std::__1::allocator<llvm::Value*> >&, llvm::Value*, char const*) Line | Count | Source | 92 | 17 | llvm::Value *Value, Args... args) { | 93 | 17 | Values.push_back(Value); | 94 | 17 | createPrinter(Builder, UseGPU, Values, args...); | 95 | 17 | } |
|
96 | | |
97 | | /// Handle StringRefs. |
98 | | template <typename... Args> |
99 | | static void createPrinter(PollyIRBuilder &Builder, bool UseGPU, |
100 | | std::vector<llvm::Value *> &Values, |
101 | 88 | llvm::StringRef String, Args... args) { |
102 | 88 | Values.push_back(getPrintableString(Builder, String)); |
103 | 88 | createPrinter(Builder, UseGPU, Values, args...); |
104 | 88 | } void polly::RuntimeDebugBuilder::createPrinter<llvm::Value*, char const*, llvm::Value*, char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, bool, std::__1::vector<llvm::Value*, std::__1::allocator<llvm::Value*> >&, llvm::StringRef, llvm::Value*, char const*, llvm::Value*, char const*) Line | Count | Source | 101 | 11 | llvm::StringRef String, Args... args) { | 102 | 11 | Values.push_back(getPrintableString(Builder, String)); | 103 | 11 | createPrinter(Builder, UseGPU, Values, args...); | 104 | 11 | } |
void polly::RuntimeDebugBuilder::createPrinter<llvm::Value*, char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, bool, std::__1::vector<llvm::Value*, std::__1::allocator<llvm::Value*> >&, llvm::StringRef, llvm::Value*, char const*) Line | Count | Source | 101 | 17 | llvm::StringRef String, Args... args) { | 102 | 17 | Values.push_back(getPrintableString(Builder, String)); | 103 | 17 | createPrinter(Builder, UseGPU, Values, args...); | 104 | 17 | } |
void polly::RuntimeDebugBuilder::createPrinter<>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, bool, std::__1::vector<llvm::Value*, std::__1::allocator<llvm::Value*> >&, llvm::StringRef) Line | Count | Source | 101 | 35 | llvm::StringRef String, Args... args) { | 102 | 35 | Values.push_back(getPrintableString(Builder, String)); | 103 | 35 | createPrinter(Builder, UseGPU, Values, args...); | 104 | 35 | } |
void polly::RuntimeDebugBuilder::createPrinter<char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, llvm::Value*, char const*, llvm::Value*, char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, bool, std::__1::vector<llvm::Value*, std::__1::allocator<llvm::Value*> >&, llvm::StringRef, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, llvm::Value*, char const*, llvm::Value*, char const*) Line | Count | Source | 101 | 5 | llvm::StringRef String, Args... args) { | 102 | 5 | Values.push_back(getPrintableString(Builder, String)); | 103 | 5 | createPrinter(Builder, UseGPU, Values, args...); | 104 | 5 | } |
void polly::RuntimeDebugBuilder::createPrinter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, llvm::Value*, char const*, llvm::Value*, char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, bool, std::__1::vector<llvm::Value*, std::__1::allocator<llvm::Value*> >&, llvm::StringRef, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, llvm::Value*, char const*, llvm::Value*, char const*) Line | Count | Source | 101 | 5 | llvm::StringRef String, Args... args) { | 102 | 5 | Values.push_back(getPrintableString(Builder, String)); | 103 | 5 | createPrinter(Builder, UseGPU, Values, args...); | 104 | 5 | } |
void polly::RuntimeDebugBuilder::createPrinter<char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, llvm::Value*, char const*, llvm::Value*, char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, bool, std::__1::vector<llvm::Value*, std::__1::allocator<llvm::Value*> >&, llvm::StringRef, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, llvm::Value*, char const*, llvm::Value*, char const*) Line | Count | Source | 101 | 5 | llvm::StringRef String, Args... args) { | 102 | 5 | Values.push_back(getPrintableString(Builder, String)); | 103 | 5 | createPrinter(Builder, UseGPU, Values, args...); | 104 | 5 | } |
void polly::RuntimeDebugBuilder::createPrinter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, llvm::Value*, char const*, llvm::Value*, char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, bool, std::__1::vector<llvm::Value*, std::__1::allocator<llvm::Value*> >&, llvm::StringRef, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, llvm::Value*, char const*, llvm::Value*, char const*) Line | Count | Source | 101 | 5 | llvm::StringRef String, Args... args) { | 102 | 5 | Values.push_back(getPrintableString(Builder, String)); | 103 | 5 | createPrinter(Builder, UseGPU, Values, args...); | 104 | 5 | } |
void polly::RuntimeDebugBuilder::createPrinter<char const*, llvm::Value*, char const*, llvm::Value*, char const*>(llvm::IRBuilder<llvm::ConstantFolder, polly::IRInserter>&, bool, std::__1::vector<llvm::Value*, std::__1::allocator<llvm::Value*> >&, llvm::StringRef, char const*, llvm::Value*, char const*, llvm::Value*, char const*) Line | Count | Source | 101 | 5 | llvm::StringRef String, Args... args) { | 102 | 5 | Values.push_back(getPrintableString(Builder, String)); | 103 | 5 | createPrinter(Builder, UseGPU, Values, args...); | 104 | 5 | } |
|
105 | | |
106 | | /// Handle ArrayRefs. |
107 | | template <typename... Args> |
108 | | static void createPrinter(PollyIRBuilder &Builder, bool UseGPU, |
109 | | std::vector<llvm::Value *> &Values, |
110 | 1 | llvm::ArrayRef<llvm::Value *> Array, Args... args) { |
111 | 1 | Values.insert(Values.end(), Array.begin(), Array.end()); |
112 | 1 | createPrinter(Builder, UseGPU, Values, args...); |
113 | 1 | } |
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 |