CGHLSLMSHelper.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #pragma once
  2. #include "clang/Basic/SourceLocation.h"
  3. #include "llvm/ADT/StringMap.h"
  4. #include "llvm/ADT/MapVector.h"
  5. #include "dxc/DXIL/DxilCBuffer.h"
  6. #include <memory>
  7. #include <vector>
  8. namespace clang {
  9. class HLSLPatchConstantFuncAttr;
  10. namespace CodeGen {
  11. class CodeGenModule;
  12. }
  13. }
  14. namespace llvm {
  15. class Function;
  16. class Module;
  17. class Value;
  18. class DebugLoc;
  19. class Constant;
  20. class GlobalVariable;
  21. class CallInst;
  22. class Instruction;
  23. template <typename T, unsigned N> class SmallVector;
  24. }
  25. namespace hlsl {
  26. class HLModule;
  27. struct DxilResourceProperties;
  28. struct DxilFunctionProps;
  29. class DxilFieldAnnotation;
  30. enum class IntrinsicOp;
  31. namespace dxilutil {
  32. class ExportMap;
  33. }
  34. }
  35. namespace CGHLSLMSHelper {
  36. struct EntryFunctionInfo {
  37. clang::SourceLocation SL = clang::SourceLocation();
  38. llvm::Function *Func = nullptr;
  39. };
  40. // Map to save patch constant functions
  41. struct PatchConstantInfo {
  42. clang::SourceLocation SL = clang::SourceLocation();
  43. llvm::Function *Func = nullptr;
  44. std::uint32_t NumOverloads = 0;
  45. };
  46. /// Use this class to represent HLSL cbuffer in high-level DXIL.
  47. class HLCBuffer : public hlsl::DxilCBuffer {
  48. public:
  49. HLCBuffer(bool bIsView, bool bIsTBuf)
  50. : bIsView(bIsView), bIsTBuf(bIsTBuf), bIsArray(false), ResultTy(nullptr) {}
  51. virtual ~HLCBuffer() = default;
  52. void AddConst(std::unique_ptr<DxilResourceBase> &pItem) {
  53. pItem->SetID(constants.size());
  54. constants.push_back(std::move(pItem));
  55. }
  56. std::vector<std::unique_ptr<DxilResourceBase>> &GetConstants() {
  57. return constants;
  58. }
  59. bool IsView() { return bIsView; }
  60. bool IsTBuf() { return bIsTBuf; }
  61. bool IsArray() { return bIsArray; }
  62. void SetIsArray() { bIsArray = true; }
  63. llvm::Type *GetResultType() { return ResultTy; }
  64. void SetResultType(llvm::Type *Ty) { ResultTy = Ty; }
  65. private:
  66. std::vector<std::unique_ptr<DxilResourceBase>>
  67. constants; // constants inside const buffer
  68. bool bIsView;
  69. bool bIsTBuf;
  70. bool bIsArray;
  71. llvm::Type *ResultTy;
  72. };
  73. // Scope to help transform multiple returns.
  74. struct Scope {
  75. enum class ScopeKind {
  76. IfScope,
  77. SwitchScope,
  78. LoopScope,
  79. ReturnScope,
  80. FunctionScope,
  81. };
  82. ScopeKind kind;
  83. llvm::BasicBlock *EndScopeBB;
  84. // Save loopContinueBB to create dxBreak.
  85. llvm::BasicBlock *loopContinueBB;
  86. // For case like
  87. // if () {
  88. // ...
  89. // return;
  90. // } else {
  91. // ...
  92. // return;
  93. // }
  94. //
  95. // both path is returned.
  96. // When whole scope is returned, go to parent scope directly.
  97. // Anything after it is unreachable.
  98. bool bWholeScopeReturned;
  99. unsigned parentScopeIndex;
  100. };
  101. class ScopeInfo {
  102. public:
  103. ScopeInfo(){}
  104. ScopeInfo(llvm::Function *F);
  105. void AddIf(llvm::BasicBlock *endIfBB);
  106. void AddSwitch(llvm::BasicBlock *endSwitchBB);
  107. void AddLoop(llvm::BasicBlock *loopContinue, llvm::BasicBlock *endLoopBB);
  108. void AddRet(llvm::BasicBlock *bbWithRet);
  109. void EndScope(bool bScopeFinishedWithRet);
  110. Scope &GetScope(unsigned i);
  111. const llvm::SmallVector<unsigned, 2> &GetRetScopes() { return rets; }
  112. void LegalizeWholeReturnedScope();
  113. llvm::SmallVector<Scope, 16> &GetScopes() { return scopes; }
  114. bool CanSkipStructurize();
  115. private:
  116. void AddScope(Scope::ScopeKind k, llvm::BasicBlock *endScopeBB);
  117. llvm::SmallVector<unsigned, 2> rets;
  118. unsigned maxRetLevel;
  119. bool bAllReturnsInIf;
  120. llvm::SmallVector<unsigned, 8> scopeStack;
  121. // save all scopes.
  122. llvm::SmallVector<Scope, 16> scopes;
  123. };
  124. // Map from value to resource properties.
  125. // This only collect object variables(global/local/parameter), not object fields inside struct.
  126. // Object fields inside struct is saved by TypeAnnotation.
  127. struct DxilObjectProperties {
  128. bool AddResource(llvm::Value *V, const hlsl::DxilResourceProperties &RP);
  129. bool IsResource(llvm::Value *V);
  130. hlsl::DxilResourceProperties GetResource(llvm::Value *V);
  131. // MapVector for deterministic iteration order.
  132. llvm::MapVector<llvm::Value *, hlsl::DxilResourceProperties> resMap;
  133. };
  134. // Align cbuffer offset in legacy mode (16 bytes per row).
  135. unsigned AlignBufferOffsetInLegacy(unsigned offset, unsigned size,
  136. unsigned scalarSizeInBytes,
  137. bool bNeedNewRow);
  138. void FinishEntries(hlsl::HLModule &HLM, const EntryFunctionInfo &Entry,
  139. clang::CodeGen::CodeGenModule &CGM,
  140. llvm::StringMap<EntryFunctionInfo> &entryFunctionMap,
  141. std::unordered_map<llvm::Function *,
  142. const clang::HLSLPatchConstantFuncAttr *>
  143. &HSEntryPatchConstantFuncAttr,
  144. llvm::StringMap<PatchConstantInfo> &patchConstantFunctionMap,
  145. std::unordered_map<llvm::Function *,
  146. std::unique_ptr<hlsl::DxilFunctionProps>>
  147. &patchConstantFunctionPropsMap);
  148. void FinishIntrinsics(
  149. hlsl::HLModule &HLM,
  150. std::vector<std::pair<llvm::Function *, unsigned>> &intrinsicMap,
  151. DxilObjectProperties &valToResPropertiesMap);
  152. void AddDxBreak(llvm::Module &M, const llvm::SmallVector<llvm::BranchInst*, 16> &DxBreaks);
  153. void ReplaceConstStaticGlobals(
  154. std::unordered_map<llvm::GlobalVariable *, std::vector<llvm::Constant *>>
  155. &staticConstGlobalInitListMap,
  156. std::unordered_map<llvm::GlobalVariable *, llvm::Function *> &staticConstGlobalCtorMap);
  157. void FinishClipPlane(hlsl::HLModule &HLM, std::vector<llvm::Function *> &clipPlaneFuncList,
  158. std::unordered_map<llvm::Value *, llvm::DebugLoc> &debugInfoMap,
  159. clang::CodeGen::CodeGenModule &CGM);
  160. void AddRegBindingsForResourceInConstantBuffer(
  161. hlsl::HLModule &HLM,
  162. llvm::DenseMap<llvm::Constant *,
  163. llvm::SmallVector<std::pair<hlsl::DXIL::ResourceClass, unsigned>,
  164. 1>> &constantRegBindingMap);
  165. void FinishCBuffer(
  166. hlsl::HLModule &HLM, llvm::Type *CBufferType,
  167. std::unordered_map<llvm::Constant *, hlsl::DxilFieldAnnotation>
  168. &AnnotationMap);
  169. void ProcessCtorFunctions(llvm::Module &M,
  170. llvm::SmallVector<llvm::Function *, 2> &Ctors,
  171. llvm::Function *Entry,
  172. llvm::Function *PatchConstantFn);
  173. void CollectCtorFunctions(llvm::Module &M, llvm::StringRef globalName,
  174. llvm::SmallVector<llvm::Function *, 2> &Ctors,
  175. clang::CodeGen::CodeGenModule &CGM);
  176. void TranslateRayQueryConstructor(hlsl::HLModule &HLM);
  177. void UpdateLinkage(
  178. hlsl::HLModule &HLM, clang::CodeGen::CodeGenModule &CGM,
  179. hlsl::dxilutil::ExportMap &exportMap,
  180. llvm::StringMap<EntryFunctionInfo> &entryFunctionMap,
  181. llvm::StringMap<PatchConstantInfo> &patchConstantFunctionMap);
  182. void StructurizeMultiRet(llvm::Module &M,
  183. clang::CodeGen::CodeGenModule &CGM,
  184. llvm::DenseMap<llvm::Function *, ScopeInfo> &ScopeMap,
  185. bool bWaveEnabledStage,
  186. llvm::SmallVector<llvm::BranchInst *, 16> &DxBreaks);
  187. llvm::Value *TryEvalIntrinsic(llvm::CallInst *CI, hlsl::IntrinsicOp intriOp, unsigned hlslVersion);
  188. void SimpleTransformForHLDXIR(llvm::Module *pM);
  189. void ExtensionCodeGen(hlsl::HLModule &HLM, clang::CodeGen::CodeGenModule &CGM);
  190. } // namespace CGHLSLMSHelper