1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2020-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 //
10 // This file implements shader dumping facilities using standard IGC
11 // functionality like debug dumps and enviroment variables.
12 //
13 // IGC has debug dump type classification and some types are reused here
14 // to provide outputs. For now, these types are picked to produce correct
15 // output format for each type of dump:
16 //
17 //   ASM_BC -- general binary data;
18 //   DBG_MSG_TEXT -- general text data;
19 //   TRANSLATED_IR_TEXT -- LLVM IR text.
20 //
21 // XXX: above types can be revised to extend classification for general-
22 // purpose dump types without special semantics.
23 //
24 //===---------------------------------------------------------------------===//
25 
26 #include "vc/igcdeps/ShaderDump.h"
27 
28 #include <llvm/ADT/ArrayRef.h>
29 #include <llvm/ADT/StringRef.h>
30 #include <llvm/IR/Module.h>
31 #include <llvm/Support/Error.h>
32 #include <llvm/Support/FileSystem.h>
33 #include <llvm/Support/Path.h>
34 #include <llvm/Support/raw_ostream.h>
35 
36 #include <common/debug/Dump.hpp>
37 
38 #include <iomanip>
39 #include <sstream>
40 #include <string>
41 
42 namespace {
43 class VC_IGCFileDumper : public vc::ShaderDumper {
44   // Partially filled dump name.
45   IGC::Debug::DumpName DumpPrefix;
46 
47 public:
48   VC_IGCFileDumper(const ShaderHash &Hash);
49 
50   void dumpBinary(llvm::ArrayRef<char> Binary,
51                   llvm::StringRef DumpName) override;
52   void dumpText(llvm::StringRef Text, llvm::StringRef DumpName) override;
53 
54   void dumpModule(const llvm::Module &M, llvm::StringRef DumpName) override;
55 
56   void dumpCos(llvm::StringRef Contents, llvm::StringRef DumpName) override;
57 
58   std::string composeDumpPath(llvm::StringRef DumpName) const override;
59 
60 private:
61   template <IGC::Debug::DumpType DumpTy, typename F>
62   void writeToFile(llvm::StringRef DumpName, F Writer) const;
63 };
64 } // namespace
65 
VC_IGCFileDumper(const ShaderHash & Hash)66 VC_IGCFileDumper::VC_IGCFileDumper(const ShaderHash &Hash)
67     : DumpPrefix{IGC::Debug::DumpName("VC").Hash(Hash)} {}
68 
addDumpPostfix(const IGC::Debug::DumpName & Name,llvm::StringRef Postfix)69 static IGC::Debug::DumpName addDumpPostfix(const IGC::Debug::DumpName &Name,
70                                            llvm::StringRef Postfix) {
71   return Name.PostFix(Postfix.str());
72 }
73 
74 template <IGC::Debug::DumpType DumpTy, typename F>
writeToFile(llvm::StringRef DumpName,F Writer) const75 void VC_IGCFileDumper::writeToFile(llvm::StringRef DumpName, F Writer) const {
76   IGC::Debug::Dump Dumper{addDumpPostfix(DumpPrefix, DumpName), DumpTy};
77   Writer(Dumper.stream());
78 }
79 
dumpBinary(llvm::ArrayRef<char> Binary,llvm::StringRef DumpName)80 void VC_IGCFileDumper::dumpBinary(llvm::ArrayRef<char> Binary,
81                                   llvm::StringRef DumpName) {
82   writeToFile<IGC::Debug::DumpType::ASM_BC>(
83       DumpName, [Binary](llvm::raw_ostream &OS) {
84         OS.write(Binary.data(), Binary.size());
85       });
86 }
87 
dumpText(llvm::StringRef Text,llvm::StringRef DumpName)88 void VC_IGCFileDumper::dumpText(llvm::StringRef Text,
89                                 llvm::StringRef DumpName) {
90   writeToFile<IGC::Debug::DumpType::DBG_MSG_TEXT>(
91       DumpName, [Text](llvm::raw_ostream &OS) { OS << Text; });
92 }
93 
dumpModule(const llvm::Module & M,llvm::StringRef DumpName)94 void VC_IGCFileDumper::dumpModule(const llvm::Module &M,
95                                   llvm::StringRef DumpName) {
96   writeToFile<IGC::Debug::DumpType::TRANSLATED_IR_TEXT>(
97       DumpName, [&M](llvm::raw_ostream &OS) { M.print(OS, nullptr); });
98 }
99 
dumpCos(llvm::StringRef Contents,llvm::StringRef DumpName)100 void VC_IGCFileDumper::dumpCos(llvm::StringRef Contents,
101                                llvm::StringRef DumpName) {
102   writeToFile<IGC::Debug::DumpType::COS_TEXT>(
103       DumpName, [Contents](llvm::raw_ostream &OS) { OS << Contents; });
104 }
105 
composeDumpPath(llvm::StringRef DumpName) const106 std::string VC_IGCFileDumper::composeDumpPath(llvm::StringRef DumpName) const {
107   return addDumpPostfix(DumpPrefix, DumpName).str();
108 }
109 
110 namespace vc {
createVC_IGCFileDumper(const ShaderHash & Hash)111 std::unique_ptr<ShaderDumper> createVC_IGCFileDumper(const ShaderHash &Hash) {
112   return std::make_unique<VC_IGCFileDumper>(Hash);
113 }
114 } // namespace vc
115