HLOperations.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // HLOperations.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. // Implentation of High Level DXIL operations. //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #pragma once
  12. #include "llvm/IR/IRBuilder.h"
  13. #include <string>
  14. namespace llvm {
  15. class Argument;
  16. template<typename T> class ArrayRef;
  17. class AttributeSet;
  18. class CallInst;
  19. class Function;
  20. class FunctionType;
  21. class Module;
  22. class StringRef;
  23. class Type;
  24. class Value;
  25. }
  26. namespace hlsl {
  27. enum class HLOpcodeGroup {
  28. NotHL,
  29. HLExtIntrinsic,
  30. HLIntrinsic,
  31. HLCast,
  32. HLInit,
  33. HLBinOp,
  34. HLUnOp,
  35. HLSubscript,
  36. HLMatLoadStore,
  37. HLSelect,
  38. HLCreateHandle,
  39. HLAnnotateHandle,
  40. NumOfHLOps
  41. };
  42. enum class HLBinaryOpcode {
  43. Invalid,
  44. Mul,
  45. Div,
  46. Rem,
  47. Add,
  48. Sub,
  49. Shl,
  50. Shr,
  51. LT,
  52. GT,
  53. LE,
  54. GE,
  55. EQ,
  56. NE,
  57. And,
  58. Xor,
  59. Or,
  60. LAnd,
  61. LOr,
  62. UDiv,
  63. URem,
  64. UShr,
  65. ULT,
  66. UGT,
  67. ULE,
  68. UGE,
  69. NumOfBO,
  70. };
  71. enum class HLUnaryOpcode {
  72. Invalid,
  73. PostInc,
  74. PostDec,
  75. PreInc,
  76. PreDec,
  77. Plus,
  78. Minus,
  79. Not,
  80. LNot,
  81. NumOfUO,
  82. };
  83. enum class HLSubscriptOpcode {
  84. DefaultSubscript,
  85. ColMatSubscript,
  86. RowMatSubscript,
  87. ColMatElement,
  88. RowMatElement,
  89. DoubleSubscript,
  90. CBufferSubscript,
  91. VectorSubscript, // Only for bool vector, other vector type will use GEP directly.
  92. };
  93. enum class HLCastOpcode {
  94. DefaultCast,
  95. UnsignedUnsignedCast,
  96. FromUnsignedCast,
  97. ToUnsignedCast,
  98. ColMatrixToVecCast,
  99. RowMatrixToVecCast,
  100. ColMatrixToRowMatrix,
  101. RowMatrixToColMatrix,
  102. HandleToResCast,
  103. };
  104. enum class HLMatLoadStoreOpcode {
  105. ColMatLoad,
  106. ColMatStore,
  107. RowMatLoad,
  108. RowMatStore,
  109. };
  110. extern const char * const HLPrefix;
  111. HLOpcodeGroup GetHLOpcodeGroup(llvm::Function *F);
  112. HLOpcodeGroup GetHLOpcodeGroupByName(const llvm::Function *F);
  113. llvm::StringRef GetHLOpcodeGroupNameByAttr(llvm::Function *F);
  114. llvm::StringRef GetHLLowerStrategy(llvm::Function *F);
  115. unsigned GetHLOpcode(const llvm::CallInst *CI);
  116. unsigned GetRowMajorOpcode(HLOpcodeGroup group, unsigned opcode);
  117. void SetHLLowerStrategy(llvm::Function *F, llvm::StringRef S);
  118. void SetHLWaveSensitive(llvm::Function *F);
  119. bool IsHLWaveSensitive(llvm::Function *F);
  120. // For intrinsic opcode.
  121. bool HasUnsignedOpcode(unsigned opcode);
  122. unsigned GetUnsignedOpcode(unsigned opcode);
  123. // For HLBinaryOpcode.
  124. bool HasUnsignedOpcode(HLBinaryOpcode opcode);
  125. HLBinaryOpcode GetUnsignedOpcode(HLBinaryOpcode opcode);
  126. llvm::StringRef GetHLOpcodeGroupName(HLOpcodeGroup op);
  127. namespace HLOperandIndex {
  128. // Opcode parameter.
  129. const unsigned kOpcodeIdx = 0;
  130. // Used to initialize values that have no valid index in the HL overload.
  131. const unsigned kInvalidIdx = UINT32_MAX;
  132. // Matrix store.
  133. const unsigned kMatStoreDstPtrOpIdx = 1;
  134. const unsigned kMatStoreValOpIdx = 2;
  135. // Matrix load.
  136. const unsigned kMatLoadPtrOpIdx = 1;
  137. // Normal subscipts.
  138. const unsigned kSubscriptObjectOpIdx = 1;
  139. const unsigned kSubscriptIndexOpIdx = 2;
  140. // Double subscripts.
  141. const unsigned kDoubleSubscriptMipLevelOpIdx = 3;
  142. // Matrix subscripts.
  143. const unsigned kMatSubscriptMatOpIdx = 1;
  144. const unsigned kMatSubscriptSubOpIdx = 2;
  145. // Matrix init.
  146. const unsigned kMatArrayInitMatOpIdx = 1;
  147. const unsigned kMatArrayInitFirstArgOpIdx = 2;
  148. // Array Init.
  149. const unsigned kArrayInitPtrOpIdx = 1;
  150. const unsigned kArrayInitFirstArgOpIdx = 2;
  151. // Normal Init.
  152. const unsigned kInitFirstArgOpIdx = 1;
  153. // Unary operators.
  154. const unsigned kUnaryOpSrc0Idx = 1;
  155. // Binary operators.
  156. const unsigned kBinaryOpSrc0Idx = 1;
  157. const unsigned kBinaryOpSrc1Idx = 2;
  158. // Trinary operators.
  159. const unsigned kTrinaryOpSrc0Idx = 1;
  160. const unsigned kTrinaryOpSrc1Idx = 2;
  161. const unsigned kTrinaryOpSrc2Idx = 3;
  162. // Interlocked.
  163. const unsigned kInterlockedDestOpIndex = 1;
  164. const unsigned kInterlockedValueOpIndex = 2;
  165. const unsigned kInterlockedOriginalValueOpIndex = 3;
  166. // Interlocked method
  167. const unsigned kInterlockedMethodValueOpIndex = 3;
  168. // InterlockedCompareExchange.
  169. const unsigned kInterlockedCmpDestOpIndex = 1;
  170. const unsigned kInterlockedCmpCompareValueOpIndex = 2;
  171. const unsigned kInterlockedCmpValueOpIndex = 3;
  172. const unsigned kInterlockedCmpOriginalValueOpIndex = 4;
  173. // Lerp.
  174. const unsigned kLerpOpXIdx = 1;
  175. const unsigned kLerpOpYIdx = 2;
  176. const unsigned kLerpOpSIdx = 3;
  177. // ProcessTessFactorIsoline.
  178. const unsigned kProcessTessFactorRawDetailFactor = 1;
  179. const unsigned kProcessTessFactorRawDensityFactor = 2;
  180. const unsigned kProcessTessFactorRoundedDetailFactor = 3;
  181. const unsigned kProcessTessFactorRoundedDensityFactor = 4;
  182. // ProcessTessFactor.
  183. const unsigned kProcessTessFactorRawEdgeFactor = 1;
  184. const unsigned kProcessTessFactorInsideScale = 2;
  185. const unsigned kProcessTessFactorRoundedEdgeFactor = 3;
  186. const unsigned kProcessTessFactorRoundedInsideFactor = 4;
  187. const unsigned kProcessTessFactorUnRoundedInsideFactor = 5;
  188. // Reflect.
  189. const unsigned kReflectOpIIdx = 1;
  190. const unsigned kReflectOpNIdx = 2;
  191. // Refract
  192. const unsigned kRefractOpIIdx = 1;
  193. const unsigned kRefractOpNIdx = 2;
  194. const unsigned kRefractOpEtaIdx = 3;
  195. // SmoothStep.
  196. const unsigned kSmoothStepOpMinIdx = 1;
  197. const unsigned kSmoothStepOpMaxIdx = 2;
  198. const unsigned kSmoothStepOpXIdx = 3;
  199. // Clamp
  200. const unsigned kClampOpXIdx = 1;
  201. const unsigned kClampOpMinIdx = 2;
  202. const unsigned kClampOpMaxIdx = 3;
  203. // Object functions.
  204. const unsigned kHandleOpIdx = 1;
  205. // Store.
  206. const unsigned kStoreOffsetOpIdx = 2;
  207. const unsigned kStoreValOpIdx = 3;
  208. // Load.
  209. const unsigned kBufLoadAddrOpIdx = 2;
  210. const unsigned kBufLoadStatusOpIdx = 3;
  211. const unsigned kRWTexLoadStatusOpIdx = 3;
  212. const unsigned kTexLoadOffsetOpIdx = 3;
  213. const unsigned kTexLoadStatusOpIdx = 4;
  214. // Load for Texture2DMS
  215. const unsigned kTex2DMSLoadSampleIdxOpIdx = 3;
  216. const unsigned kTex2DMSLoadOffsetOpIdx = 4;
  217. const unsigned kTex2DMSLoadStatusOpIdx = 5;
  218. // mips.Operator.
  219. const unsigned kMipLoadAddrOpIdx = 3;
  220. const unsigned kMipLoadOffsetOpIdx = 4;
  221. const unsigned kMipLoadStatusOpIdx = 5;
  222. // Sample.
  223. const unsigned kSampleSamplerArgIndex = 2;
  224. const unsigned kSampleCoordArgIndex = 3;
  225. const unsigned kSampleOffsetArgIndex = 4;
  226. const unsigned kSampleClampArgIndex = 5;
  227. const unsigned kSampleStatusArgIndex = 6;
  228. // SampleG.
  229. const unsigned kSampleGDDXArgIndex = 4;
  230. const unsigned kSampleGDDYArgIndex = 5;
  231. const unsigned kSampleGOffsetArgIndex = 6;
  232. const unsigned kSampleGClampArgIndex = 7;
  233. const unsigned kSampleGStatusArgIndex = 8;
  234. // SampleCmp.
  235. const unsigned kSampleCmpCmpValArgIndex = 4;
  236. const unsigned kSampleCmpOffsetArgIndex = 5;
  237. const unsigned kSampleCmpClampArgIndex = 6;
  238. const unsigned kSampleCmpStatusArgIndex = 7;
  239. // SampleBias.
  240. const unsigned kSampleBBiasArgIndex = 4;
  241. const unsigned kSampleBOffsetArgIndex = 5;
  242. const unsigned kSampleBClampArgIndex = 6;
  243. const unsigned kSampleBStatusArgIndex = 7;
  244. // SampleLevel.
  245. const unsigned kSampleLLevelArgIndex = 4;
  246. const unsigned kSampleLOffsetArgIndex = 5;
  247. const unsigned kSampleLStatusArgIndex = 6;
  248. // SampleCmpLevelZero.
  249. const unsigned kSampleCmpLZCmpValArgIndex = 4;
  250. const unsigned kSampleCmpLZOffsetArgIndex = 5;
  251. const unsigned kSampleCmpLZStatusArgIndex = 6;
  252. // Gather.
  253. const unsigned kGatherSamplerArgIndex = 2;
  254. const unsigned kGatherCoordArgIndex = 3;
  255. const unsigned kGatherOffsetArgIndex = 4;
  256. const unsigned kGatherStatusArgIndex = 5;
  257. const unsigned kGatherSampleOffsetArgIndex = 5;
  258. const unsigned kGatherStatusWithSampleOffsetArgIndex = 8;
  259. const unsigned kGatherCubeStatusArgIndex = 4;
  260. // GatherCmp.
  261. const unsigned kGatherCmpCmpValArgIndex = 4;
  262. const unsigned kGatherCmpOffsetArgIndex = 5;
  263. const unsigned kGatherCmpStatusArgIndex = 6;
  264. const unsigned kGatherCmpSampleOffsetArgIndex = 6;
  265. const unsigned kGatherCmpStatusWithSampleOffsetArgIndex = 9;
  266. const unsigned kGatherCmpCubeStatusArgIndex = 5;
  267. // WriteSamplerFeedback.
  268. const unsigned kWriteSamplerFeedbackSampledArgIndex = 2;
  269. const unsigned kWriteSamplerFeedbackSamplerArgIndex = 3;
  270. const unsigned kWriteSamplerFeedbackCoordArgIndex = 4;
  271. const unsigned kWriteSamplerFeedbackBias_BiasArgIndex = 5;
  272. const unsigned kWriteSamplerFeedbackLevel_LodArgIndex = 5;
  273. const unsigned kWriteSamplerFeedbackGrad_DdxArgIndex = 5;
  274. const unsigned kWriteSamplerFeedbackGrad_DdyArgIndex = 6;
  275. const unsigned kWriteSamplerFeedback_ClampArgIndex = 5;
  276. const unsigned kWriteSamplerFeedbackBias_ClampArgIndex = 6;
  277. const unsigned kWriteSamplerFeedbackGrad_ClampArgIndex = 7;
  278. // StreamAppend.
  279. const unsigned kStreamAppendStreamOpIndex = 1;
  280. const unsigned kStreamAppendDataOpIndex = 2;
  281. // Append.
  282. const unsigned kAppendValOpIndex = 2;
  283. // Interlocked.
  284. const unsigned kObjectInterlockedDestOpIndex = 2;
  285. const unsigned kObjectInterlockedValueOpIndex = 3;
  286. const unsigned kObjectInterlockedOriginalValueOpIndex = 4;
  287. // InterlockedCompareExchange.
  288. const unsigned kObjectInterlockedCmpDestOpIndex = 2;
  289. const unsigned kObjectInterlockedCmpCompareValueOpIndex = 3;
  290. const unsigned kObjectInterlockedCmpValueOpIndex = 4;
  291. const unsigned kObjectInterlockedCmpOriginalValueOpIndex = 5;
  292. // GetSamplePosition.
  293. const unsigned kGetSamplePositionSampleIdxOpIndex = 2;
  294. // GetDimensions.
  295. const unsigned kGetDimensionsMipLevelOpIndex = 2;
  296. const unsigned kGetDimensionsMipWidthOpIndex = 3;
  297. const unsigned kGetDimensionsNoMipWidthOpIndex = 2;
  298. // WaveAllEqual.
  299. const unsigned kWaveAllEqualValueOpIdx = 1;
  300. // CreateHandle.
  301. const unsigned kCreateHandleResourceOpIdx = 1;
  302. const unsigned kCreateHandleIndexOpIdx = 2; // Only for array of cbuffer.
  303. // AnnotateHandle.
  304. const unsigned kAnnotateHandleHandleOpIdx = 1;
  305. const unsigned kAnnotateHandleResourcePropertiesOpIdx = 2;
  306. const unsigned kAnnotateHandleResourceTypeOpIdx = 3;
  307. // TraceRay.
  308. const unsigned kTraceRayRayDescOpIdx = 7;
  309. const unsigned kTraceRayPayLoadOpIdx = 8;
  310. // CallShader.
  311. const unsigned kCallShaderPayloadOpIdx = 2;
  312. // TraceRayInline.
  313. const unsigned kTraceRayInlineRayDescOpIdx = 5;
  314. // ReportIntersection.
  315. const unsigned kReportIntersectionAttributeOpIdx = 3;
  316. // DispatchMesh
  317. const unsigned kDispatchMeshOpThreadX = 1;
  318. const unsigned kDispatchMeshOpThreadY = 2;
  319. const unsigned kDispatchMeshOpThreadZ = 3;
  320. const unsigned kDispatchMeshOpPayload = 4;
  321. } // namespace HLOperandIndex
  322. llvm::Function *GetOrCreateHLFunction(llvm::Module &M,
  323. llvm::FunctionType *funcTy,
  324. HLOpcodeGroup group, unsigned opcode);
  325. llvm::Function *GetOrCreateHLFunction(llvm::Module &M,
  326. llvm::FunctionType *funcTy,
  327. HLOpcodeGroup group,
  328. llvm::StringRef *groupName,
  329. llvm::StringRef *fnName,
  330. unsigned opcode);
  331. llvm::Function *GetOrCreateHLFunction(llvm::Module &M,
  332. llvm::FunctionType *funcTy,
  333. HLOpcodeGroup group, unsigned opcode,
  334. const llvm::AttributeSet &attribs);
  335. llvm::Function *GetOrCreateHLFunction(llvm::Module &M,
  336. llvm::FunctionType *funcTy,
  337. HLOpcodeGroup group,
  338. llvm::StringRef *groupName,
  339. llvm::StringRef *fnName,
  340. unsigned opcode,
  341. const llvm::AttributeSet &attribs);
  342. llvm::Function *GetOrCreateHLFunctionWithBody(llvm::Module &M,
  343. llvm::FunctionType *funcTy,
  344. HLOpcodeGroup group,
  345. unsigned opcode,
  346. llvm::StringRef name);
  347. llvm::Value *callHLFunction(llvm::Module &Module, HLOpcodeGroup OpcodeGroup, unsigned Opcode,
  348. llvm::Type *RetTy, llvm::ArrayRef<llvm::Value*> Args,
  349. const llvm::AttributeSet &attribs, llvm::IRBuilder<> &Builder);
  350. llvm::Value *callHLFunction(llvm::Module &Module, HLOpcodeGroup OpcodeGroup, unsigned Opcode,
  351. llvm::Type *RetTy, llvm::ArrayRef<llvm::Value*> Args,
  352. llvm::IRBuilder<> &Builder);
  353. } // namespace hlsl