HLModule.cpp 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // HLModule.cpp //
  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. #include "dxc/HLSL/DxilOperations.h"
  12. #include "dxc/HLSL/DxilShaderModel.h"
  13. #include "dxc/HLSL/DxilCBuffer.h"
  14. #include "dxc/HLSL/HLModule.h"
  15. #include "dxc/HLSL/DxilTypeSystem.h"
  16. #include "dxc/HLSL/DxilRootSignature.h"
  17. #include "llvm/ADT/STLExtras.h"
  18. #include "llvm/IR/Constants.h"
  19. #include "llvm/IR/Function.h"
  20. #include "llvm/IR/IRBuilder.h"
  21. #include "llvm/IR/LLVMContext.h"
  22. #include "llvm/IR/Metadata.h"
  23. #include "llvm/IR/Module.h"
  24. #include "llvm/IR/DebugInfo.h"
  25. #include "llvm/IR/DIBuilder.h"
  26. #include "llvm/Support/raw_ostream.h"
  27. #include "llvm/IR/GetElementPtrTypeIterator.h"
  28. using namespace llvm;
  29. using std::string;
  30. using std::vector;
  31. using std::unique_ptr;
  32. namespace hlsl {
  33. static void
  34. CreateSignatures(const ShaderModel *pSM,
  35. std::unique_ptr<DxilSignature> &InputSignature,
  36. std::unique_ptr<DxilSignature> &OutputSignature,
  37. std::unique_ptr<DxilSignature> &PatchConstantSignature,
  38. std::unique_ptr<RootSignatureHandle> &RootSignature) {
  39. DXIL::ShaderKind shaderKind = pSM->GetKind();
  40. InputSignature = llvm::make_unique<DxilSignature>(shaderKind, DxilSignature::Kind::Input);
  41. OutputSignature = llvm::make_unique<DxilSignature>(shaderKind, DxilSignature::Kind::Output);
  42. PatchConstantSignature = llvm::make_unique<DxilSignature>(shaderKind, DxilSignature::Kind::PatchConstant);
  43. RootSignature = llvm::make_unique<RootSignatureHandle>();
  44. }
  45. //------------------------------------------------------------------------------
  46. //
  47. // HLModule methods.
  48. //
  49. HLModule::HLModule(Module *pModule)
  50. : m_Ctx(pModule->getContext())
  51. , m_pModule(pModule)
  52. , m_pEntryFunc(nullptr)
  53. , m_EntryName("")
  54. , m_pMDHelper(llvm::make_unique<DxilMDHelper>(
  55. pModule, llvm::make_unique<HLExtraPropertyHelper>(pModule)))
  56. , m_pDebugInfoFinder(nullptr)
  57. , m_pSM(nullptr)
  58. , m_DxilMajor(DXIL::kDxilMajor)
  59. , m_DxilMinor(DXIL::kDxilMinor)
  60. , m_pOP(llvm::make_unique<OP>(pModule->getContext(), pModule))
  61. , m_pTypeSystem(llvm::make_unique<DxilTypeSystem>(pModule)) {
  62. DXASSERT_NOMSG(m_pModule != nullptr);
  63. // Pin LLVM dump methods. TODO: make debug-only.
  64. void (__thiscall Module::*pfnModuleDump)() const = &Module::dump;
  65. void (__thiscall Type::*pfnTypeDump)() const = &Type::dump;
  66. m_pUnused = (char *)&pfnModuleDump - (char *)&pfnTypeDump;
  67. }
  68. HLModule::~HLModule() {
  69. }
  70. LLVMContext &HLModule::GetCtx() const { return m_Ctx; }
  71. Module *HLModule::GetModule() const { return m_pModule; }
  72. OP *HLModule::GetOP() const { return m_pOP.get(); }
  73. void HLModule::SetValidatorVersion(unsigned ValMajor, unsigned ValMinor) {
  74. m_ValMajor = ValMajor;
  75. m_ValMinor = ValMinor;
  76. }
  77. void HLModule::GetValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const {
  78. ValMajor = m_ValMajor;
  79. ValMinor = m_ValMinor;
  80. }
  81. void HLModule::SetShaderModel(const ShaderModel *pSM) {
  82. DXASSERT(m_pSM == nullptr, "shader model must not change for the module");
  83. DXASSERT(pSM != nullptr && pSM->IsValidForDxil(), "shader model must be valid");
  84. m_pSM = pSM;
  85. m_pSM->GetDxilVersion(m_DxilMajor, m_DxilMinor);
  86. m_pMDHelper->SetShaderModel(m_pSM);
  87. CreateSignatures(m_pSM, m_InputSignature, m_OutputSignature, m_PatchConstantSignature, m_RootSignature);
  88. }
  89. const ShaderModel *HLModule::GetShaderModel() const {
  90. return m_pSM;
  91. }
  92. uint32_t HLOptions::GetHLOptionsRaw() const {
  93. union Cast {
  94. Cast(const HLOptions &options) {
  95. hlOptions = options;
  96. }
  97. HLOptions hlOptions;
  98. uint32_t rawData;
  99. };
  100. static_assert(sizeof(uint32_t) == sizeof(HLOptions),
  101. "size must match to make sure no undefined bits when cast");
  102. Cast rawCast(*this);
  103. return rawCast.rawData;
  104. }
  105. void HLOptions::SetHLOptionsRaw(uint32_t data) {
  106. union Cast {
  107. Cast(uint32_t data) {
  108. rawData = data;
  109. }
  110. HLOptions hlOptions;
  111. uint64_t rawData;
  112. };
  113. Cast rawCast(data);
  114. *this = rawCast.hlOptions;
  115. }
  116. void HLModule::SetHLOptions(HLOptions &opts) {
  117. m_Options = opts;
  118. }
  119. const HLOptions &HLModule::GetHLOptions() const {
  120. return m_Options;
  121. }
  122. Function *HLModule::GetEntryFunction() const {
  123. return m_pEntryFunc;
  124. }
  125. void HLModule::SetEntryFunction(Function *pEntryFunc) {
  126. m_pEntryFunc = pEntryFunc;
  127. }
  128. const string &HLModule::GetEntryFunctionName() const { return m_EntryName; }
  129. void HLModule::SetEntryFunctionName(const string &name) { m_EntryName = name; }
  130. template<typename T> unsigned
  131. HLModule::AddResource(vector<unique_ptr<T> > &Vec, unique_ptr<T> pRes) {
  132. DXASSERT_NOMSG((unsigned)Vec.size() < UINT_MAX);
  133. unsigned Id = (unsigned)Vec.size();
  134. Vec.emplace_back(std::move(pRes));
  135. return Id;
  136. }
  137. unsigned HLModule::AddCBuffer(unique_ptr<DxilCBuffer> pCBuffer) {
  138. return AddResource<DxilCBuffer>(m_CBuffers, std::move(pCBuffer));
  139. }
  140. DxilCBuffer &HLModule::GetCBuffer(unsigned idx) {
  141. return *m_CBuffers[idx];
  142. }
  143. const DxilCBuffer &HLModule::GetCBuffer(unsigned idx) const {
  144. return *m_CBuffers[idx];
  145. }
  146. const vector<unique_ptr<DxilCBuffer> > &HLModule::GetCBuffers() const {
  147. return m_CBuffers;
  148. }
  149. unsigned HLModule::AddSampler(unique_ptr<DxilSampler> pSampler) {
  150. return AddResource<DxilSampler>(m_Samplers, std::move(pSampler));
  151. }
  152. DxilSampler &HLModule::GetSampler(unsigned idx) {
  153. return *m_Samplers[idx];
  154. }
  155. const DxilSampler &HLModule::GetSampler(unsigned idx) const {
  156. return *m_Samplers[idx];
  157. }
  158. const vector<unique_ptr<DxilSampler> > &HLModule::GetSamplers() const {
  159. return m_Samplers;
  160. }
  161. unsigned HLModule::AddSRV(unique_ptr<HLResource> pSRV) {
  162. return AddResource<HLResource>(m_SRVs, std::move(pSRV));
  163. }
  164. HLResource &HLModule::GetSRV(unsigned idx) {
  165. return *m_SRVs[idx];
  166. }
  167. const HLResource &HLModule::GetSRV(unsigned idx) const {
  168. return *m_SRVs[idx];
  169. }
  170. const vector<unique_ptr<HLResource> > &HLModule::GetSRVs() const {
  171. return m_SRVs;
  172. }
  173. unsigned HLModule::AddUAV(unique_ptr<HLResource> pUAV) {
  174. return AddResource<HLResource>(m_UAVs, std::move(pUAV));
  175. }
  176. HLResource &HLModule::GetUAV(unsigned idx) {
  177. return *m_UAVs[idx];
  178. }
  179. const HLResource &HLModule::GetUAV(unsigned idx) const {
  180. return *m_UAVs[idx];
  181. }
  182. const vector<unique_ptr<HLResource> > &HLModule::GetUAVs() const {
  183. return m_UAVs;
  184. }
  185. void HLModule::RemoveFunction(llvm::Function *F) {
  186. DXASSERT_NOMSG(F != nullptr);
  187. m_HLFunctionPropsMap.erase(F);
  188. if (m_pTypeSystem.get()->GetFunctionAnnotation(F))
  189. m_pTypeSystem.get()->EraseFunctionAnnotation(F);
  190. m_pOP->RemoveFunction(F);
  191. }
  192. template <typename TResource>
  193. bool RemoveResource(std::vector<std::unique_ptr<TResource>> &vec,
  194. GlobalVariable *pVariable) {
  195. for (auto p = vec.begin(), e = vec.end(); p != e; ++p) {
  196. if ((*p)->GetGlobalSymbol() == pVariable) {
  197. p = vec.erase(p);
  198. // Update ID.
  199. for (e = vec.end();p != e; ++p) {
  200. unsigned ID = (*p)->GetID()-1;
  201. (*p)->SetID(ID);
  202. }
  203. return true;
  204. }
  205. }
  206. return false;
  207. }
  208. bool RemoveResource(std::vector<GlobalVariable *> &vec,
  209. llvm::GlobalVariable *pVariable) {
  210. for (auto p = vec.begin(), e = vec.end(); p != e; ++p) {
  211. if (*p == pVariable) {
  212. vec.erase(p);
  213. return true;
  214. }
  215. }
  216. return false;
  217. }
  218. void HLModule::RemoveGlobal(llvm::GlobalVariable *GV) {
  219. RemoveResources(&GV, 1);
  220. }
  221. void HLModule::RemoveResources(llvm::GlobalVariable **ppVariables,
  222. unsigned count) {
  223. DXASSERT_NOMSG(count == 0 || ppVariables != nullptr);
  224. unsigned resourcesRemoved = count;
  225. for (unsigned i = 0; i < count; ++i) {
  226. GlobalVariable *pVariable = ppVariables[i];
  227. // This could be considerably faster - check variable type to see which
  228. // resource type this is rather than scanning all lists, and look for
  229. // usage and removal patterns.
  230. if (RemoveResource(m_CBuffers, pVariable))
  231. continue;
  232. if (RemoveResource(m_SRVs, pVariable))
  233. continue;
  234. if (RemoveResource(m_UAVs, pVariable))
  235. continue;
  236. if (RemoveResource(m_Samplers, pVariable))
  237. continue;
  238. // TODO: do m_TGSMVariables and m_StreamOutputs need maintenance?
  239. --resourcesRemoved; // Global variable is not a resource?
  240. }
  241. }
  242. HLModule::tgsm_iterator HLModule::tgsm_begin() {
  243. return m_TGSMVariables.begin();
  244. }
  245. HLModule::tgsm_iterator HLModule::tgsm_end() {
  246. return m_TGSMVariables.end();
  247. }
  248. void HLModule::AddGroupSharedVariable(GlobalVariable *GV) {
  249. m_TGSMVariables.emplace_back(GV);
  250. }
  251. DxilSignature &HLModule::GetInputSignature() {
  252. return *m_InputSignature;
  253. }
  254. DxilSignature &HLModule::GetOutputSignature() {
  255. return *m_OutputSignature;
  256. }
  257. DxilSignature &HLModule::GetPatchConstantSignature() {
  258. return *m_PatchConstantSignature;
  259. }
  260. RootSignatureHandle &HLModule::GetRootSignature() {
  261. return *m_RootSignature;
  262. }
  263. DxilTypeSystem &HLModule::GetTypeSystem() {
  264. return *m_pTypeSystem;
  265. }
  266. DxilSignature *HLModule::ReleaseInputSignature() {
  267. return m_InputSignature.release();
  268. }
  269. DxilSignature *HLModule::ReleaseOutputSignature() {
  270. return m_OutputSignature.release();
  271. }
  272. DxilSignature *HLModule::ReleasePatchConstantSignature() {
  273. return m_PatchConstantSignature.release();
  274. }
  275. DxilTypeSystem *HLModule::ReleaseTypeSystem() {
  276. return m_pTypeSystem.release();
  277. }
  278. hlsl::OP *HLModule::ReleaseOP() {
  279. return m_pOP.release();
  280. }
  281. RootSignatureHandle *HLModule::ReleaseRootSignature() {
  282. return m_RootSignature.release();
  283. }
  284. void HLModule::EmitLLVMUsed() {
  285. if (m_LLVMUsed.empty())
  286. return;
  287. vector<llvm::Constant*> GVs;
  288. GVs.resize(m_LLVMUsed.size());
  289. for (size_t i = 0, e = m_LLVMUsed.size(); i != e; i++) {
  290. GVs[i] = ConstantExpr::getAddrSpaceCast(cast<llvm::Constant>(&*m_LLVMUsed[i]), Type::getInt8PtrTy(m_Ctx));
  291. }
  292. ArrayType *pATy = ArrayType::get(Type::getInt8PtrTy(m_Ctx), GVs.size());
  293. GlobalVariable *pGV = new GlobalVariable(*m_pModule, pATy, false,
  294. GlobalValue::AppendingLinkage,
  295. ConstantArray::get(pATy, GVs),
  296. "llvm.used");
  297. pGV->setSection("llvm.metadata");
  298. }
  299. vector<GlobalVariable* > &HLModule::GetLLVMUsed() {
  300. return m_LLVMUsed;
  301. }
  302. bool HLModule::HasHLFunctionProps(llvm::Function *F) {
  303. return m_HLFunctionPropsMap.find(F) != m_HLFunctionPropsMap.end();
  304. }
  305. HLFunctionProps &HLModule::GetHLFunctionProps(llvm::Function *F) {
  306. return *m_HLFunctionPropsMap[F];
  307. }
  308. void HLModule::AddHLFunctionProps(llvm::Function *F, std::unique_ptr<HLFunctionProps> &info) {
  309. DXASSERT(m_HLFunctionPropsMap.count(F) == 0, "F already in map, info will be overwritten");
  310. m_HLFunctionPropsMap[F] = std::move(info);
  311. }
  312. DxilFunctionAnnotation *HLModule::GetFunctionAnnotation(llvm::Function *F) {
  313. return m_pTypeSystem->GetFunctionAnnotation(F);
  314. }
  315. DxilFunctionAnnotation *HLModule::AddFunctionAnnotation(llvm::Function *F) {
  316. DXASSERT(m_pTypeSystem->GetFunctionAnnotation(F)==nullptr, "function annotation already exist");
  317. return m_pTypeSystem->AddFunctionAnnotation(F);
  318. }
  319. void HLModule::AddResourceTypeAnnotation(llvm::Type *Ty,
  320. DXIL::ResourceClass resClass,
  321. DXIL::ResourceKind kind) {
  322. if (m_ResTypeAnnotation.count(Ty) == 0) {
  323. m_ResTypeAnnotation.emplace(Ty, std::make_pair(resClass, kind));
  324. } else {
  325. DXASSERT(resClass == m_ResTypeAnnotation[Ty].first, "resClass mismatch");
  326. DXASSERT(kind == m_ResTypeAnnotation[Ty].second, "kind mismatch");
  327. }
  328. }
  329. DXIL::ResourceClass HLModule::GetResourceClass(llvm::Type *Ty) {
  330. if (m_ResTypeAnnotation.count(Ty) > 0) {
  331. return m_ResTypeAnnotation[Ty].first;
  332. } else {
  333. return DXIL::ResourceClass::Invalid;
  334. }
  335. }
  336. DXIL::ResourceKind HLModule::GetResourceKind(llvm::Type *Ty) {
  337. if (m_ResTypeAnnotation.count(Ty) > 0) {
  338. return m_ResTypeAnnotation[Ty].second;
  339. } else {
  340. return DXIL::ResourceKind::Invalid;
  341. }
  342. }
  343. static unsigned GetIntAt(MDTuple *tuple, unsigned idx) {
  344. return DxilMDHelper::ConstMDToUint32(tuple->getOperand(idx));
  345. }
  346. static unsigned GetFloatAt(MDTuple *tuple, unsigned idx) {
  347. return DxilMDHelper::ConstMDToFloat(tuple->getOperand(idx));
  348. }
  349. static const StringRef kHLDxilFunctionPropertiesMDName = "dx.fnprops";
  350. static const StringRef kHLDxilOptionsMDName = "dx.options";
  351. static const StringRef kHLDxilResourceTypeAnnotationMDName = "dx.resource.type.annotation";
  352. // DXIL metadata serialization/deserialization.
  353. void HLModule::EmitHLMetadata() {
  354. m_pMDHelper->EmitDxilVersion(m_DxilMajor, m_DxilMinor);
  355. m_pMDHelper->EmitValidatorVersion(m_ValMajor, m_ValMinor);
  356. m_pMDHelper->EmitDxilShaderModel(m_pSM);
  357. MDTuple *pMDSignatures = m_pMDHelper->EmitDxilSignatures(*m_InputSignature,
  358. *m_OutputSignature,
  359. *m_PatchConstantSignature);
  360. MDTuple *pMDResources = EmitHLResources();
  361. MDTuple *pMDProperties = EmitHLShaderProperties();
  362. m_pMDHelper->EmitDxilTypeSystem(GetTypeSystem(), m_LLVMUsed);
  363. EmitLLVMUsed();
  364. MDTuple *pEntry = m_pMDHelper->EmitDxilEntryPointTuple(GetEntryFunction(), m_EntryName, pMDSignatures, pMDResources, pMDProperties);
  365. vector<MDNode *> Entries;
  366. Entries.emplace_back(pEntry);
  367. m_pMDHelper->EmitDxilEntryPoints(Entries);
  368. {
  369. NamedMDNode * fnProps = m_pModule->getOrInsertNamedMetadata(kHLDxilFunctionPropertiesMDName);
  370. for (auto && pair : m_HLFunctionPropsMap) {
  371. const hlsl::HLFunctionProps * props = pair.second.get();
  372. Metadata *MDVals[30];
  373. std::fill(MDVals, MDVals + _countof(MDVals), nullptr);
  374. unsigned valIdx = 0;
  375. MDVals[valIdx++] = ValueAsMetadata::get(pair.first);
  376. switch (m_pSM->GetKind()) {
  377. case DXIL::ShaderKind::Compute:
  378. MDVals[valIdx++] = m_pMDHelper->Uint32ToConstMD(props->ShaderProps.CS.numThreads[0]);
  379. MDVals[valIdx++] = m_pMDHelper->Uint32ToConstMD(props->ShaderProps.CS.numThreads[1]);
  380. MDVals[valIdx++] = m_pMDHelper->Uint32ToConstMD(props->ShaderProps.CS.numThreads[2]);
  381. break;
  382. case DXIL::ShaderKind::Geometry:
  383. MDVals[valIdx++] = m_pMDHelper->Uint8ToConstMD((uint8_t)props->ShaderProps.GS.inputPrimitive);
  384. MDVals[valIdx++] = m_pMDHelper->Uint32ToConstMD(props->ShaderProps.GS.maxVertexCount);
  385. for (size_t i = 0; i < _countof(props->ShaderProps.GS.streamPrimitiveTopologies); ++i)
  386. MDVals[valIdx++] = m_pMDHelper->Uint8ToConstMD((uint8_t)props->ShaderProps.GS.streamPrimitiveTopologies[i]);
  387. break;
  388. case DXIL::ShaderKind::Hull:
  389. MDVals[valIdx++] = ValueAsMetadata::get(props->ShaderProps.HS.patchConstantFunc);
  390. MDVals[valIdx++] = m_pMDHelper->Uint8ToConstMD((uint8_t)props->ShaderProps.HS.domain);
  391. MDVals[valIdx++] = m_pMDHelper->Uint8ToConstMD((uint8_t)props->ShaderProps.HS.partition);
  392. MDVals[valIdx++] = m_pMDHelper->Uint8ToConstMD((uint8_t)props->ShaderProps.HS.outputPrimitive);
  393. MDVals[valIdx++] = m_pMDHelper->Uint32ToConstMD(props->ShaderProps.HS.inputControlPoints);
  394. MDVals[valIdx++] = m_pMDHelper->Uint32ToConstMD(props->ShaderProps.HS.outputControlPoints);
  395. MDVals[valIdx++] = m_pMDHelper->FloatToConstMD(props->ShaderProps.HS.maxTessFactor);
  396. break;
  397. case DXIL::ShaderKind::Domain:
  398. MDVals[valIdx++] = m_pMDHelper->Uint8ToConstMD((uint8_t)props->ShaderProps.DS.domain);
  399. MDVals[valIdx++] = m_pMDHelper->Uint32ToConstMD(props->ShaderProps.DS.inputControlPoints);
  400. break;
  401. case DXIL::ShaderKind::Pixel:
  402. MDVals[valIdx++] = m_pMDHelper->BoolToConstMD(props->ShaderProps.PS.EarlyDepthStencil);
  403. break;
  404. }
  405. fnProps->addOperand(MDTuple::get(m_Ctx, ArrayRef<llvm::Metadata *>(MDVals, valIdx)));
  406. }
  407. NamedMDNode * options = m_pModule->getOrInsertNamedMetadata(kHLDxilOptionsMDName);
  408. uint32_t hlOptions = m_Options.GetHLOptionsRaw();
  409. options->addOperand(MDNode::get(m_Ctx, m_pMDHelper->Uint32ToConstMD(hlOptions)));
  410. NamedMDNode * resTyAnnotations = m_pModule->getOrInsertNamedMetadata(kHLDxilResourceTypeAnnotationMDName);
  411. resTyAnnotations->addOperand(EmitResTyAnnotations());
  412. }
  413. if (!m_RootSignature->IsEmpty()) {
  414. m_pMDHelper->EmitRootSignature(*m_RootSignature.get());
  415. }
  416. }
  417. void HLModule::LoadHLMetadata() {
  418. m_pMDHelper->LoadDxilVersion(m_DxilMajor, m_DxilMinor);
  419. m_pMDHelper->LoadValidatorVersion(m_ValMajor, m_ValMinor);
  420. m_pMDHelper->LoadDxilShaderModel(m_pSM);
  421. CreateSignatures(m_pSM, m_InputSignature, m_OutputSignature, m_PatchConstantSignature, m_RootSignature);
  422. const llvm::NamedMDNode *pEntries = m_pMDHelper->GetDxilEntryPoints();
  423. Function *pEntryFunc;
  424. string EntryName;
  425. const llvm::MDOperand *pSignatures, *pResources, *pProperties;
  426. m_pMDHelper->GetDxilEntryPoint(pEntries->getOperand(0), pEntryFunc, EntryName, pSignatures, pResources, pProperties);
  427. SetEntryFunction(pEntryFunc);
  428. SetEntryFunctionName(EntryName);
  429. m_pMDHelper->LoadDxilSignatures(*pSignatures, *m_InputSignature,
  430. *m_OutputSignature, *m_PatchConstantSignature);
  431. LoadHLResources(*pResources);
  432. LoadHLShaderProperties(*pProperties);
  433. m_pMDHelper->LoadDxilTypeSystem(*m_pTypeSystem.get());
  434. {
  435. NamedMDNode * fnProps = m_pModule->getNamedMetadata(kHLDxilFunctionPropertiesMDName);
  436. size_t propIdx = 0;
  437. while (propIdx < fnProps->getNumOperands()) {
  438. MDTuple *pProps = dyn_cast<MDTuple>(fnProps->getOperand(propIdx++));
  439. std::unique_ptr<hlsl::HLFunctionProps> props = llvm::make_unique<hlsl::HLFunctionProps>();
  440. unsigned idx = 0;
  441. Function *F = dyn_cast<Function>(dyn_cast<ValueAsMetadata>(pProps->getOperand(idx++))->getValue());
  442. switch (m_pSM->GetKind()) {
  443. case DXIL::ShaderKind::Compute:
  444. props->ShaderProps.CS.numThreads[0] = GetIntAt(pProps, idx++);
  445. props->ShaderProps.CS.numThreads[1] = GetIntAt(pProps, idx++);
  446. props->ShaderProps.CS.numThreads[2] = GetIntAt(pProps, idx++);
  447. break;
  448. case DXIL::ShaderKind::Geometry:
  449. props->ShaderProps.GS.inputPrimitive = (DXIL::InputPrimitive)GetIntAt(pProps, idx++);
  450. props->ShaderProps.GS.maxVertexCount = GetIntAt(pProps, idx++);
  451. for (size_t i = 0; i < _countof(props->ShaderProps.GS.streamPrimitiveTopologies); ++i)
  452. props->ShaderProps.GS.streamPrimitiveTopologies[i] = (DXIL::PrimitiveTopology)GetIntAt(pProps, idx++);
  453. break;
  454. case DXIL::ShaderKind::Hull:
  455. props->ShaderProps.HS.patchConstantFunc = dyn_cast<Function>(dyn_cast<ValueAsMetadata>(pProps->getOperand(idx++))->getValue());
  456. props->ShaderProps.HS.domain = (DXIL::TessellatorDomain)GetIntAt(pProps, idx++);
  457. props->ShaderProps.HS.partition = (DXIL::TessellatorPartitioning)GetIntAt(pProps, idx++);
  458. props->ShaderProps.HS.outputPrimitive = (DXIL::TessellatorOutputPrimitive)GetIntAt(pProps, idx++);
  459. props->ShaderProps.HS.inputControlPoints = GetIntAt(pProps, idx++);
  460. props->ShaderProps.HS.outputControlPoints = GetIntAt(pProps, idx++);
  461. props->ShaderProps.HS.maxTessFactor = GetFloatAt(pProps, idx++);
  462. break;
  463. case DXIL::ShaderKind::Domain:
  464. props->ShaderProps.DS.domain = (DXIL::TessellatorDomain)GetIntAt(pProps, idx++);
  465. props->ShaderProps.DS.inputControlPoints = GetIntAt(pProps, idx++);
  466. break;
  467. case DXIL::ShaderKind::Pixel:
  468. props->ShaderProps.PS.EarlyDepthStencil = GetIntAt(pProps, idx++);
  469. break;
  470. }
  471. m_HLFunctionPropsMap[F] = std::move(props);
  472. }
  473. const NamedMDNode * options = m_pModule->getOrInsertNamedMetadata(kHLDxilOptionsMDName);
  474. const MDNode *MDOptions = options->getOperand(0);
  475. m_Options.SetHLOptionsRaw(DxilMDHelper::ConstMDToUint32(MDOptions->getOperand(0)));
  476. NamedMDNode * resTyAnnotations = m_pModule->getOrInsertNamedMetadata(kHLDxilResourceTypeAnnotationMDName);
  477. const MDNode *MDResTyAnnotations = resTyAnnotations->getOperand(0);
  478. if (MDResTyAnnotations->getNumOperands())
  479. LoadResTyAnnotations(MDResTyAnnotations->getOperand(0));
  480. }
  481. m_pMDHelper->LoadRootSignature(*m_RootSignature.get());
  482. }
  483. void HLModule::ClearHLMetadata(llvm::Module &M) {
  484. Module::named_metadata_iterator
  485. b = M.named_metadata_begin(),
  486. e = M.named_metadata_end();
  487. SmallVector<NamedMDNode*, 8> nodes;
  488. for (; b != e; ++b) {
  489. StringRef name = b->getName();
  490. if (name == DxilMDHelper::kDxilVersionMDName ||
  491. name == DxilMDHelper::kDxilShaderModelMDName ||
  492. name == DxilMDHelper::kDxilEntryPointsMDName ||
  493. name == DxilMDHelper::kDxilRootSignatureMDName ||
  494. name == DxilMDHelper::kDxilResourcesMDName ||
  495. name == DxilMDHelper::kDxilTypeSystemMDName ||
  496. name == DxilMDHelper::kDxilValidatorVersionMDName ||
  497. name == kHLDxilFunctionPropertiesMDName || // TODO: adjust to proper name
  498. name == kHLDxilResourceTypeAnnotationMDName ||
  499. name == kHLDxilOptionsMDName ||
  500. name.startswith(DxilMDHelper::kDxilTypeSystemHelperVariablePrefix)) {
  501. nodes.push_back(b);
  502. }
  503. }
  504. for (size_t i = 0; i < nodes.size(); ++i) {
  505. M.eraseNamedMetadata(nodes[i]);
  506. }
  507. }
  508. MDTuple *HLModule::EmitHLResources() {
  509. // Emit SRV records.
  510. MDTuple *pTupleSRVs = nullptr;
  511. if (!m_SRVs.empty()) {
  512. vector<Metadata *> MDVals;
  513. for (size_t i = 0; i < m_SRVs.size(); i++) {
  514. MDVals.emplace_back(m_pMDHelper->EmitDxilSRV(*m_SRVs[i]));
  515. }
  516. pTupleSRVs = MDNode::get(m_Ctx, MDVals);
  517. }
  518. // Emit UAV records.
  519. MDTuple *pTupleUAVs = nullptr;
  520. if (!m_UAVs.empty()) {
  521. vector<Metadata *> MDVals;
  522. for (size_t i = 0; i < m_UAVs.size(); i++) {
  523. MDVals.emplace_back(m_pMDHelper->EmitDxilUAV(*m_UAVs[i]));
  524. }
  525. pTupleUAVs = MDNode::get(m_Ctx, MDVals);
  526. }
  527. // Emit CBuffer records.
  528. MDTuple *pTupleCBuffers = nullptr;
  529. if (!m_CBuffers.empty()) {
  530. vector<Metadata *> MDVals;
  531. for (size_t i = 0; i < m_CBuffers.size(); i++) {
  532. MDVals.emplace_back(m_pMDHelper->EmitDxilCBuffer(*m_CBuffers[i]));
  533. }
  534. pTupleCBuffers = MDNode::get(m_Ctx, MDVals);
  535. }
  536. // Emit Sampler records.
  537. MDTuple *pTupleSamplers = nullptr;
  538. if (!m_Samplers.empty()) {
  539. vector<Metadata *> MDVals;
  540. for (size_t i = 0; i < m_Samplers.size(); i++) {
  541. MDVals.emplace_back(m_pMDHelper->EmitDxilSampler(*m_Samplers[i]));
  542. }
  543. pTupleSamplers = MDNode::get(m_Ctx, MDVals);
  544. }
  545. if (pTupleSRVs != nullptr || pTupleUAVs != nullptr || pTupleCBuffers != nullptr || pTupleSamplers != nullptr) {
  546. return m_pMDHelper->EmitDxilResourceTuple(pTupleSRVs, pTupleUAVs, pTupleCBuffers, pTupleSamplers);
  547. } else {
  548. return nullptr;
  549. }
  550. }
  551. void HLModule::LoadHLResources(const llvm::MDOperand &MDO) {
  552. const llvm::MDTuple *pSRVs, *pUAVs, *pCBuffers, *pSamplers;
  553. m_pMDHelper->GetDxilResources(MDO, pSRVs, pUAVs, pCBuffers, pSamplers);
  554. // Load SRV records.
  555. if (pSRVs != nullptr) {
  556. for (unsigned i = 0; i < pSRVs->getNumOperands(); i++) {
  557. unique_ptr<HLResource> pSRV(new HLResource);
  558. m_pMDHelper->LoadDxilSRV(pSRVs->getOperand(i), *pSRV);
  559. AddSRV(std::move(pSRV));
  560. }
  561. }
  562. // Load UAV records.
  563. if (pUAVs != nullptr) {
  564. for (unsigned i = 0; i < pUAVs->getNumOperands(); i++) {
  565. unique_ptr<HLResource> pUAV(new HLResource);
  566. m_pMDHelper->LoadDxilUAV(pUAVs->getOperand(i), *pUAV);
  567. AddUAV(std::move(pUAV));
  568. }
  569. }
  570. // Load CBuffer records.
  571. if (pCBuffers != nullptr) {
  572. for (unsigned i = 0; i < pCBuffers->getNumOperands(); i++) {
  573. unique_ptr<DxilCBuffer> pCB = llvm::make_unique<DxilCBuffer>();
  574. m_pMDHelper->LoadDxilCBuffer(pCBuffers->getOperand(i), *pCB);
  575. AddCBuffer(std::move(pCB));
  576. }
  577. }
  578. // Load Sampler records.
  579. if (pSamplers != nullptr) {
  580. for (unsigned i = 0; i < pSamplers->getNumOperands(); i++) {
  581. unique_ptr<DxilSampler> pSampler(new DxilSampler);
  582. m_pMDHelper->LoadDxilSampler(pSamplers->getOperand(i), *pSampler);
  583. AddSampler(std::move(pSampler));
  584. }
  585. }
  586. }
  587. llvm::MDTuple *HLModule::EmitResTyAnnotations() {
  588. vector<Metadata *> MDVals;
  589. for (auto &resAnnotation : m_ResTypeAnnotation) {
  590. Metadata *TyMeta =
  591. ValueAsMetadata::get(UndefValue::get(resAnnotation.first));
  592. MDVals.emplace_back(TyMeta);
  593. MDVals.emplace_back(m_pMDHelper->Uint32ToConstMD(
  594. static_cast<unsigned>(resAnnotation.second.first)));
  595. MDVals.emplace_back(m_pMDHelper->Uint32ToConstMD(
  596. static_cast<unsigned>(resAnnotation.second.second)));
  597. }
  598. return MDNode::get(m_Ctx, MDVals);
  599. }
  600. void HLModule::LoadResTyAnnotations(const llvm::MDOperand &MDO) {
  601. if (MDO.get() == nullptr)
  602. return;
  603. const MDTuple *pTupleMD = dyn_cast<MDTuple>(MDO.get());
  604. IFTBOOL(pTupleMD != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
  605. IFTBOOL((pTupleMD->getNumOperands() & 0x3) == 0,
  606. DXC_E_INCORRECT_DXIL_METADATA);
  607. for (unsigned iNode = 0; iNode < pTupleMD->getNumOperands(); iNode += 3) {
  608. const MDOperand &MDTy = pTupleMD->getOperand(iNode);
  609. const MDOperand &MDClass = pTupleMD->getOperand(iNode + 1);
  610. const MDOperand &MDKind = pTupleMD->getOperand(iNode + 2);
  611. Type *Ty = m_pMDHelper->ValueMDToValue(MDTy)->getType();
  612. DXIL::ResourceClass resClass = static_cast<DXIL::ResourceClass>(
  613. DxilMDHelper::ConstMDToUint32(MDClass));
  614. DXIL::ResourceKind kind =
  615. static_cast<DXIL::ResourceKind>(DxilMDHelper::ConstMDToUint32(MDKind));
  616. AddResourceTypeAnnotation(Ty, resClass, kind);
  617. }
  618. }
  619. MDTuple *HLModule::EmitHLShaderProperties() {
  620. return nullptr;
  621. }
  622. void HLModule::LoadHLShaderProperties(const MDOperand &MDO) {
  623. return;
  624. }
  625. MDNode *HLModule::DxilSamplerToMDNode(const DxilSampler &S) {
  626. MDNode *MD = m_pMDHelper->EmitDxilSampler(S);
  627. ValueAsMetadata *ResClass =
  628. m_pMDHelper->Uint32ToConstMD((unsigned)DXIL::ResourceClass::Sampler);
  629. return MDNode::get(m_Ctx, {ResClass, MD});
  630. }
  631. MDNode *HLModule::DxilSRVToMDNode(const DxilResource &SRV) {
  632. MDNode *MD = m_pMDHelper->EmitDxilSRV(SRV);
  633. ValueAsMetadata *ResClass =
  634. m_pMDHelper->Uint32ToConstMD((unsigned)DXIL::ResourceClass::SRV);
  635. return MDNode::get(m_Ctx, {ResClass, MD});
  636. }
  637. MDNode *HLModule::DxilUAVToMDNode(const DxilResource &UAV) {
  638. MDNode *MD = m_pMDHelper->EmitDxilUAV(UAV);
  639. ValueAsMetadata *ResClass =
  640. m_pMDHelper->Uint32ToConstMD((unsigned)DXIL::ResourceClass::UAV);
  641. return MDNode::get(m_Ctx, {ResClass, MD});
  642. }
  643. MDNode *HLModule::DxilCBufferToMDNode(const DxilCBuffer &CB) {
  644. MDNode *MD = m_pMDHelper->EmitDxilCBuffer(CB);
  645. ValueAsMetadata *ResClass =
  646. m_pMDHelper->Uint32ToConstMD((unsigned)DXIL::ResourceClass::CBuffer);
  647. return MDNode::get(m_Ctx, {ResClass, MD});
  648. }
  649. void HLModule::LoadDxilResourceBaseFromMDNode(MDNode *MD, DxilResourceBase &R) {
  650. return m_pMDHelper->LoadDxilResourceBaseFromMDNode(MD, R);
  651. }
  652. void HLModule::AddResourceWithGlobalVariableAndMDNode(llvm::Constant *GV,
  653. llvm::MDNode *MD) {
  654. IFTBOOL(MD->getNumOperands() >= DxilMDHelper::kHLDxilResourceAttributeNumFields,
  655. DXC_E_INCORRECT_DXIL_METADATA);
  656. DxilResource::Class RC =
  657. static_cast<DxilResource::Class>(m_pMDHelper->ConstMDToUint32(
  658. MD->getOperand(DxilMDHelper::kHLDxilResourceAttributeClass)));
  659. const MDOperand &Meta =
  660. MD->getOperand(DxilMDHelper::kHLDxilResourceAttributeMeta);
  661. unsigned rangeSize = 1;
  662. Type *Ty = GV->getType()->getPointerElementType();
  663. if (ArrayType *AT = dyn_cast<ArrayType>(Ty))
  664. rangeSize = AT->getNumElements();
  665. switch (RC) {
  666. case DxilResource::Class::Sampler: {
  667. std::unique_ptr<DxilSampler> S = llvm::make_unique<DxilSampler>();
  668. m_pMDHelper->LoadDxilSampler(Meta, *S);
  669. S->SetGlobalSymbol(GV);
  670. S->SetGlobalName(GV->getName());
  671. S->SetRangeSize(rangeSize);
  672. AddSampler(std::move(S));
  673. } break;
  674. case DxilResource::Class::SRV: {
  675. std::unique_ptr<HLResource> Res = llvm::make_unique<HLResource>();
  676. m_pMDHelper->LoadDxilSRV(Meta, *Res);
  677. Res->SetGlobalSymbol(GV);
  678. Res->SetGlobalName(GV->getName());
  679. Res->SetRangeSize(rangeSize);
  680. AddSRV(std::move(Res));
  681. } break;
  682. case DxilResource::Class::UAV: {
  683. std::unique_ptr<HLResource> Res = llvm::make_unique<HLResource>();
  684. m_pMDHelper->LoadDxilUAV(Meta, *Res);
  685. Res->SetGlobalSymbol(GV);
  686. Res->SetGlobalName(GV->getName());
  687. Res->SetRangeSize(rangeSize);
  688. AddUAV(std::move(Res));
  689. } break;
  690. default:
  691. DXASSERT(0, "Invalid metadata for AddResourceWithGlobalVariableAndMDNode");
  692. }
  693. }
  694. // TODO: Don't check names.
  695. bool HLModule::IsStreamOutputType(llvm::Type *Ty) {
  696. if (StructType *ST = dyn_cast<StructType>(Ty)) {
  697. if (ST->getName().startswith("class.PointStream"))
  698. return true;
  699. if (ST->getName().startswith("class.LineStream"))
  700. return true;
  701. if (ST->getName().startswith("class.TriangleStream"))
  702. return true;
  703. }
  704. return false;
  705. }
  706. bool HLModule::IsStreamOutputPtrType(llvm::Type *Ty) {
  707. if (!Ty->isPointerTy())
  708. return false;
  709. Ty = Ty->getPointerElementType();
  710. return IsStreamOutputType(Ty);
  711. }
  712. bool HLModule::IsHLSLObjectType(llvm::Type *Ty) {
  713. if (llvm::StructType *ST = dyn_cast<llvm::StructType>(Ty)) {
  714. StringRef name = ST->getName();
  715. if (name.startswith("dx.types.wave_t"))
  716. return true;
  717. if (name.endswith("_slice_type"))
  718. return false;
  719. name = name.ltrim("class.");
  720. name = name.ltrim("struct.");
  721. if (name == "SamplerState")
  722. return true;
  723. if (name == "SamplerComparisonState")
  724. return true;
  725. if (name.startswith("TriangleStream"))
  726. return true;
  727. if (name.startswith("PointStream"))
  728. return true;
  729. if (name.startswith("LineStream"))
  730. return true;
  731. if (name.startswith("AppendStructuredBuffer"))
  732. return true;
  733. if (name.startswith("ConsumeStructuredBuffer"))
  734. return true;
  735. if (name.startswith("ConstantBuffer"))
  736. return true;
  737. name = name.ltrim("RasterizerOrdered");
  738. name = name.ltrim("RW");
  739. if (name == "ByteAddressBuffer")
  740. return true;
  741. if (name.startswith("Buffer"))
  742. return true;
  743. if (name.startswith("StructuredBuffer"))
  744. return true;
  745. if (name.startswith("Texture1D"))
  746. return true;
  747. if (name.startswith("Texture1DArray"))
  748. return true;
  749. if (name.startswith("Texture2D"))
  750. return true;
  751. if (name.startswith("Texture2DArray"))
  752. return true;
  753. if (name.startswith("Texture3D"))
  754. return true;
  755. if (name.startswith("TextureCube"))
  756. return true;
  757. if (name.startswith("TextureCubeArray"))
  758. return true;
  759. if (name.startswith("Texture2DMS"))
  760. return true;
  761. if (name.startswith("Texture2DMSArray"))
  762. return true;
  763. }
  764. return false;
  765. }
  766. Type *HLModule::GetArrayEltTy(Type *Ty) {
  767. if (isa<PointerType>(Ty))
  768. Ty = Ty->getPointerElementType();
  769. while (isa<ArrayType>(Ty)) {
  770. Ty = Ty->getArrayElementType();
  771. }
  772. return Ty;
  773. }
  774. unsigned
  775. HLModule::GetLegacyCBufferFieldElementSize(DxilFieldAnnotation &fieldAnnotation,
  776. llvm::Type *Ty,
  777. DxilTypeSystem &typeSys) {
  778. while (isa<ArrayType>(Ty)) {
  779. Ty = Ty->getArrayElementType();
  780. }
  781. // Bytes.
  782. unsigned compSize = fieldAnnotation.GetCompType().Is64Bit()?8:4;
  783. unsigned fieldSize = compSize;
  784. if (Ty->isVectorTy()) {
  785. fieldSize *= Ty->getVectorNumElements();
  786. } else if (StructType *ST = dyn_cast<StructType>(Ty)) {
  787. DxilStructAnnotation *EltAnnotation = typeSys.GetStructAnnotation(ST);
  788. if (EltAnnotation) {
  789. fieldSize = EltAnnotation->GetCBufferSize();
  790. } else {
  791. // Calculate size when don't have annotation.
  792. if (fieldAnnotation.HasMatrixAnnotation()) {
  793. const DxilMatrixAnnotation &matAnnotation =
  794. fieldAnnotation.GetMatrixAnnotation();
  795. unsigned rows = matAnnotation.Rows;
  796. unsigned cols = matAnnotation.Cols;
  797. if (matAnnotation.Orientation == MatrixOrientation::ColumnMajor) {
  798. rows = cols;
  799. cols = matAnnotation.Rows;
  800. } else if (matAnnotation.Orientation != MatrixOrientation::RowMajor) {
  801. // Invalid matrix orientation.
  802. fieldSize = 0;
  803. }
  804. fieldSize = (rows - 1) * 16 + cols * 4;
  805. } else {
  806. // Cannot find struct annotation.
  807. fieldSize = 0;
  808. }
  809. }
  810. }
  811. return fieldSize;
  812. }
  813. bool HLModule::IsStaticGlobal(GlobalVariable *GV) {
  814. return GV->getLinkage() == GlobalValue::LinkageTypes::InternalLinkage &&
  815. GV->getType()->getPointerAddressSpace() == DXIL::kDefaultAddrSpace;
  816. }
  817. bool HLModule::IsSharedMemoryGlobal(llvm::GlobalVariable *GV) {
  818. return GV->getType()->getPointerAddressSpace() == DXIL::kTGSMAddrSpace;
  819. }
  820. void HLModule::GetParameterRowsAndCols(Type *Ty, unsigned &rows, unsigned &cols,
  821. DxilParameterAnnotation &paramAnnotation) {
  822. if (Ty->isPointerTy())
  823. Ty = Ty->getPointerElementType();
  824. // For array input of HS, DS, GS,
  825. // we need to skip the first level which size is based on primitive type.
  826. DxilParamInputQual inputQual = paramAnnotation.GetParamInputQual();
  827. bool skipOneLevelArray = inputQual == DxilParamInputQual::InputPatch;
  828. skipOneLevelArray |= inputQual == DxilParamInputQual::OutputPatch;
  829. skipOneLevelArray |= inputQual == DxilParamInputQual::InputPrimitive;
  830. if (skipOneLevelArray) {
  831. if (Ty->isArrayTy())
  832. Ty = Ty->getArrayElementType();
  833. }
  834. unsigned arraySize = 1;
  835. while (Ty->isArrayTy()) {
  836. arraySize *= Ty->getArrayNumElements();
  837. Ty = Ty->getArrayElementType();
  838. }
  839. rows = 1;
  840. cols = 1;
  841. if (paramAnnotation.HasMatrixAnnotation()) {
  842. const DxilMatrixAnnotation &matrix = paramAnnotation.GetMatrixAnnotation();
  843. if (matrix.Orientation == MatrixOrientation::RowMajor) {
  844. rows = matrix.Rows;
  845. cols = matrix.Cols;
  846. } else {
  847. DXASSERT(matrix.Orientation == MatrixOrientation::ColumnMajor, "");
  848. cols = matrix.Rows;
  849. rows = matrix.Cols;
  850. }
  851. } else if (Ty->isVectorTy())
  852. cols = Ty->getVectorNumElements();
  853. rows *= arraySize;
  854. }
  855. // For legacy data layout, everything less than 32 align to 32.
  856. static const StringRef kLegacyLayoutString = "e-m:e-p:32:32-i1:32:32-i8:32:32-i16:32:32-i64:64-f16:32-f80:32-n8:16:32-a:0:32-S32";
  857. const char *HLModule::GetLegacyDataLayoutDesc() {
  858. return kLegacyLayoutString.data();
  859. }
  860. static Value *MergeGEP(GEPOperator *SrcGEP, GetElementPtrInst *GEP) {
  861. IRBuilder<> Builder(GEP);
  862. SmallVector<Value *, 8> Indices;
  863. // Find out whether the last index in the source GEP is a sequential idx.
  864. bool EndsWithSequential = false;
  865. for (gep_type_iterator I = gep_type_begin(*SrcGEP), E = gep_type_end(*SrcGEP);
  866. I != E; ++I)
  867. EndsWithSequential = !(*I)->isStructTy();
  868. if (EndsWithSequential) {
  869. Value *Sum;
  870. Value *SO1 = SrcGEP->getOperand(SrcGEP->getNumOperands() - 1);
  871. Value *GO1 = GEP->getOperand(1);
  872. if (SO1 == Constant::getNullValue(SO1->getType())) {
  873. Sum = GO1;
  874. } else if (GO1 == Constant::getNullValue(GO1->getType())) {
  875. Sum = SO1;
  876. } else {
  877. // If they aren't the same type, then the input hasn't been processed
  878. // by the loop above yet (which canonicalizes sequential index types to
  879. // intptr_t). Just avoid transforming this until the input has been
  880. // normalized.
  881. if (SO1->getType() != GO1->getType())
  882. return nullptr;
  883. // Only do the combine when GO1 and SO1 are both constants. Only in
  884. // this case, we are sure the cost after the merge is never more than
  885. // that before the merge.
  886. if (!isa<Constant>(GO1) || !isa<Constant>(SO1))
  887. return nullptr;
  888. Sum = Builder.CreateAdd(SO1, GO1);
  889. }
  890. // Update the GEP in place if possible.
  891. if (SrcGEP->getNumOperands() == 2) {
  892. GEP->setOperand(0, SrcGEP->getOperand(0));
  893. GEP->setOperand(1, Sum);
  894. return GEP;
  895. }
  896. Indices.append(SrcGEP->op_begin() + 1, SrcGEP->op_end() - 1);
  897. Indices.push_back(Sum);
  898. Indices.append(GEP->op_begin() + 2, GEP->op_end());
  899. } else if (isa<Constant>(*GEP->idx_begin()) &&
  900. cast<Constant>(*GEP->idx_begin())->isNullValue() &&
  901. SrcGEP->getNumOperands() != 1) {
  902. // Otherwise we can do the fold if the first index of the GEP is a zero
  903. Indices.append(SrcGEP->op_begin() + 1, SrcGEP->op_end());
  904. Indices.append(GEP->idx_begin() + 1, GEP->idx_end());
  905. }
  906. if (!Indices.empty())
  907. return Builder.CreateInBoundsGEP(SrcGEP->getSourceElementType(),
  908. SrcGEP->getOperand(0), Indices,
  909. GEP->getName());
  910. else
  911. llvm_unreachable("must merge");
  912. }
  913. void HLModule::MergeGepUse(Value *V) {
  914. for (auto U = V->user_begin(); U != V->user_end();) {
  915. auto Use = U++;
  916. if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(*Use)) {
  917. if (GEPOperator *prevGEP = dyn_cast<GEPOperator>(V)) {
  918. // merge the 2 GEPs
  919. Value *newGEP = MergeGEP(prevGEP, GEP);
  920. // Don't need to replace when GEP is updated in place
  921. if (newGEP != GEP) {
  922. GEP->replaceAllUsesWith(newGEP);
  923. GEP->eraseFromParent();
  924. }
  925. MergeGepUse(newGEP);
  926. } else {
  927. MergeGepUse(*Use);
  928. }
  929. } else if (GEPOperator *GEPOp = dyn_cast<GEPOperator>(*Use)) {
  930. if (GEPOperator *prevGEP = dyn_cast<GEPOperator>(V)) {
  931. // merge the 2 GEPs
  932. Value *newGEP = MergeGEP(prevGEP, GEP);
  933. // Don't need to replace when GEP is updated in place
  934. if (newGEP != GEP) {
  935. GEP->replaceAllUsesWith(newGEP);
  936. GEP->eraseFromParent();
  937. }
  938. MergeGepUse(newGEP);
  939. } else {
  940. MergeGepUse(*Use);
  941. }
  942. }
  943. }
  944. if (V->user_empty()) {
  945. // Only remove GEP here, root ptr will be removed by DCE.
  946. if (GetElementPtrInst *I = dyn_cast<GetElementPtrInst>(V))
  947. I->eraseFromParent();
  948. }
  949. }
  950. template<typename BuilderTy>
  951. CallInst *HLModule::EmitHLOperationCall(BuilderTy &Builder,
  952. HLOpcodeGroup group, unsigned opcode,
  953. Type *RetType,
  954. ArrayRef<Value *> paramList,
  955. llvm::Module &M) {
  956. SmallVector<llvm::Type *, 4> paramTyList;
  957. // Add the opcode param
  958. llvm::Type *opcodeTy = llvm::Type::getInt32Ty(M.getContext());
  959. paramTyList.emplace_back(opcodeTy);
  960. for (Value *param : paramList) {
  961. paramTyList.emplace_back(param->getType());
  962. }
  963. llvm::FunctionType *funcTy =
  964. llvm::FunctionType::get(RetType, paramTyList, false);
  965. Function *opFunc = GetOrCreateHLFunction(M, funcTy, group, opcode);
  966. SmallVector<Value *, 4> opcodeParamList;
  967. Value *opcodeConst = Constant::getIntegerValue(opcodeTy, APInt(32, opcode));
  968. opcodeParamList.emplace_back(opcodeConst);
  969. opcodeParamList.append(paramList.begin(), paramList.end());
  970. return Builder.CreateCall(opFunc, opcodeParamList);
  971. }
  972. template
  973. CallInst *HLModule::EmitHLOperationCall(IRBuilder<> &Builder,
  974. HLOpcodeGroup group, unsigned opcode,
  975. Type *RetType,
  976. ArrayRef<Value *> paramList,
  977. llvm::Module &M);
  978. unsigned HLModule::FindCastOp(bool fromUnsigned, bool toUnsigned,
  979. llvm::Type *SrcTy, llvm::Type *DstTy) {
  980. Instruction::CastOps castOp = llvm::Instruction::CastOps::BitCast;
  981. if (SrcTy->isAggregateType() || DstTy->isAggregateType())
  982. return llvm::Instruction::CastOps::BitCast;
  983. uint32_t SrcBitSize = SrcTy->getScalarSizeInBits();
  984. uint32_t DstBitSize = DstTy->getScalarSizeInBits();
  985. if (SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy()) {
  986. if (SrcBitSize > DstBitSize)
  987. return Instruction::Trunc;
  988. if (toUnsigned)
  989. return Instruction::ZExt;
  990. else
  991. return Instruction::SExt;
  992. }
  993. if (SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy()) {
  994. if (SrcBitSize > DstBitSize)
  995. return Instruction::FPTrunc;
  996. else
  997. return Instruction::FPExt;
  998. }
  999. if (SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy())
  1000. if (fromUnsigned)
  1001. return Instruction::UIToFP;
  1002. else
  1003. return Instruction::SIToFP;
  1004. if (SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy())
  1005. if (toUnsigned)
  1006. return Instruction::FPToUI;
  1007. else
  1008. return Instruction::FPToSI;
  1009. DXASSERT_NOMSG(0);
  1010. return castOp;
  1011. }
  1012. bool HLModule::HasPreciseAttributeWithMetadata(Instruction *I) {
  1013. MDNode *preciseNode =
  1014. I->getMetadata(DxilMDHelper::kDxilPreciseAttributeMDName);
  1015. return preciseNode != nullptr;
  1016. }
  1017. void HLModule::MarkPreciseAttributeWithMetadata(Instruction *I) {
  1018. LLVMContext &Ctx = I->getContext();
  1019. MDNode *preciseNode = MDNode::get(
  1020. Ctx,
  1021. {ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Ctx), 1))});
  1022. I->setMetadata(DxilMDHelper::kDxilPreciseAttributeMDName, preciseNode);
  1023. }
  1024. void HLModule::ClearPreciseAttributeWithMetadata(Instruction *I) {
  1025. I->setMetadata(DxilMDHelper::kDxilPreciseAttributeMDName, nullptr);
  1026. }
  1027. static void MarkPreciseAttribute(Function *F) {
  1028. LLVMContext &Ctx = F->getContext();
  1029. MDNode *preciseNode = MDNode::get(
  1030. Ctx, {MDString::get(Ctx, DxilMDHelper::kDxilPreciseAttributeMDName)});
  1031. F->setMetadata(DxilMDHelper::kDxilPreciseAttributeMDName, preciseNode);
  1032. }
  1033. static void MarkPreciseAttributeOnValWithFunctionCall(
  1034. llvm::Value *V, llvm::IRBuilder<> &Builder, llvm::Module &M) {
  1035. Type *Ty = V->getType();
  1036. Type *EltTy = Ty->getScalarType();
  1037. // TODO: Only do this on basic types.
  1038. FunctionType *preciseFuncTy =
  1039. FunctionType::get(Type::getVoidTy(M.getContext()), {EltTy}, false);
  1040. // The function will be deleted after precise propagate.
  1041. std::string preciseFuncName = "dx.attribute.precise.";
  1042. raw_string_ostream mangledNameStr(preciseFuncName);
  1043. EltTy->print(mangledNameStr);
  1044. mangledNameStr.flush();
  1045. Function *preciseFunc =
  1046. cast<Function>(M.getOrInsertFunction(preciseFuncName, preciseFuncTy));
  1047. if (!HLModule::HasPreciseAttribute(preciseFunc))
  1048. MarkPreciseAttribute(preciseFunc);
  1049. if (Ty->isVectorTy()) {
  1050. for (unsigned i = 0; i < Ty->getVectorNumElements(); i++) {
  1051. Value *Elt = Builder.CreateExtractElement(V, i);
  1052. Builder.CreateCall(preciseFunc, {Elt});
  1053. }
  1054. } else
  1055. Builder.CreateCall(preciseFunc, {V});
  1056. }
  1057. void HLModule::MarkPreciseAttributeOnPtrWithFunctionCall(llvm::Value *Ptr,
  1058. llvm::Module &M) {
  1059. for (User *U : Ptr->users()) {
  1060. // Skip load inst.
  1061. if (LoadInst *LI = dyn_cast<LoadInst>(U))
  1062. continue;
  1063. if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
  1064. Value *V = SI->getValueOperand();
  1065. if (isa<Instruction>(V)) {
  1066. // Mark the Value with function call.
  1067. IRBuilder<> Builder(SI);
  1068. MarkPreciseAttributeOnValWithFunctionCall(V, Builder, M);
  1069. }
  1070. } else if (CallInst *CI = dyn_cast<CallInst>(U)) {
  1071. if (CI->getType()->isVoidTy()) {
  1072. IRBuilder<> Builder(CI);
  1073. // For void type, cannot use as function arg.
  1074. // Mark all arg for it?
  1075. for (auto &arg : CI->arg_operands()) {
  1076. MarkPreciseAttributeOnValWithFunctionCall(arg, Builder, M);
  1077. }
  1078. } else {
  1079. IRBuilder<> Builder(CI->getNextNode());
  1080. MarkPreciseAttributeOnValWithFunctionCall(CI, Builder, M);
  1081. }
  1082. } else {
  1083. // Must be GEP here.
  1084. GetElementPtrInst *GEP = cast<GetElementPtrInst>(U);
  1085. MarkPreciseAttributeOnPtrWithFunctionCall(GEP, M);
  1086. }
  1087. }
  1088. }
  1089. bool HLModule::HasPreciseAttribute(Function *F) {
  1090. MDNode *preciseNode =
  1091. F->getMetadata(DxilMDHelper::kDxilPreciseAttributeMDName);
  1092. return preciseNode != nullptr;
  1093. }
  1094. void HLModule::MarkDxilResourceAttrib(llvm::Function *F, MDNode *MD) {
  1095. F->setMetadata(DxilMDHelper::kHLDxilResourceAttributeMDName, MD);
  1096. }
  1097. MDNode *HLModule::GetDxilResourceAttrib(llvm::Function *F) {
  1098. return F->getMetadata(DxilMDHelper::kHLDxilResourceAttributeMDName);
  1099. }
  1100. void HLModule::MarkDxilResourceAttrib(llvm::Argument *Arg, llvm::MDNode *MD) {
  1101. unsigned i = Arg->getArgNo();
  1102. Function *F = Arg->getParent();
  1103. DxilFunctionAnnotation *FuncAnnot = m_pTypeSystem->GetFunctionAnnotation(F);
  1104. if (!FuncAnnot) {
  1105. DXASSERT(0, "Invalid function");
  1106. return;
  1107. }
  1108. DxilParameterAnnotation &ParamAnnot = FuncAnnot->GetParameterAnnotation(i);
  1109. ParamAnnot.SetResourceAttribute(MD);
  1110. }
  1111. MDNode *HLModule::GetDxilResourceAttrib(llvm::Argument *Arg) {
  1112. unsigned i = Arg->getArgNo();
  1113. Function *F = Arg->getParent();
  1114. DxilFunctionAnnotation *FuncAnnot = m_pTypeSystem->GetFunctionAnnotation(F);
  1115. if (!FuncAnnot)
  1116. return nullptr;
  1117. DxilParameterAnnotation &ParamAnnot = FuncAnnot->GetParameterAnnotation(i);
  1118. return ParamAnnot.GetResourceAttribute();
  1119. }
  1120. MDNode *HLModule::GetDxilResourceAttrib(Type *Ty, Module &M) {
  1121. for (Function &F : M.functions()) {
  1122. if (hlsl::GetHLOpcodeGroupByName(&F) == HLOpcodeGroup::HLCreateHandle) {
  1123. Type *ResTy = F.getFunctionType()->getParamType(
  1124. HLOperandIndex::kCreateHandleResourceOpIdx);
  1125. if (ResTy == Ty)
  1126. return GetDxilResourceAttrib(&F);
  1127. }
  1128. }
  1129. return nullptr;
  1130. }
  1131. DIGlobalVariable *
  1132. HLModule::FindGlobalVariableDebugInfo(GlobalVariable *GV,
  1133. DebugInfoFinder &DbgInfoFinder) {
  1134. struct GlobalFinder {
  1135. GlobalVariable *GV;
  1136. bool operator()(llvm::DIGlobalVariable *const arg) const {
  1137. return arg->getVariable() == GV;
  1138. }
  1139. };
  1140. GlobalFinder F = {GV};
  1141. DebugInfoFinder::global_variable_iterator Found =
  1142. std::find_if(DbgInfoFinder.global_variables().begin(),
  1143. DbgInfoFinder.global_variables().end(), F);
  1144. if (Found != DbgInfoFinder.global_variables().end()) {
  1145. return *Found;
  1146. }
  1147. return nullptr;
  1148. }
  1149. static void AddDIGlobalVariable(DIBuilder &Builder, DIGlobalVariable *LocDIGV,
  1150. StringRef Name, DIType *DITy,
  1151. GlobalVariable *GV, DebugInfoFinder &DbgInfoFinder, bool removeLocDIGV) {
  1152. DIGlobalVariable *EltDIGV = Builder.createGlobalVariable(
  1153. LocDIGV->getScope(), Name, GV->getName(), LocDIGV->getFile(),
  1154. LocDIGV->getLine(), DITy, false, GV);
  1155. DICompileUnit *DICU = dyn_cast<DICompileUnit>(LocDIGV->getScope());
  1156. if (!DICU) {
  1157. DISubprogram *DIS = dyn_cast<DISubprogram>(LocDIGV->getScope());
  1158. if (DIS) {
  1159. // Find the DICU which has this Subprogram.
  1160. NamedMDNode *CompileUnits = GV->getParent()->getNamedMetadata("llvm.dbg.cu");
  1161. DXASSERT_NOMSG(CompileUnits);
  1162. for (unsigned I = 0, E = CompileUnits->getNumOperands(); I != E; ++I) {
  1163. auto *CU = cast<DICompileUnit>(CompileUnits->getOperand(I));
  1164. DXASSERT(CU , "Expected valid compile unit");
  1165. for (DISubprogram *SP : CU->getSubprograms()) {
  1166. if (SP == DIS) {
  1167. DICU = CU;
  1168. break;
  1169. }
  1170. }
  1171. }
  1172. }
  1173. }
  1174. DXASSERT_NOMSG(DICU);
  1175. // Add global to CU.
  1176. auto *GlobalVariables = DICU->getRawGlobalVariables();
  1177. DXASSERT_NOMSG(GlobalVariables);
  1178. MDTuple *GTuple = cast<MDTuple>(GlobalVariables);
  1179. std::vector<Metadata *> AllGVs(GTuple->operands().begin(),
  1180. GTuple->operands().end());
  1181. if (removeLocDIGV) {
  1182. auto locIt = std::find(AllGVs.begin(), AllGVs.end(), LocDIGV);
  1183. AllGVs.erase(locIt);
  1184. }
  1185. AllGVs.emplace_back(EltDIGV);
  1186. DICU->replaceGlobalVariables(MDTuple::get(GV->getContext(), AllGVs));
  1187. DXVERIFY_NOMSG(DbgInfoFinder.appendGlobalVariable(EltDIGV));
  1188. }
  1189. void HLModule::CreateElementGlobalVariableDebugInfo(
  1190. GlobalVariable *GV, DebugInfoFinder &DbgInfoFinder, GlobalVariable *EltGV,
  1191. unsigned sizeInBits, unsigned alignInBits, unsigned offsetInBits,
  1192. StringRef eltName) {
  1193. DIGlobalVariable *DIGV = FindGlobalVariableDebugInfo(GV, DbgInfoFinder);
  1194. DXASSERT_NOMSG(DIGV);
  1195. DIBuilder Builder(*GV->getParent());
  1196. DITypeIdentifierMap EmptyMap;
  1197. DIType *DITy = DIGV->getType().resolve(EmptyMap);
  1198. DIScope *DITyScope = DITy->getScope().resolve(EmptyMap);
  1199. // Create Elt type.
  1200. DIType *EltDITy =
  1201. Builder.createMemberType(DITyScope, DITy->getName().str() + eltName.str(),
  1202. DITy->getFile(), DITy->getLine(), sizeInBits,
  1203. alignInBits, offsetInBits, /*Flags*/ 0, DITy);
  1204. AddDIGlobalVariable(Builder, DIGV, DIGV->getName().str() + eltName.str(),
  1205. EltDITy, EltGV, DbgInfoFinder, /*removeDIGV*/false);
  1206. }
  1207. void HLModule::UpdateGlobalVariableDebugInfo(
  1208. llvm::GlobalVariable *GV, llvm::DebugInfoFinder &DbgInfoFinder,
  1209. llvm::GlobalVariable *NewGV) {
  1210. DIGlobalVariable *DIGV = FindGlobalVariableDebugInfo(GV, DbgInfoFinder);
  1211. DXASSERT_NOMSG(DIGV);
  1212. DIBuilder Builder(*GV->getParent());
  1213. DITypeIdentifierMap EmptyMap;
  1214. DIType *DITy = DIGV->getType().resolve(EmptyMap);
  1215. AddDIGlobalVariable(Builder, DIGV, DIGV->getName(), DITy, NewGV,
  1216. DbgInfoFinder,/*removeDIGV*/true);
  1217. }
  1218. DebugInfoFinder &HLModule::GetOrCreateDebugInfoFinder() {
  1219. if (m_pDebugInfoFinder == nullptr) {
  1220. m_pDebugInfoFinder = llvm::make_unique<llvm::DebugInfoFinder>();
  1221. m_pDebugInfoFinder->processModule(*m_pModule);
  1222. }
  1223. return *m_pDebugInfoFinder;
  1224. }
  1225. //------------------------------------------------------------------------------
  1226. //
  1227. // Signature methods.
  1228. //
  1229. HLExtraPropertyHelper::HLExtraPropertyHelper(llvm::Module *pModule)
  1230. : DxilExtraPropertyHelper(pModule) {
  1231. }
  1232. void HLExtraPropertyHelper::EmitSignatureElementProperties(const DxilSignatureElement &SE,
  1233. vector<Metadata *> &MDVals) {
  1234. }
  1235. void HLExtraPropertyHelper::LoadSignatureElementProperties(const MDOperand &MDO,
  1236. DxilSignatureElement &SE) {
  1237. if (MDO.get() == nullptr)
  1238. return;
  1239. }
  1240. } // namespace hlsl
  1241. namespace llvm {
  1242. hlsl::HLModule &Module::GetOrCreateHLModule(bool skipInit) {
  1243. std::unique_ptr<hlsl::HLModule> M;
  1244. if (!HasHLModule()) {
  1245. M = llvm::make_unique<hlsl::HLModule>(this);
  1246. if (!skipInit) {
  1247. M->LoadHLMetadata();
  1248. }
  1249. SetHLModule(M.release());
  1250. }
  1251. return GetHLModule();
  1252. }
  1253. void Module::ResetHLModule() {
  1254. if (HasHLModule()) {
  1255. delete TheHLModule;
  1256. TheHLModule = nullptr;
  1257. }
  1258. }
  1259. }