1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2017-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #pragma once
10 
11 #include "common/Types.hpp"
12 
13 #include "AdaptorCommon/customApi.hpp"
14 #include "Compiler/CodeGenPublicEnums.h"
15 
16 #include <iStdLib/utility.h>
17 
18 #include "common/LLVMWarningsPush.hpp"
19 #include <llvm/Support/raw_ostream.h>
20 #include <llvm/IR/Module.h>
21 #include <llvm/ADT/Optional.h>
22 #include <llvm/Pass.h>
23 #include "common/LLVMWarningsPop.hpp"
24 #include "AdaptorCommon/API/igc.h"
25 
26 #include <string>
27 #include <vector>
28 #include <stdarg.h>
29 #include <mutex>
30 
31 // Forward declarations
32 struct D3D10DDIARG_SIGNATURE_ENTRY;
33 struct D3D10DDIARG_STAGE_IO_SIGNATURES;
34 struct D3D11DDIARG_TESSELLATION_IO_SIGNATURES;
35 namespace IGC { class CodeGenContext; }
36 
37 namespace USC
38 {
39     struct ShaderD3D;
40     struct SPixelShaderNOS;
41     struct SVertexShaderNOS;
42 }
43 
44 namespace IGC
45 {
46 class CShader;
47 namespace Debug
48 {
49 
50 /*************************************************************************************************\
51  *  Generic
52  */
53 
54 class DumpName
55 {
56 public:
57     explicit DumpName(std::string const& dumpName);
58     DumpName();
59 
60     //Needs to be static so that all objects of the class share it and public so that all derived classes have access to it.
61     static std::mutex hashMapLock;
62     static unsigned int shaderNum;
63 
64     DumpName ShaderName(std::string const& name) const;
65     DumpName Type(ShaderType type) const;
66     DumpName Extension(std::string const& extension) const;
67     DumpName StagedInfo(void const* context) const;
68     DumpName SIMDSize(SIMDMode width) const;
69     DumpName DispatchMode(ShaderDispatchMode mode) const;
70     DumpName Hash(ShaderHash hash) const;
71     DumpName PostFix(std::string const& postfixStr) const;
72     DumpName Pass(std::string const& name, llvm::Optional<uint32_t> index = llvm::Optional<uint32_t>()) const;
73     DumpName PSPhase(PixelShaderPhaseType phase) const;
74     DumpName Retry(unsigned retryId) const;
75     std::string str() const;
76     std::string overridePath() const;
77     std::string RelativePath() const;
78     std::string AbsolutePath(OutputFolderName folder) const;
79     std::string GetKernelName() const;
80     bool allow() const;
81 
82 private:
83     class CPassDescriptor
84     {
85     public:
86         std::string               m_name;
87         llvm::Optional<unsigned int>    m_index;
88     };
89 
90     llvm::Optional<std::string>         m_dumpName;
91     llvm::Optional<std::string>         m_shaderName;
92     llvm::Optional<ShaderType>          m_type;
93     llvm::Optional<PixelShaderPhaseType> m_psPhase;
94     llvm::Optional<std::string>         m_extension;
95     llvm::Optional<SIMDMode>            m_simdWidth;
96     llvm::Optional<CG_FLAG_t>           m_cgFlag;
97     llvm::Optional<ShaderDispatchMode>  m_ShaderMode;
98     llvm::Optional<ShaderHash>          m_hash;
99     llvm::Optional<std::string>         m_postfixStr;
100     llvm::Optional<CPassDescriptor>     m_pass;
101     llvm::Optional<unsigned>            m_retryId;
102 };
103 
104 /// return the name of the file to dump
105 std::string GetDumpName(const CShader* pProgram, const char* ext);
106 
107 /// return the name of the file to dump
108 DumpName GetDumpNameObj(const CShader* pProgram, const char* ext);
109 
110 /// return the name of the file to dump for llvm IR
111 DumpName GetLLDumpName(IGC::CodeGenContext* pContext, const char* dumpName);
112 
113 class Dump
114 {
115 public:
116     Dump( DumpName const& dumpName, DumpType type );
117     virtual ~Dump();
118 
119     llvm::raw_ostream& stream() const;
120 
121     void flush();
122 
123     template<typename T>
operator <<(T const & val) const124     llvm::raw_ostream& operator<< ( T const& val ) const
125     {
126         stream() << val;
127         return stream();
128     }
129 
130 private:
131     std::string                        m_string;
132     const DumpName                     m_name;
133     std::unique_ptr<llvm::raw_ostream> m_pStream;
134     llvm::raw_ostream*                 m_pStringStream;
135     const DumpType                     m_type;
136     bool                               m_ClearFile;
137 };
138 
139 // Common implementation of the flush pass
140 template<typename PassT>
141 class CommonFlushDumpPass : public PassT
142 {
143 public:
144 
CommonFlushDumpPass(Dump & dump,char & pid)145     CommonFlushDumpPass(Dump& dump, char& pid) : PassT(pid), m_Dump(dump) {}
146 
getAnalysisUsage(llvm::AnalysisUsage & AU) const147     void getAnalysisUsage(llvm::AnalysisUsage& AU) const override
148     {
149         AU.setPreservesAll();
150     }
151 
getPassName() const152     llvm::StringRef getPassName() const override
153     {
154         return "Flush Dump";
155     }
156 
157 protected:
158     Dump& m_Dump;
159 };
160 
161 class ModuleFlushDumpPass : public CommonFlushDumpPass<llvm::ModulePass>
162 {
163 public:
164     static char ID;
165 
ModuleFlushDumpPass(Dump & dump)166     ModuleFlushDumpPass(Dump& dump) : CommonFlushDumpPass(dump, ID) {}
167 
runOnModule(llvm::Module &)168     bool runOnModule(llvm::Module&) override
169     {
170         m_Dump.flush();
171         return false;
172     }
173 };
174 
175 class FunctionFlushDumpPass : public CommonFlushDumpPass<llvm::FunctionPass>
176 {
177 public:
178     static char ID;
179 
FunctionFlushDumpPass(Dump & dump)180     FunctionFlushDumpPass(Dump& dump) : CommonFlushDumpPass(dump, ID) {}
181 
runOnFunction(llvm::Function &)182     bool runOnFunction(llvm::Function&) override
183     {
184         m_Dump.flush();
185         return false;
186     }
187 };
188 
189 void DumpLLVMIRText(
190     llvm::Module*             pModule,
191     const DumpName&           dumpName,
192     llvm::AssemblyAnnotationWriter*  optionalAnnotationWriter = nullptr);
193 
194 int PrintDebugMsgV(
195     const Dump* dump,
196     const char* fmt,
197     va_list ap);
198 
199 void PrintDebugMsg(
200     const Dump* dump,
201     const char* fmt,
202     ...);
203 
204 
OpenDumpFile(const char * fileNamePrefix,const char * fileNameExt,const ShaderHash & hash,const char * flag)205 inline FILE* OpenDumpFile(
206     const char* fileNamePrefix,
207     const char* fileNameExt,
208     const ShaderHash& hash,
209     const char* flag)
210 {
211     std::string name =
212         IGC::Debug::DumpName(fileNamePrefix)
213         .Hash(hash)
214         .Extension(fileNameExt)
215         .str();
216     FILE* fp = fopen(name.c_str(), flag);
217     return fp;
218 }
219 
220 ShaderHash ShaderHashOCL(const UINT* pShaderCode, size_t size);
221 
222 ShaderHash ShaderHashOGL(QWORD glslHash, QWORD nosHash);
223 
224 } // namespace Debug
225 } // namespace IGC
226