HLModule.cpp 49 KB

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