HLModule.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // HLModule.h //
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. // This file is distributed under the University of Illinois Open Source //
  6. // License. See LICENSE.TXT for details. //
  7. // //
  8. // HighLevel DX IR module. //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #pragma once
  12. #include "dxc/Support/Global.h"
  13. #include "dxc/HLSL/DxilMetadataHelper.h"
  14. #include "dxc/HLSL/DxilConstants.h"
  15. #include "dxc/HLSL/HLResource.h"
  16. #include "dxc/HLSL/HLOperations.h"
  17. #include "dxc/HLSL/DxilSampler.h"
  18. #include "dxc/HLSL/DxilShaderModel.h"
  19. #include "dxc/HLSL/DxilSignature.h"
  20. #include "dxc/HLSL/DxilFunctionProps.h"
  21. #include <memory>
  22. #include <string>
  23. #include <vector>
  24. #include <unordered_map>
  25. namespace llvm {
  26. class LLVMContext;
  27. class Module;
  28. class Function;
  29. class Instruction;
  30. class CallInst;
  31. class MDTuple;
  32. class MDNode;
  33. class GlobalVariable;
  34. class DIGlobalVariable;
  35. class DebugInfoFinder;
  36. };
  37. namespace hlsl {
  38. class ShaderModel;
  39. class OP;
  40. class RootSignatureHandle;
  41. struct HLOptions {
  42. HLOptions()
  43. : bDefaultRowMajor(false), bIEEEStrict(false), bDisableOptimizations(false),
  44. bLegacyCBufferLoad(false), PackingStrategy(0), unused(0) {
  45. }
  46. uint32_t GetHLOptionsRaw() const;
  47. void SetHLOptionsRaw(uint32_t data);
  48. unsigned bDefaultRowMajor : 1;
  49. unsigned bIEEEStrict : 1;
  50. unsigned bAllResourcesBound : 1;
  51. unsigned bDisableOptimizations : 1;
  52. unsigned bLegacyCBufferLoad : 1;
  53. unsigned PackingStrategy : 2;
  54. static_assert((unsigned)DXIL::PackingStrategy::Invalid < 4, "otherwise 2 bits is not enough to store PackingStrategy");
  55. unsigned bUseMinPrecision : 1;
  56. unsigned unused : 24;
  57. };
  58. /// Use this class to manipulate HLDXIR of a shader.
  59. class HLModule {
  60. public:
  61. HLModule(llvm::Module *pModule);
  62. ~HLModule();
  63. using Domain = DXIL::TessellatorDomain;
  64. // Subsystems.
  65. llvm::LLVMContext &GetCtx() const;
  66. llvm::Module *GetModule() const;
  67. OP *GetOP() const;
  68. void SetShaderModel(const ShaderModel *pSM);
  69. const ShaderModel *GetShaderModel() const;
  70. void SetValidatorVersion(unsigned ValMajor, unsigned ValMinor);
  71. void GetValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const;
  72. // HLOptions
  73. void SetHLOptions(HLOptions &opts);
  74. const HLOptions &GetHLOptions() const;
  75. // Entry function.
  76. llvm::Function *GetEntryFunction() const;
  77. void SetEntryFunction(llvm::Function *pEntryFunc);
  78. const std::string &GetEntryFunctionName() const;
  79. void SetEntryFunctionName(const std::string &name);
  80. llvm::Function *GetPatchConstantFunction();
  81. // Resources.
  82. unsigned AddCBuffer(std::unique_ptr<DxilCBuffer> pCB);
  83. DxilCBuffer &GetCBuffer(unsigned idx);
  84. const DxilCBuffer &GetCBuffer(unsigned idx) const;
  85. const std::vector<std::unique_ptr<DxilCBuffer> > &GetCBuffers() const;
  86. unsigned AddSampler(std::unique_ptr<DxilSampler> pSampler);
  87. DxilSampler &GetSampler(unsigned idx);
  88. const DxilSampler &GetSampler(unsigned idx) const;
  89. const std::vector<std::unique_ptr<DxilSampler> > &GetSamplers() const;
  90. unsigned AddSRV(std::unique_ptr<HLResource> pSRV);
  91. HLResource &GetSRV(unsigned idx);
  92. const HLResource &GetSRV(unsigned idx) const;
  93. const std::vector<std::unique_ptr<HLResource> > &GetSRVs() const;
  94. unsigned AddUAV(std::unique_ptr<HLResource> pUAV);
  95. HLResource &GetUAV(unsigned idx);
  96. const HLResource &GetUAV(unsigned idx) const;
  97. const std::vector<std::unique_ptr<HLResource> > &GetUAVs() const;
  98. void RemoveGlobal(llvm::GlobalVariable *GV);
  99. void RemoveFunction(llvm::Function *F);
  100. void RemoveResources(llvm::GlobalVariable **ppVariables, unsigned count);
  101. // ThreadGroupSharedMemory.
  102. typedef std::vector<llvm::GlobalVariable*>::iterator tgsm_iterator;
  103. tgsm_iterator tgsm_begin();
  104. tgsm_iterator tgsm_end();
  105. void AddGroupSharedVariable(llvm::GlobalVariable *GV);
  106. // Signatures.
  107. RootSignatureHandle &GetRootSignature();
  108. // DxilFunctionProps.
  109. bool HasDxilFunctionProps(llvm::Function *F);
  110. DxilFunctionProps &GetDxilFunctionProps(llvm::Function *F);
  111. void AddDxilFunctionProps(llvm::Function *F, std::unique_ptr<DxilFunctionProps> &info);
  112. DxilFunctionAnnotation *GetFunctionAnnotation(llvm::Function *F);
  113. DxilFunctionAnnotation *AddFunctionAnnotation(llvm::Function *F);
  114. DxilFunctionAnnotation *AddFunctionAnnotationWithFPDenormMode(llvm::Function *F, DXIL::FPDenormMode mode);
  115. void AddResourceTypeAnnotation(llvm::Type *Ty, DXIL::ResourceClass resClass,
  116. DXIL::ResourceKind kind);
  117. DXIL::ResourceClass GetResourceClass(llvm::Type *Ty);
  118. DXIL::ResourceKind GetResourceKind(llvm::Type *Ty);
  119. // Float Denorm mode.
  120. void SetFPDenormMode(const DXIL::FPDenormMode mode);
  121. DXIL::FPDenormMode GetFPDenormMode() const;
  122. // HLDXIR metadata manipulation.
  123. /// Serialize HLDXIR in-memory form to metadata form.
  124. void EmitHLMetadata();
  125. /// Deserialize HLDXIR metadata form into in-memory form.
  126. void LoadHLMetadata();
  127. /// Delete any HLDXIR from the specified module.
  128. static void ClearHLMetadata(llvm::Module &M);
  129. /// Create Metadata from a resource.
  130. llvm::MDNode *DxilSamplerToMDNode(const DxilSampler &S);
  131. llvm::MDNode *DxilSRVToMDNode(const DxilResource &SRV);
  132. llvm::MDNode *DxilUAVToMDNode(const DxilResource &UAV);
  133. llvm::MDNode *DxilCBufferToMDNode(const DxilCBuffer &CB);
  134. void LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD, DxilResourceBase &R);
  135. void AddResourceWithGlobalVariableAndMDNode(llvm::Constant *GV,
  136. llvm::MDNode *MD);
  137. // Type related methods.
  138. static bool IsStreamOutputPtrType(llvm::Type *Ty);
  139. static bool IsStreamOutputType(llvm::Type *Ty);
  140. static bool IsHLSLObjectType(llvm::Type *Ty);
  141. static void GetParameterRowsAndCols(llvm::Type *Ty, unsigned &rows, unsigned &cols,
  142. DxilParameterAnnotation &paramAnnotation);
  143. static const char *GetLegacyDataLayoutDesc();
  144. static const char *GetNewDataLayoutDesc();
  145. static void MergeGepUse(llvm::Value *V);
  146. // HL code gen.
  147. template<class BuilderTy>
  148. static llvm::CallInst *EmitHLOperationCall(BuilderTy &Builder,
  149. HLOpcodeGroup group, unsigned opcode,
  150. llvm::Type *RetType,
  151. llvm::ArrayRef<llvm::Value *> paramList,
  152. llvm::Module &M);
  153. static unsigned FindCastOp(bool fromUnsigned, bool toUnsigned,
  154. llvm::Type *SrcTy, llvm::Type *DstTy);
  155. // Precise attribute.
  156. // Note: Precise will be marked on alloca inst with metadata in code gen.
  157. // But mem2reg will remove alloca inst, so need mark precise with
  158. // function call before mem2reg.
  159. static bool HasPreciseAttributeWithMetadata(llvm::Instruction *I);
  160. static void MarkPreciseAttributeWithMetadata(llvm::Instruction *I);
  161. static void ClearPreciseAttributeWithMetadata(llvm::Instruction *I);
  162. static void MarkPreciseAttributeOnPtrWithFunctionCall(llvm::Value *Ptr,
  163. llvm::Module &M);
  164. static bool HasPreciseAttribute(llvm::Function *F);
  165. // Resource attribute.
  166. static void MarkDxilResourceAttrib(llvm::Function *F, llvm::MDNode *MD);
  167. static llvm::MDNode *GetDxilResourceAttrib(llvm::Function *F);
  168. void MarkDxilResourceAttrib(llvm::Argument *Arg, llvm::MDNode *MD);
  169. llvm::MDNode *GetDxilResourceAttrib(llvm::Argument *Arg);
  170. static llvm::MDNode *GetDxilResourceAttrib(llvm::Type *Ty, llvm::Module &M);
  171. // DXIL type system.
  172. DxilTypeSystem &GetTypeSystem();
  173. /// Emit llvm.used array to make sure that optimizations do not remove unreferenced globals.
  174. void EmitLLVMUsed();
  175. std::vector<llvm::GlobalVariable* > &GetLLVMUsed();
  176. // Release functions used to transfer ownership.
  177. DxilTypeSystem *ReleaseTypeSystem();
  178. OP *ReleaseOP();
  179. RootSignatureHandle *ReleaseRootSignature();
  180. std::unordered_map<llvm::Function *, std::unique_ptr<DxilFunctionProps>> &&
  181. ReleaseFunctionPropsMap();
  182. llvm::DebugInfoFinder &GetOrCreateDebugInfoFinder();
  183. static llvm::DIGlobalVariable *
  184. FindGlobalVariableDebugInfo(llvm::GlobalVariable *GV,
  185. llvm::DebugInfoFinder &DbgInfoFinder);
  186. // Create global variable debug info for element global variable based on the
  187. // whole global variable.
  188. static void CreateElementGlobalVariableDebugInfo(
  189. llvm::GlobalVariable *GV, llvm::DebugInfoFinder &DbgInfoFinder,
  190. llvm::GlobalVariable *EltGV, unsigned sizeInBits, unsigned alignInBits,
  191. unsigned offsetInBits, llvm::StringRef eltName);
  192. // Replace GV with NewGV in GlobalVariable debug info.
  193. static void
  194. UpdateGlobalVariableDebugInfo(llvm::GlobalVariable *GV,
  195. llvm::DebugInfoFinder &DbgInfoFinder,
  196. llvm::GlobalVariable *NewGV);
  197. private:
  198. // Signatures.
  199. std::unique_ptr<RootSignatureHandle> m_RootSignature;
  200. // Shader resources.
  201. std::vector<std::unique_ptr<HLResource> > m_SRVs;
  202. std::vector<std::unique_ptr<HLResource> > m_UAVs;
  203. std::vector<std::unique_ptr<DxilCBuffer> > m_CBuffers;
  204. std::vector<std::unique_ptr<DxilSampler> > m_Samplers;
  205. // ThreadGroupSharedMemory.
  206. std::vector<llvm::GlobalVariable*> m_TGSMVariables;
  207. // High level function info.
  208. std::unordered_map<llvm::Function *, std::unique_ptr<DxilFunctionProps>> m_DxilFunctionPropsMap;
  209. // Resource type annotation.
  210. std::unordered_map<llvm::Type *, std::pair<DXIL::ResourceClass, DXIL::ResourceKind>> m_ResTypeAnnotation;
  211. private:
  212. llvm::LLVMContext &m_Ctx;
  213. llvm::Module *m_pModule;
  214. llvm::Function *m_pEntryFunc;
  215. std::string m_EntryName;
  216. std::unique_ptr<DxilMDHelper> m_pMDHelper;
  217. std::unique_ptr<llvm::DebugInfoFinder> m_pDebugInfoFinder;
  218. const ShaderModel *m_pSM;
  219. unsigned m_DxilMajor;
  220. unsigned m_DxilMinor;
  221. unsigned m_ValMajor;
  222. unsigned m_ValMinor;
  223. DXIL::FPDenormMode m_FPDenormMode;
  224. HLOptions m_Options;
  225. std::unique_ptr<OP> m_pOP;
  226. size_t m_pUnused;
  227. // DXIL metadata serialization/deserialization.
  228. llvm::MDTuple *EmitHLResources();
  229. void LoadHLResources(const llvm::MDOperand &MDO);
  230. llvm::MDTuple *EmitHLShaderProperties();
  231. void LoadHLShaderProperties(const llvm::MDOperand &MDO);
  232. llvm::MDTuple *EmitDxilShaderProperties();
  233. llvm::MDTuple *EmitResTyAnnotations();
  234. void LoadResTyAnnotations(const llvm::MDOperand &MDO);
  235. // LLVM used.
  236. std::vector<llvm::GlobalVariable*> m_LLVMUsed;
  237. // Type annotations.
  238. std::unique_ptr<DxilTypeSystem> m_pTypeSystem;
  239. // Helpers.
  240. template<typename T> unsigned AddResource(std::vector<std::unique_ptr<T> > &Vec, std::unique_ptr<T> pRes);
  241. };
  242. /// Use this class to manipulate metadata of extra metadata record properties that are specific to high-level DX IR.
  243. class HLExtraPropertyHelper : public DxilExtraPropertyHelper {
  244. public:
  245. HLExtraPropertyHelper(llvm::Module *pModule);
  246. virtual ~HLExtraPropertyHelper() {}
  247. virtual void EmitSignatureElementProperties(const DxilSignatureElement &SE, std::vector<llvm::Metadata *> &MDVals);
  248. virtual void LoadSignatureElementProperties(const llvm::MDOperand &MDO, DxilSignatureElement &SE);
  249. };
  250. } // namespace hlsl