HLModule.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  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/DXIL/DxilMetadataHelper.h"
  14. #include "dxc/DXIL/DxilConstants.h"
  15. #include "dxc/HLSL/HLResource.h"
  16. #include "dxc/HLSL/HLOperations.h"
  17. #include "dxc/DXIL/DxilSampler.h"
  18. #include "dxc/DXIL/DxilShaderModel.h"
  19. #include "dxc/DXIL/DxilSignature.h"
  20. #include "dxc/DXIL/DxilFunctionProps.h"
  21. #include "dxc/DXIL/DxilSubobject.h"
  22. #include "dxc/DXIL/DxilResourceProperties.h"
  23. #include <memory>
  24. #include <string>
  25. #include <vector>
  26. #include <unordered_map>
  27. #include <unordered_set>
  28. namespace llvm {
  29. template<typename T> class ArrayRef;
  30. class LLVMContext;
  31. class Module;
  32. class Function;
  33. class Instruction;
  34. class CallInst;
  35. class MDTuple;
  36. class MDNode;
  37. class GlobalVariable;
  38. class DIGlobalVariable;
  39. class DebugInfoFinder;
  40. class GetElementPtrInst;
  41. }
  42. namespace hlsl {
  43. class ShaderModel;
  44. class OP;
  45. struct HLOptions {
  46. HLOptions()
  47. : bDefaultRowMajor(false), bIEEEStrict(false), bAllResourcesBound(false), bDisableOptimizations(false),
  48. bLegacyCBufferLoad(false), PackingStrategy(0), bUseMinPrecision(false), bDX9CompatMode(false),
  49. bFXCCompatMode(false), bLegacyResourceReservation(false), bForceZeroStoreLifetimes(false), unused(0) {
  50. }
  51. uint32_t GetHLOptionsRaw() const;
  52. void SetHLOptionsRaw(uint32_t data);
  53. unsigned bDefaultRowMajor : 1;
  54. unsigned bIEEEStrict : 1;
  55. unsigned bAllResourcesBound : 1;
  56. unsigned bDisableOptimizations : 1;
  57. unsigned bLegacyCBufferLoad : 1;
  58. unsigned PackingStrategy : 2;
  59. static_assert((unsigned)DXIL::PackingStrategy::Invalid < 4, "otherwise 2 bits is not enough to store PackingStrategy");
  60. unsigned bUseMinPrecision : 1;
  61. unsigned bDX9CompatMode : 1;
  62. unsigned bFXCCompatMode : 1;
  63. unsigned bLegacyResourceReservation : 1;
  64. unsigned bForceZeroStoreLifetimes : 1;
  65. unsigned unused : 20;
  66. };
  67. typedef std::unordered_map<const llvm::Function *, std::unique_ptr<DxilFunctionProps>> DxilFunctionPropsMap;
  68. /// Use this class to manipulate HLDXIR of a shader.
  69. class HLModule {
  70. public:
  71. HLModule(llvm::Module *pModule);
  72. ~HLModule();
  73. using Domain = DXIL::TessellatorDomain;
  74. // Subsystems.
  75. llvm::LLVMContext &GetCtx() const;
  76. llvm::Module *GetModule() const;
  77. OP *GetOP() const;
  78. void SetShaderModel(const ShaderModel *pSM);
  79. const ShaderModel *GetShaderModel() const;
  80. void SetValidatorVersion(unsigned ValMajor, unsigned ValMinor);
  81. void GetValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const;
  82. void SetForceZeroStoreLifetimes(bool ForceZeroStoreLifetimes);
  83. bool GetForceZeroStoreLifetimes() const;
  84. // HLOptions
  85. void SetHLOptions(HLOptions &opts);
  86. const HLOptions &GetHLOptions() const;
  87. // AutoBindingSpace also enables automatic binding for libraries if set.
  88. // UINT_MAX == unset
  89. void SetAutoBindingSpace(uint32_t Space);
  90. uint32_t GetAutoBindingSpace() const;
  91. // Entry function.
  92. llvm::Function *GetEntryFunction() const;
  93. void SetEntryFunction(llvm::Function *pEntryFunc);
  94. const std::string &GetEntryFunctionName() const;
  95. void SetEntryFunctionName(const std::string &name);
  96. llvm::Function *GetPatchConstantFunction();
  97. // Resources.
  98. unsigned AddCBuffer(std::unique_ptr<DxilCBuffer> pCB);
  99. DxilCBuffer &GetCBuffer(unsigned idx);
  100. const DxilCBuffer &GetCBuffer(unsigned idx) const;
  101. const std::vector<std::unique_ptr<DxilCBuffer> > &GetCBuffers() const;
  102. unsigned AddSampler(std::unique_ptr<DxilSampler> pSampler);
  103. DxilSampler &GetSampler(unsigned idx);
  104. const DxilSampler &GetSampler(unsigned idx) const;
  105. const std::vector<std::unique_ptr<DxilSampler> > &GetSamplers() const;
  106. unsigned AddSRV(std::unique_ptr<HLResource> pSRV);
  107. HLResource &GetSRV(unsigned idx);
  108. const HLResource &GetSRV(unsigned idx) const;
  109. const std::vector<std::unique_ptr<HLResource> > &GetSRVs() const;
  110. unsigned AddUAV(std::unique_ptr<HLResource> pUAV);
  111. HLResource &GetUAV(unsigned idx);
  112. const HLResource &GetUAV(unsigned idx) const;
  113. const std::vector<std::unique_ptr<HLResource> > &GetUAVs() const;
  114. void RemoveGlobal(llvm::GlobalVariable *GV);
  115. void RemoveFunction(llvm::Function *F);
  116. // ThreadGroupSharedMemory.
  117. typedef std::vector<llvm::GlobalVariable*>::iterator tgsm_iterator;
  118. tgsm_iterator tgsm_begin();
  119. tgsm_iterator tgsm_end();
  120. void AddGroupSharedVariable(llvm::GlobalVariable *GV);
  121. // Signatures.
  122. std::vector<uint8_t> &GetSerializedRootSignature();
  123. void SetSerializedRootSignature(const uint8_t *pData, unsigned size);
  124. // DxilFunctionProps.
  125. bool HasDxilFunctionProps(llvm::Function *F);
  126. DxilFunctionProps &GetDxilFunctionProps(llvm::Function *F);
  127. void AddDxilFunctionProps(llvm::Function *F, std::unique_ptr<DxilFunctionProps> &info);
  128. void SetPatchConstantFunctionForHS(llvm::Function *hullShaderFunc, llvm::Function *patchConstantFunc);
  129. bool IsGraphicsShader(llvm::Function *F); // vs,hs,ds,gs,ps
  130. bool IsPatchConstantShader(llvm::Function *F);
  131. bool IsComputeShader(llvm::Function *F);
  132. // Is an entry function that uses input/output signature conventions?
  133. // Includes: vs/hs/ds/gs/ps/cs as well as the patch constant function.
  134. bool IsEntryThatUsesSignatures(llvm::Function *F);
  135. // Is F an entry?
  136. // Includes: IsEntryThatUsesSignatures and all ray tracing shaders.
  137. bool IsEntry(llvm::Function *F);
  138. DxilFunctionAnnotation *GetFunctionAnnotation(llvm::Function *F);
  139. DxilFunctionAnnotation *AddFunctionAnnotation(llvm::Function *F);
  140. // Float Denorm mode.
  141. void SetFloat32DenormMode(const DXIL::Float32DenormMode mode);
  142. DXIL::Float32DenormMode GetFloat32DenormMode() const;
  143. // Default function linkage for libraries
  144. DXIL::DefaultLinkage GetDefaultLinkage() const;
  145. void SetDefaultLinkage(const DXIL::DefaultLinkage linkage);
  146. // HLDXIR metadata manipulation.
  147. /// Serialize HLDXIR in-memory form to metadata form.
  148. void EmitHLMetadata();
  149. /// Deserialize HLDXIR metadata form into in-memory form.
  150. void LoadHLMetadata();
  151. /// Delete any HLDXIR from the specified module.
  152. static void ClearHLMetadata(llvm::Module &M);
  153. /// Create Metadata from a resource.
  154. llvm::MDNode *DxilSamplerToMDNode(const DxilSampler &S);
  155. llvm::MDNode *DxilSRVToMDNode(const DxilResource &SRV);
  156. llvm::MDNode *DxilUAVToMDNode(const DxilResource &UAV);
  157. llvm::MDNode *DxilCBufferToMDNode(const DxilCBuffer &CB);
  158. void LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD, DxilResourceBase &R);
  159. void LoadDxilResourceFromMDNode(llvm::MDNode *MD, DxilResource &R);
  160. void LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S);
  161. DxilResourceBase *
  162. AddResourceWithGlobalVariableAndProps(llvm::Constant *GV,
  163. DxilResourceProperties &RP);
  164. unsigned GetBindingForResourceInCB(llvm::GetElementPtrInst *CbPtr,
  165. llvm::GlobalVariable *CbGV,
  166. DXIL::ResourceClass RC);
  167. // Type related methods.
  168. static bool IsStreamOutputPtrType(llvm::Type *Ty);
  169. static bool IsStreamOutputType(llvm::Type *Ty);
  170. static void GetParameterRowsAndCols(llvm::Type *Ty, unsigned &rows, unsigned &cols,
  171. DxilParameterAnnotation &paramAnnotation);
  172. static void MergeGepUse(llvm::Value *V);
  173. // HL code gen.
  174. template<class BuilderTy>
  175. static llvm::CallInst *EmitHLOperationCall(BuilderTy &Builder,
  176. HLOpcodeGroup group, unsigned opcode,
  177. llvm::Type *RetType,
  178. llvm::ArrayRef<llvm::Value *> paramList,
  179. llvm::Module &M);
  180. // Caller must handle conversions to bool and no-ops
  181. static unsigned GetNumericCastOp(
  182. llvm::Type *SrcTy, bool SrcIsUnsigned, llvm::Type *DstTy, bool DstIsUnsigned);
  183. // Precise attribute.
  184. // Note: Precise will be marked on alloca inst with metadata in code gen.
  185. // But mem2reg will remove alloca inst, so need mark precise with
  186. // function call before mem2reg.
  187. static bool HasPreciseAttributeWithMetadata(llvm::Instruction *I);
  188. static void MarkPreciseAttributeWithMetadata(llvm::Instruction *I);
  189. static void ClearPreciseAttributeWithMetadata(llvm::Instruction *I);
  190. template<class BuilderTy>
  191. static void MarkPreciseAttributeOnValWithFunctionCall(llvm::Value *V,
  192. BuilderTy &Builder, llvm::Module &M);
  193. static void MarkPreciseAttributeOnPtrWithFunctionCall(llvm::Value *Ptr,
  194. llvm::Module &M);
  195. static bool HasPreciseAttribute(llvm::Function *F);
  196. // DXIL type system.
  197. DxilTypeSystem &GetTypeSystem();
  198. /// Emit llvm.used array to make sure that optimizations do not remove unreferenced globals.
  199. void EmitLLVMUsed();
  200. std::vector<llvm::GlobalVariable* > &GetLLVMUsed();
  201. // Release functions used to transfer ownership.
  202. DxilTypeSystem *ReleaseTypeSystem();
  203. OP *ReleaseOP();
  204. DxilFunctionPropsMap &&ReleaseFunctionPropsMap();
  205. llvm::DebugInfoFinder &GetOrCreateDebugInfoFinder();
  206. // Create global variable debug info for element global variable based on the
  207. // whole global variable.
  208. static void CreateElementGlobalVariableDebugInfo(
  209. llvm::GlobalVariable *GV, llvm::DebugInfoFinder &DbgInfoFinder,
  210. llvm::GlobalVariable *EltGV, unsigned sizeInBits, unsigned alignInBits,
  211. unsigned offsetInBits, llvm::StringRef eltName);
  212. // Replace GV with NewGV in GlobalVariable debug info.
  213. static void
  214. UpdateGlobalVariableDebugInfo(llvm::GlobalVariable *GV,
  215. llvm::DebugInfoFinder &DbgInfoFinder,
  216. llvm::GlobalVariable *NewGV);
  217. DxilSubobjects *GetSubobjects();
  218. const DxilSubobjects *GetSubobjects() const;
  219. DxilSubobjects *ReleaseSubobjects();
  220. void ResetSubobjects(DxilSubobjects *subobjects);
  221. // Reg binding for resource in cb.
  222. void AddRegBinding(unsigned CbID, unsigned ConstantIdx, unsigned Srv, unsigned Uav, unsigned Sampler);
  223. private:
  224. // Signatures.
  225. std::vector<uint8_t> m_SerializedRootSignature;
  226. // Shader resources.
  227. std::vector<std::unique_ptr<HLResource> > m_SRVs;
  228. std::vector<std::unique_ptr<HLResource> > m_UAVs;
  229. std::vector<std::unique_ptr<DxilCBuffer> > m_CBuffers;
  230. std::vector<std::unique_ptr<DxilSampler> > m_Samplers;
  231. // ThreadGroupSharedMemory.
  232. std::vector<llvm::GlobalVariable*> m_TGSMVariables;
  233. // High level function info.
  234. std::unordered_map<const llvm::Function *, std::unique_ptr<DxilFunctionProps>> m_DxilFunctionPropsMap;
  235. std::unordered_set<llvm::Function *> m_PatchConstantFunctions;
  236. // Resource bindings for res in cb.
  237. // Key = CbID << 32 | ConstantIdx. Val is reg binding.
  238. std::unordered_map<uint64_t, unsigned> m_SrvBindingInCB;
  239. std::unordered_map<uint64_t, unsigned> m_UavBindingInCB;
  240. std::unordered_map<uint64_t, unsigned> m_SamplerBindingInCB;
  241. private:
  242. llvm::LLVMContext &m_Ctx;
  243. llvm::Module *m_pModule;
  244. llvm::Function *m_pEntryFunc;
  245. std::string m_EntryName;
  246. std::unique_ptr<DxilMDHelper> m_pMDHelper;
  247. std::unique_ptr<llvm::DebugInfoFinder> m_pDebugInfoFinder;
  248. const ShaderModel *m_pSM;
  249. unsigned m_DxilMajor;
  250. unsigned m_DxilMinor;
  251. unsigned m_ValMajor;
  252. unsigned m_ValMinor;
  253. DXIL::Float32DenormMode m_Float32DenormMode;
  254. HLOptions m_Options;
  255. std::unique_ptr<OP> m_pOP;
  256. size_t m_pUnused;
  257. uint32_t m_AutoBindingSpace;
  258. DXIL::DefaultLinkage m_DefaultLinkage;
  259. std::unique_ptr<DxilSubobjects> m_pSubobjects;
  260. // DXIL metadata serialization/deserialization.
  261. llvm::MDTuple *EmitHLResources();
  262. void LoadHLResources(const llvm::MDOperand &MDO);
  263. llvm::MDTuple *EmitHLShaderProperties();
  264. void LoadHLShaderProperties(const llvm::MDOperand &MDO);
  265. llvm::MDTuple *EmitDxilShaderProperties();
  266. // LLVM used.
  267. std::vector<llvm::GlobalVariable*> m_LLVMUsed;
  268. // Type annotations.
  269. std::unique_ptr<DxilTypeSystem> m_pTypeSystem;
  270. // Helpers.
  271. template<typename T> unsigned AddResource(std::vector<std::unique_ptr<T> > &Vec, std::unique_ptr<T> pRes);
  272. };
  273. /// Use this class to manipulate metadata of extra metadata record properties that are specific to high-level DX IR.
  274. class HLExtraPropertyHelper : public DxilExtraPropertyHelper {
  275. public:
  276. HLExtraPropertyHelper(llvm::Module *pModule);
  277. virtual ~HLExtraPropertyHelper() {}
  278. virtual void EmitSignatureElementProperties(const DxilSignatureElement &SE, std::vector<llvm::Metadata *> &MDVals);
  279. virtual void LoadSignatureElementProperties(const llvm::MDOperand &MDO, DxilSignatureElement &SE);
  280. };
  281. } // namespace hlsl