2
0

HLModule.cpp 43 KB

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