Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  170.