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 createCPUPrinter().
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 
42   /// Return whether an llvm::Value of the type @p Ty is printable for
43   /// debugging.
44   ///
45   /// That is, whether such a value can be passed to createGPUPrinter()
46   /// to be dumped as runtime.  If false is returned, those
47   /// functions will fail.
48   static bool isPrintable(llvm::Type *Ty);
49 
50   /// Print a set of LLVM-IR Values or StringRefs via printf
51   ///
52   ///  This function emits a call to printf that will print the given arguments.
53   ///  It is useful for debugging CPU programs. All arguments given in this list
54   ///  will be automatically concatenated and the resulting string will be
55   ///  printed atomically. We also support ArrayRef arguments, which can be used
56   ///  to provide of id values.
57   ///
58   ///  @param Builder The builder used to emit the printer calls.
59   ///  @param Args    The list of values to print.
60   template <typename... Args>
createCPUPrinterRuntimeDebugBuilder61   static void createCPUPrinter(PollyIRBuilder &Builder, Args... args) {
62     std::vector<llvm::Value *> Vector;
63     createPrinter(Builder, Vector, args...);
64   }
65 
66 private:
67   /// Handle Values.
68   template <typename... Args>
createPrinterRuntimeDebugBuilder69   static void createPrinter(PollyIRBuilder &Builder,
70                             std::vector<llvm::Value *> &Values,
71                             llvm::Value *Value, Args... args) {
72     Values.push_back(Value);
73     createPrinter(Builder, Values, args...);
74   }
75 
76   /// Handle StringRefs.
77   template <typename... Args>
createPrinterRuntimeDebugBuilder78   static void createPrinter(PollyIRBuilder &Builder,
79                             std::vector<llvm::Value *> &Values,
80                             llvm::StringRef String, Args... args) {
81     Values.push_back(getPrintableString(Builder, String));
82     createPrinter(Builder, Values, args...);
83   }
84 
85   /// Handle ArrayRefs.
86   template <typename... Args>
createPrinterRuntimeDebugBuilder87   static void createPrinter(PollyIRBuilder &Builder,
88                             std::vector<llvm::Value *> &Values,
89                             llvm::ArrayRef<llvm::Value *> Array, Args... args) {
90     Values.insert(Values.end(), Array.begin(), Array.end());
91     createPrinter(Builder, Values, args...);
92   }
93 
94   /// Print a list of Values.
95   static void createPrinter(PollyIRBuilder &Builder,
96                             llvm::ArrayRef<llvm::Value *> Values);
97 
98   /// Print a list of Values on a CPU.
99   static void createCPUPrinterT(PollyIRBuilder &Builder,
100                                 llvm::ArrayRef<llvm::Value *> Values);
101 
102   /// Get a reference to the 'printf' function.
103   ///
104   /// If the current module does not yet contain a reference to printf, we
105   /// insert a reference to it. Otherwise the existing reference is returned.
106   static llvm::Function *getPrintF(PollyIRBuilder &Builder);
107 
108   /// Call printf
109   ///
110   /// @param Builder The builder used to insert the code.
111   /// @param Format  The format string.
112   /// @param Values  The set of values to print.
113   static void createPrintF(PollyIRBuilder &Builder, std::string Format,
114                            llvm::ArrayRef<llvm::Value *> Values);
115 
116   /// Get (and possibly insert) a vprintf declaration into the module.
117   static llvm::Function *getVPrintF(PollyIRBuilder &Builder);
118 
119   /// Call fflush
120   ///
121   /// @parma Builder The builder used to insert the code.
122   static void createFlush(PollyIRBuilder &Builder);
123 };
124 } // namespace polly
125 
126 extern bool PollyDebugPrinting;
127 
128 #endif
129