2
0

HLModule.cpp 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396
  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/DXIL/DxilOperations.h"
  12. #include "dxc/DXIL/DxilShaderModel.h"
  13. #include "dxc/DXIL/DxilCBuffer.h"
  14. #include "dxc/HLSL/HLModule.h"
  15. #include "dxc/DXIL/DxilTypeSystem.h"
  16. #include "dxc/DXIL/DxilUtil.h"
  17. #include "dxc/Support/WinAdapter.h"
  18. #include "llvm/ADT/STLExtras.h"
  19. #include "llvm/IR/Constants.h"
  20. #include "llvm/IR/Function.h"
  21. #include "llvm/IR/IRBuilder.h"
  22. #include "llvm/IR/LLVMContext.h"
  23. #include "llvm/IR/Metadata.h"
  24. #include "llvm/IR/Module.h"
  25. #include "llvm/IR/DebugInfo.h"
  26. #include "llvm/IR/DIBuilder.h"
  27. #include "llvm/Support/raw_ostream.h"
  28. #include "llvm/IR/GetElementPtrTypeIterator.h"
  29. #include "llvm/Analysis/ValueTracking.h"
  30. using namespace llvm;
  31. using std::string;
  32. using std::vector;
  33. using std::unique_ptr;
  34. namespace hlsl {
  35. // Avoid dependency on HLModule from llvm::Module using this:
  36. void HLModule_RemoveGlobal(llvm::Module* M, llvm::GlobalObject* G) {
  37. if (M && G && M->HasHLModule()) {
  38. if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(G))
  39. M->GetHLModule().RemoveGlobal(GV);
  40. else if (llvm::Function *F = dyn_cast<llvm::Function>(G))
  41. M->GetHLModule().RemoveFunction(F);
  42. }
  43. }
  44. void HLModule_ResetModule(llvm::Module* M) {
  45. if (M && M->HasHLModule())
  46. delete &M->GetHLModule();
  47. M->SetHLModule(nullptr);
  48. }
  49. //------------------------------------------------------------------------------
  50. //
  51. // HLModule methods.
  52. //
  53. HLModule::HLModule(Module *pModule)
  54. : m_Ctx(pModule->getContext())
  55. , m_pModule(pModule)
  56. , m_pEntryFunc(nullptr)
  57. , m_EntryName("")
  58. , m_pMDHelper(llvm::make_unique<DxilMDHelper>(
  59. pModule, llvm::make_unique<HLExtraPropertyHelper>(pModule)))
  60. , m_pDebugInfoFinder(nullptr)
  61. , m_pSM(nullptr)
  62. , m_DxilMajor(DXIL::kDxilMajor)
  63. , m_DxilMinor(DXIL::kDxilMinor)
  64. , m_ValMajor(0)
  65. , m_ValMinor(0)
  66. , m_Float32DenormMode(DXIL::Float32DenormMode::Any)
  67. , m_pOP(llvm::make_unique<OP>(pModule->getContext(), pModule))
  68. , m_AutoBindingSpace(UINT_MAX)
  69. , m_DefaultLinkage(DXIL::DefaultLinkage::Default)
  70. , m_pTypeSystem(llvm::make_unique<DxilTypeSystem>(pModule)) {
  71. DXASSERT_NOMSG(m_pModule != nullptr);
  72. m_pModule->pfnRemoveGlobal = &HLModule_RemoveGlobal;
  73. m_pModule->pfnResetHLModule = &HLModule_ResetModule;
  74. // Pin LLVM dump methods. TODO: make debug-only.
  75. void (__thiscall Module::*pfnModuleDump)() const = &Module::dump;
  76. void (__thiscall Type::*pfnTypeDump)() const = &Type::dump;
  77. m_pUnused = (char *)&pfnModuleDump - (char *)&pfnTypeDump;
  78. }
  79. HLModule::~HLModule() {
  80. if (m_pModule->pfnRemoveGlobal == &HLModule_RemoveGlobal)
  81. m_pModule->pfnRemoveGlobal = nullptr;
  82. }
  83. LLVMContext &HLModule::GetCtx() const { return m_Ctx; }
  84. Module *HLModule::GetModule() const { return m_pModule; }
  85. OP *HLModule::GetOP() const { return m_pOP.get(); }
  86. void HLModule::SetValidatorVersion(unsigned ValMajor, unsigned ValMinor) {
  87. m_ValMajor = ValMajor;
  88. m_ValMinor = ValMinor;
  89. }
  90. void HLModule::GetValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const {
  91. ValMajor = m_ValMajor;
  92. ValMinor = m_ValMinor;
  93. }
  94. void HLModule::SetShaderModel(const ShaderModel *pSM) {
  95. DXASSERT(m_pSM == nullptr, "shader model must not change for the module");
  96. DXASSERT(pSM != nullptr && pSM->IsValidForDxil(), "shader model must be valid");
  97. m_pSM = pSM;
  98. m_pSM->GetDxilVersion(m_DxilMajor, m_DxilMinor);
  99. m_pMDHelper->SetShaderModel(m_pSM);
  100. m_SerializedRootSignature.clear();
  101. }
  102. const ShaderModel *HLModule::GetShaderModel() const {
  103. return m_pSM;
  104. }
  105. uint32_t HLOptions::GetHLOptionsRaw() const {
  106. union Cast {
  107. Cast(const HLOptions &options) {
  108. hlOptions = options;
  109. }
  110. HLOptions hlOptions;
  111. uint32_t rawData;
  112. };
  113. static_assert(sizeof(uint32_t) == sizeof(HLOptions),
  114. "size must match to make sure no undefined bits when cast");
  115. Cast rawCast(*this);
  116. return rawCast.rawData;
  117. }
  118. void HLOptions::SetHLOptionsRaw(uint32_t data) {
  119. union Cast {
  120. Cast(uint32_t data) {
  121. rawData = data;
  122. }
  123. HLOptions hlOptions;
  124. uint64_t rawData;
  125. };
  126. Cast rawCast(data);
  127. *this = rawCast.hlOptions;
  128. }
  129. void HLModule::SetHLOptions(HLOptions &opts) {
  130. m_Options = opts;
  131. }
  132. const HLOptions &HLModule::GetHLOptions() const {
  133. return m_Options;
  134. }
  135. void HLModule::SetAutoBindingSpace(uint32_t Space) {
  136. m_AutoBindingSpace = Space;
  137. }
  138. uint32_t HLModule::GetAutoBindingSpace() const {
  139. return m_AutoBindingSpace;
  140. }
  141. Function *HLModule::GetEntryFunction() const {
  142. return m_pEntryFunc;
  143. }
  144. Function *HLModule::GetPatchConstantFunction() {
  145. if (!m_pSM->IsHS())
  146. return nullptr;
  147. if (!m_pEntryFunc)
  148. return nullptr;
  149. DxilFunctionProps &funcProps = GetDxilFunctionProps(m_pEntryFunc);
  150. return funcProps.ShaderProps.HS.patchConstantFunc;
  151. }
  152. void HLModule::SetEntryFunction(Function *pEntryFunc) {
  153. m_pEntryFunc = pEntryFunc;
  154. }
  155. const string &HLModule::GetEntryFunctionName() const { return m_EntryName; }
  156. void HLModule::SetEntryFunctionName(const string &name) { m_EntryName = name; }
  157. template<typename T> unsigned
  158. HLModule::AddResource(vector<unique_ptr<T> > &Vec, unique_ptr<T> pRes) {
  159. DXASSERT_NOMSG((unsigned)Vec.size() < UINT_MAX);
  160. unsigned Id = (unsigned)Vec.size();
  161. Vec.emplace_back(std::move(pRes));
  162. return Id;
  163. }
  164. unsigned HLModule::AddCBuffer(unique_ptr<DxilCBuffer> pCBuffer) {
  165. return AddResource<DxilCBuffer>(m_CBuffers, std::move(pCBuffer));
  166. }
  167. DxilCBuffer &HLModule::GetCBuffer(unsigned idx) {
  168. return *m_CBuffers[idx];
  169. }
  170. const DxilCBuffer &HLModule::GetCBuffer(unsigned idx) const {
  171. return *m_CBuffers[idx];
  172. }
  173. const vector<unique_ptr<DxilCBuffer> > &HLModule::GetCBuffers() const {
  174. return m_CBuffers;
  175. }
  176. unsigned HLModule::AddSampler(unique_ptr<DxilSampler> pSampler) {
  177. return AddResource<DxilSampler>(m_Samplers, std::move(pSampler));
  178. }
  179. DxilSampler &HLModule::GetSampler(unsigned idx) {
  180. return *m_Samplers[idx];
  181. }
  182. const DxilSampler &HLModule::GetSampler(unsigned idx) const {
  183. return *m_Samplers[idx];
  184. }
  185. const vector<unique_ptr<DxilSampler> > &HLModule::GetSamplers() const {
  186. return m_Samplers;
  187. }
  188. unsigned HLModule::AddSRV(unique_ptr<HLResource> pSRV) {
  189. return AddResource<HLResource>(m_SRVs, std::move(pSRV));
  190. }
  191. HLResource &HLModule::GetSRV(unsigned idx) {
  192. return *m_SRVs[idx];
  193. }
  194. const HLResource &HLModule::GetSRV(unsigned idx) const {
  195. return *m_SRVs[idx];
  196. }
  197. const vector<unique_ptr<HLResource> > &HLModule::GetSRVs() const {
  198. return m_SRVs;
  199. }
  200. unsigned HLModule::AddUAV(unique_ptr<HLResource> pUAV) {
  201. return AddResource<HLResource>(m_UAVs, std::move(pUAV));
  202. }
  203. HLResource &HLModule::GetUAV(unsigned idx) {
  204. return *m_UAVs[idx];
  205. }
  206. const HLResource &HLModule::GetUAV(unsigned idx) const {
  207. return *m_UAVs[idx];
  208. }
  209. const vector<unique_ptr<HLResource> > &HLModule::GetUAVs() const {
  210. return m_UAVs;
  211. }
  212. void HLModule::RemoveFunction(llvm::Function *F) {
  213. DXASSERT_NOMSG(F != nullptr);
  214. m_DxilFunctionPropsMap.erase(F);
  215. if (m_pTypeSystem.get()->GetFunctionAnnotation(F))
  216. m_pTypeSystem.get()->EraseFunctionAnnotation(F);
  217. m_pOP->RemoveFunction(F);
  218. }
  219. namespace {
  220. template <typename TResource>
  221. bool RemoveResource(std::vector<std::unique_ptr<TResource>> &vec,
  222. GlobalVariable *pVariable, bool keepAllocated) {
  223. for (auto p = vec.begin(), e = vec.end(); p != e; ++p) {
  224. if ((*p)->GetGlobalSymbol() != pVariable)
  225. continue;
  226. if (keepAllocated && (*p)->IsAllocated()) {
  227. // Keep the resource, but it has no more symbol.
  228. (*p)->SetGlobalSymbol(UndefValue::get(pVariable->getType()));
  229. } else {
  230. // Erase the resource alltogether and update IDs of subsequent ones
  231. p = vec.erase(p);
  232. for (e = vec.end(); p != e; ++p) {
  233. unsigned ID = (*p)->GetID() - 1;
  234. (*p)->SetID(ID);
  235. }
  236. }
  237. return true;
  238. }
  239. return false;
  240. }
  241. }
  242. void HLModule::RemoveGlobal(llvm::GlobalVariable *GV) {
  243. DXASSERT_NOMSG(GV != nullptr);
  244. // With legacy resource reservation, we must keep unused resources around
  245. // when they have a register allocation because they prevent that
  246. // register range from being allocated to other resources.
  247. bool keepAllocated = GetHLOptions().bLegacyResourceReservation;
  248. // This could be considerably faster - check variable type to see which
  249. // resource type this is rather than scanning all lists, and look for
  250. // usage and removal patterns.
  251. if (RemoveResource(m_CBuffers, GV, keepAllocated))
  252. return;
  253. if (RemoveResource(m_SRVs, GV, keepAllocated))
  254. return;
  255. if (RemoveResource(m_UAVs, GV, keepAllocated))
  256. return;
  257. if (RemoveResource(m_Samplers, GV, keepAllocated))
  258. return;
  259. // TODO: do m_TGSMVariables and m_StreamOutputs need maintenance?
  260. }
  261. HLModule::tgsm_iterator HLModule::tgsm_begin() {
  262. return m_TGSMVariables.begin();
  263. }
  264. HLModule::tgsm_iterator HLModule::tgsm_end() {
  265. return m_TGSMVariables.end();
  266. }
  267. void HLModule::AddGroupSharedVariable(GlobalVariable *GV) {
  268. m_TGSMVariables.emplace_back(GV);
  269. }
  270. std::vector<uint8_t> &HLModule::GetSerializedRootSignature() {
  271. return m_SerializedRootSignature;
  272. }
  273. void HLModule::SetSerializedRootSignature(const uint8_t *pData, unsigned size) {
  274. m_SerializedRootSignature.assign(pData, pData+size);
  275. }
  276. DxilTypeSystem &HLModule::GetTypeSystem() {
  277. return *m_pTypeSystem;
  278. }
  279. DxilTypeSystem *HLModule::ReleaseTypeSystem() {
  280. return m_pTypeSystem.release();
  281. }
  282. hlsl::OP *HLModule::ReleaseOP() {
  283. return m_pOP.release();
  284. }
  285. DxilFunctionPropsMap &&HLModule::ReleaseFunctionPropsMap() {
  286. return std::move(m_DxilFunctionPropsMap);
  287. }
  288. void HLModule::EmitLLVMUsed() {
  289. if (m_LLVMUsed.empty())
  290. return;
  291. vector<llvm::Constant*> GVs;
  292. GVs.resize(m_LLVMUsed.size());
  293. for (size_t i = 0, e = m_LLVMUsed.size(); i != e; i++) {
  294. GVs[i] = ConstantExpr::getAddrSpaceCast(cast<llvm::Constant>(&*m_LLVMUsed[i]), Type::getInt8PtrTy(m_Ctx));
  295. }
  296. ArrayType *pATy = ArrayType::get(Type::getInt8PtrTy(m_Ctx), GVs.size());
  297. GlobalVariable *pGV = new GlobalVariable(*m_pModule, pATy, false,
  298. GlobalValue::AppendingLinkage,
  299. ConstantArray::get(pATy, GVs),
  300. "llvm.used");
  301. pGV->setSection("llvm.metadata");
  302. }
  303. vector<GlobalVariable* > &HLModule::GetLLVMUsed() {
  304. return m_LLVMUsed;
  305. }
  306. bool HLModule::HasDxilFunctionProps(llvm::Function *F) {
  307. return m_DxilFunctionPropsMap.find(F) != m_DxilFunctionPropsMap.end();
  308. }
  309. DxilFunctionProps &HLModule::GetDxilFunctionProps(llvm::Function *F) {
  310. DXASSERT(m_DxilFunctionPropsMap.count(F) != 0, "cannot find F in map");
  311. return *m_DxilFunctionPropsMap[F];
  312. }
  313. void HLModule::AddDxilFunctionProps(llvm::Function *F, std::unique_ptr<DxilFunctionProps> &info) {
  314. DXASSERT(m_DxilFunctionPropsMap.count(F) == 0, "F already in map, info will be overwritten");
  315. DXASSERT_NOMSG(info->shaderKind != DXIL::ShaderKind::Invalid);
  316. m_DxilFunctionPropsMap[F] = std::move(info);
  317. }
  318. void HLModule::SetPatchConstantFunctionForHS(llvm::Function *hullShaderFunc, llvm::Function *patchConstantFunc) {
  319. auto propIter = m_DxilFunctionPropsMap.find(hullShaderFunc);
  320. DXASSERT(propIter != m_DxilFunctionPropsMap.end(), "else Hull Shader missing function props");
  321. DxilFunctionProps &props = *(propIter->second);
  322. DXASSERT(props.IsHS(), "else hullShaderFunc is not a Hull Shader");
  323. if (props.ShaderProps.HS.patchConstantFunc)
  324. m_PatchConstantFunctions.erase(props.ShaderProps.HS.patchConstantFunc);
  325. props.ShaderProps.HS.patchConstantFunc = patchConstantFunc;
  326. if (patchConstantFunc)
  327. m_PatchConstantFunctions.insert(patchConstantFunc);
  328. }
  329. bool HLModule::IsGraphicsShader(llvm::Function *F) {
  330. return HasDxilFunctionProps(F) && GetDxilFunctionProps(F).IsGraphics();
  331. }
  332. bool HLModule::IsPatchConstantShader(llvm::Function *F) {
  333. return m_PatchConstantFunctions.count(F) != 0;
  334. }
  335. bool HLModule::IsComputeShader(llvm::Function *F) {
  336. return HasDxilFunctionProps(F) && GetDxilFunctionProps(F).IsCS();
  337. }
  338. bool HLModule::IsEntryThatUsesSignatures(llvm::Function *F) {
  339. auto propIter = m_DxilFunctionPropsMap.find(F);
  340. if (propIter != m_DxilFunctionPropsMap.end()) {
  341. DxilFunctionProps &props = *(propIter->second);
  342. return props.IsGraphics() || props.IsCS();
  343. }
  344. // Otherwise, return true if patch constant function
  345. return IsPatchConstantShader(F);
  346. }
  347. bool HLModule::IsEntry(llvm::Function *F) {
  348. auto propIter = m_DxilFunctionPropsMap.find(F);
  349. if (propIter != m_DxilFunctionPropsMap.end()) {
  350. DXASSERT(propIter->second->shaderKind != DXIL::ShaderKind::Invalid,
  351. "invalid entry props");
  352. return true;
  353. }
  354. // Otherwise, return true if patch constant function
  355. return IsPatchConstantShader(F);
  356. }
  357. DxilFunctionAnnotation *HLModule::GetFunctionAnnotation(llvm::Function *F) {
  358. return m_pTypeSystem->GetFunctionAnnotation(F);
  359. }
  360. DxilFunctionAnnotation *HLModule::AddFunctionAnnotation(llvm::Function *F) {
  361. DXASSERT(m_pTypeSystem->GetFunctionAnnotation(F)==nullptr, "function annotation already exist");
  362. return m_pTypeSystem->AddFunctionAnnotation(F);
  363. }
  364. DXIL::Float32DenormMode HLModule::GetFloat32DenormMode() const {
  365. return m_Float32DenormMode;
  366. }
  367. void HLModule::SetFloat32DenormMode(const DXIL::Float32DenormMode mode) {
  368. m_Float32DenormMode = mode;
  369. }
  370. DXIL::DefaultLinkage HLModule::GetDefaultLinkage() const {
  371. return m_DefaultLinkage;
  372. }
  373. void HLModule::SetDefaultLinkage(const DXIL::DefaultLinkage linkage) {
  374. m_DefaultLinkage = linkage;
  375. }
  376. static const StringRef kHLDxilFunctionPropertiesMDName = "dx.fnprops";
  377. static const StringRef kHLDxilOptionsMDName = "dx.options";
  378. // DXIL metadata serialization/deserialization.
  379. void HLModule::EmitHLMetadata() {
  380. m_pMDHelper->EmitDxilVersion(m_DxilMajor, m_DxilMinor);
  381. m_pMDHelper->EmitValidatorVersion(m_ValMajor, m_ValMinor);
  382. m_pMDHelper->EmitDxilShaderModel(m_pSM);
  383. MDTuple *pMDResources = EmitHLResources();
  384. MDTuple *pMDProperties = EmitHLShaderProperties();
  385. m_pMDHelper->EmitDxilTypeSystem(GetTypeSystem(), m_LLVMUsed);
  386. EmitLLVMUsed();
  387. MDTuple *const pNullMDSig = nullptr;
  388. MDTuple *pEntry = m_pMDHelper->EmitDxilEntryPointTuple(GetEntryFunction(), m_EntryName, pNullMDSig, pMDResources, pMDProperties);
  389. vector<MDNode *> Entries;
  390. Entries.emplace_back(pEntry);
  391. m_pMDHelper->EmitDxilEntryPoints(Entries);
  392. {
  393. NamedMDNode * fnProps = m_pModule->getOrInsertNamedMetadata(kHLDxilFunctionPropertiesMDName);
  394. for (auto && pair : m_DxilFunctionPropsMap) {
  395. const hlsl::DxilFunctionProps * props = pair.second.get();
  396. MDTuple *pProps = m_pMDHelper->EmitDxilFunctionProps(props, pair.first);
  397. fnProps->addOperand(pProps);
  398. }
  399. NamedMDNode * options = m_pModule->getOrInsertNamedMetadata(kHLDxilOptionsMDName);
  400. uint32_t hlOptions = m_Options.GetHLOptionsRaw();
  401. options->addOperand(MDNode::get(m_Ctx, m_pMDHelper->Uint32ToConstMD(hlOptions)));
  402. options->addOperand(MDNode::get(m_Ctx, m_pMDHelper->Uint32ToConstMD(GetAutoBindingSpace())));
  403. }
  404. if (!m_SerializedRootSignature.empty()) {
  405. m_pMDHelper->EmitRootSignature(m_SerializedRootSignature);
  406. }
  407. // Save Subobjects
  408. if (GetSubobjects()) {
  409. m_pMDHelper->EmitSubobjects(*GetSubobjects());
  410. }
  411. }
  412. void HLModule::LoadHLMetadata() {
  413. m_pMDHelper->LoadDxilVersion(m_DxilMajor, m_DxilMinor);
  414. m_pMDHelper->LoadValidatorVersion(m_ValMajor, m_ValMinor);
  415. m_pMDHelper->LoadDxilShaderModel(m_pSM);
  416. m_SerializedRootSignature.clear();
  417. const llvm::NamedMDNode *pEntries = m_pMDHelper->GetDxilEntryPoints();
  418. Function *pEntryFunc;
  419. string EntryName;
  420. const llvm::MDOperand *pSignatures, *pResources, *pProperties;
  421. m_pMDHelper->GetDxilEntryPoint(pEntries->getOperand(0), pEntryFunc, EntryName, pSignatures, pResources, pProperties);
  422. SetEntryFunction(pEntryFunc);
  423. SetEntryFunctionName(EntryName);
  424. LoadHLResources(*pResources);
  425. LoadHLShaderProperties(*pProperties);
  426. m_pMDHelper->LoadDxilTypeSystem(*m_pTypeSystem.get());
  427. {
  428. NamedMDNode * fnProps = m_pModule->getNamedMetadata(kHLDxilFunctionPropertiesMDName);
  429. size_t propIdx = 0;
  430. while (propIdx < fnProps->getNumOperands()) {
  431. MDTuple *pProps = dyn_cast<MDTuple>(fnProps->getOperand(propIdx++));
  432. std::unique_ptr<hlsl::DxilFunctionProps> props =
  433. llvm::make_unique<hlsl::DxilFunctionProps>();
  434. const Function *F = m_pMDHelper->LoadDxilFunctionProps(pProps, props.get());
  435. if (props->IsHS() && props->ShaderProps.HS.patchConstantFunc) {
  436. // Add patch constant function to m_PatchConstantFunctions
  437. m_PatchConstantFunctions.insert(props->ShaderProps.HS.patchConstantFunc);
  438. }
  439. m_DxilFunctionPropsMap[F] = std::move(props);
  440. }
  441. const NamedMDNode * options = m_pModule->getOrInsertNamedMetadata(kHLDxilOptionsMDName);
  442. const MDNode *MDOptions = options->getOperand(0);
  443. m_Options.SetHLOptionsRaw(DxilMDHelper::ConstMDToUint32(MDOptions->getOperand(0)));
  444. if (options->getNumOperands() > 1)
  445. SetAutoBindingSpace(DxilMDHelper::ConstMDToUint32(options->getOperand(1)->getOperand(0)));
  446. }
  447. m_pMDHelper->LoadRootSignature(m_SerializedRootSignature);
  448. // Load Subobjects
  449. std::unique_ptr<DxilSubobjects> pSubobjects(new DxilSubobjects());
  450. m_pMDHelper->LoadSubobjects(*pSubobjects);
  451. if (pSubobjects->GetSubobjects().size()) {
  452. ResetSubobjects(pSubobjects.release());
  453. }
  454. }
  455. void HLModule::ClearHLMetadata(llvm::Module &M) {
  456. Module::named_metadata_iterator
  457. b = M.named_metadata_begin(),
  458. e = M.named_metadata_end();
  459. SmallVector<NamedMDNode*, 8> nodes;
  460. for (; b != e; ++b) {
  461. StringRef name = b->getName();
  462. if (name == DxilMDHelper::kDxilVersionMDName ||
  463. name == DxilMDHelper::kDxilShaderModelMDName ||
  464. name == DxilMDHelper::kDxilEntryPointsMDName ||
  465. name == DxilMDHelper::kDxilRootSignatureMDName ||
  466. name == DxilMDHelper::kDxilResourcesMDName ||
  467. name == DxilMDHelper::kDxilTypeSystemMDName ||
  468. name == DxilMDHelper::kDxilValidatorVersionMDName ||
  469. name == kHLDxilFunctionPropertiesMDName || // TODO: adjust to proper name
  470. name == kHLDxilOptionsMDName ||
  471. name.startswith(DxilMDHelper::kDxilTypeSystemHelperVariablePrefix)) {
  472. nodes.push_back(b);
  473. }
  474. }
  475. for (size_t i = 0; i < nodes.size(); ++i) {
  476. M.eraseNamedMetadata(nodes[i]);
  477. }
  478. }
  479. MDTuple *HLModule::EmitHLResources() {
  480. // Emit SRV records.
  481. MDTuple *pTupleSRVs = nullptr;
  482. if (!m_SRVs.empty()) {
  483. vector<Metadata *> MDVals;
  484. for (size_t i = 0; i < m_SRVs.size(); i++) {
  485. MDVals.emplace_back(m_pMDHelper->EmitDxilSRV(*m_SRVs[i]));
  486. }
  487. pTupleSRVs = MDNode::get(m_Ctx, MDVals);
  488. }
  489. // Emit UAV records.
  490. MDTuple *pTupleUAVs = nullptr;
  491. if (!m_UAVs.empty()) {
  492. vector<Metadata *> MDVals;
  493. for (size_t i = 0; i < m_UAVs.size(); i++) {
  494. MDVals.emplace_back(m_pMDHelper->EmitDxilUAV(*m_UAVs[i]));
  495. }
  496. pTupleUAVs = MDNode::get(m_Ctx, MDVals);
  497. }
  498. // Emit CBuffer records.
  499. MDTuple *pTupleCBuffers = nullptr;
  500. if (!m_CBuffers.empty()) {
  501. vector<Metadata *> MDVals;
  502. for (size_t i = 0; i < m_CBuffers.size(); i++) {
  503. MDVals.emplace_back(m_pMDHelper->EmitDxilCBuffer(*m_CBuffers[i]));
  504. }
  505. pTupleCBuffers = MDNode::get(m_Ctx, MDVals);
  506. }
  507. // Emit Sampler records.
  508. MDTuple *pTupleSamplers = nullptr;
  509. if (!m_Samplers.empty()) {
  510. vector<Metadata *> MDVals;
  511. for (size_t i = 0; i < m_Samplers.size(); i++) {
  512. MDVals.emplace_back(m_pMDHelper->EmitDxilSampler(*m_Samplers[i]));
  513. }
  514. pTupleSamplers = MDNode::get(m_Ctx, MDVals);
  515. }
  516. if (pTupleSRVs != nullptr || pTupleUAVs != nullptr || pTupleCBuffers != nullptr || pTupleSamplers != nullptr) {
  517. return m_pMDHelper->EmitDxilResourceTuple(pTupleSRVs, pTupleUAVs, pTupleCBuffers, pTupleSamplers);
  518. } else {
  519. return nullptr;
  520. }
  521. }
  522. void HLModule::LoadHLResources(const llvm::MDOperand &MDO) {
  523. const llvm::MDTuple *pSRVs, *pUAVs, *pCBuffers, *pSamplers;
  524. m_pMDHelper->GetDxilResources(MDO, pSRVs, pUAVs, pCBuffers, pSamplers);
  525. // Load SRV records.
  526. if (pSRVs != nullptr) {
  527. for (unsigned i = 0; i < pSRVs->getNumOperands(); i++) {
  528. unique_ptr<HLResource> pSRV(new HLResource);
  529. m_pMDHelper->LoadDxilSRV(pSRVs->getOperand(i), *pSRV);
  530. AddSRV(std::move(pSRV));
  531. }
  532. }
  533. // Load UAV records.
  534. if (pUAVs != nullptr) {
  535. for (unsigned i = 0; i < pUAVs->getNumOperands(); i++) {
  536. unique_ptr<HLResource> pUAV(new HLResource);
  537. m_pMDHelper->LoadDxilUAV(pUAVs->getOperand(i), *pUAV);
  538. AddUAV(std::move(pUAV));
  539. }
  540. }
  541. // Load CBuffer records.
  542. if (pCBuffers != nullptr) {
  543. for (unsigned i = 0; i < pCBuffers->getNumOperands(); i++) {
  544. unique_ptr<DxilCBuffer> pCB = llvm::make_unique<DxilCBuffer>();
  545. m_pMDHelper->LoadDxilCBuffer(pCBuffers->getOperand(i), *pCB);
  546. AddCBuffer(std::move(pCB));
  547. }
  548. }
  549. // Load Sampler records.
  550. if (pSamplers != nullptr) {
  551. for (unsigned i = 0; i < pSamplers->getNumOperands(); i++) {
  552. unique_ptr<DxilSampler> pSampler(new DxilSampler);
  553. m_pMDHelper->LoadDxilSampler(pSamplers->getOperand(i), *pSampler);
  554. AddSampler(std::move(pSampler));
  555. }
  556. }
  557. }
  558. MDTuple *HLModule::EmitHLShaderProperties() {
  559. return nullptr;
  560. }
  561. void HLModule::LoadHLShaderProperties(const MDOperand &MDO) {
  562. return;
  563. }
  564. MDNode *HLModule::DxilSamplerToMDNode(const DxilSampler &S) {
  565. MDNode *MD = m_pMDHelper->EmitDxilSampler(S);
  566. ValueAsMetadata *ResClass =
  567. m_pMDHelper->Uint32ToConstMD((unsigned)DXIL::ResourceClass::Sampler);
  568. return MDNode::get(m_Ctx, {ResClass, MD});
  569. }
  570. MDNode *HLModule::DxilSRVToMDNode(const DxilResource &SRV) {
  571. MDNode *MD = m_pMDHelper->EmitDxilSRV(SRV);
  572. ValueAsMetadata *ResClass =
  573. m_pMDHelper->Uint32ToConstMD((unsigned)DXIL::ResourceClass::SRV);
  574. return MDNode::get(m_Ctx, {ResClass, MD});
  575. }
  576. MDNode *HLModule::DxilUAVToMDNode(const DxilResource &UAV) {
  577. MDNode *MD = m_pMDHelper->EmitDxilUAV(UAV);
  578. ValueAsMetadata *ResClass =
  579. m_pMDHelper->Uint32ToConstMD((unsigned)DXIL::ResourceClass::UAV);
  580. return MDNode::get(m_Ctx, {ResClass, MD});
  581. }
  582. MDNode *HLModule::DxilCBufferToMDNode(const DxilCBuffer &CB) {
  583. MDNode *MD = m_pMDHelper->EmitDxilCBuffer(CB);
  584. ValueAsMetadata *ResClass =
  585. m_pMDHelper->Uint32ToConstMD((unsigned)DXIL::ResourceClass::CBuffer);
  586. return MDNode::get(m_Ctx, {ResClass, MD});
  587. }
  588. void HLModule::LoadDxilResourceBaseFromMDNode(MDNode *MD, DxilResourceBase &R) {
  589. return m_pMDHelper->LoadDxilResourceBaseFromMDNode(MD, R);
  590. }
  591. void HLModule::LoadDxilResourceFromMDNode(llvm::MDNode *MD, DxilResource &R) {
  592. return m_pMDHelper->LoadDxilResourceFromMDNode(MD, R);
  593. }
  594. void HLModule::LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S) {
  595. return m_pMDHelper->LoadDxilSamplerFromMDNode(MD, S);
  596. }
  597. DxilResourceBase *
  598. HLModule::AddResourceWithGlobalVariableAndProps(llvm::Constant *GV,
  599. DxilResourceProperties &RP) {
  600. DxilResource::Class RC = RP.getResourceClass();
  601. DxilResource::Kind RK = RP.getResourceKind();
  602. unsigned rangeSize = 1;
  603. Type *Ty = GV->getType()->getPointerElementType();
  604. if (ArrayType *AT = dyn_cast<ArrayType>(Ty))
  605. rangeSize = AT->getNumElements();
  606. DxilResourceBase *R = nullptr;
  607. switch (RC) {
  608. case DxilResource::Class::Sampler: {
  609. std::unique_ptr<DxilSampler> S = llvm::make_unique<DxilSampler>();
  610. if (RP.Basic.SamplerCmpOrHasCounter)
  611. S->SetSamplerKind(DxilSampler::SamplerKind::Comparison);
  612. else
  613. S->SetSamplerKind(DxilSampler::SamplerKind::Default);
  614. S->SetKind(RK);
  615. S->SetGlobalSymbol(GV);
  616. S->SetGlobalName(GV->getName());
  617. S->SetRangeSize(rangeSize);
  618. R = S.get();
  619. AddSampler(std::move(S));
  620. } break;
  621. case DxilResource::Class::SRV: {
  622. std::unique_ptr<HLResource> Res = llvm::make_unique<HLResource>();
  623. if (DXIL::IsTyped(RP.getResourceKind())) {
  624. Res->SetCompType(RP.Typed.CompType);
  625. } else if (DXIL::IsStructuredBuffer(RK)) {
  626. Res->SetElementStride(RP.StructStrideInBytes);
  627. }
  628. Res->SetRW(false);
  629. Res->SetKind(RK);
  630. Res->SetGlobalSymbol(GV);
  631. Res->SetGlobalName(GV->getName());
  632. Res->SetRangeSize(rangeSize);
  633. R = Res.get();
  634. AddSRV(std::move(Res));
  635. } break;
  636. case DxilResource::Class::UAV: {
  637. std::unique_ptr<HLResource> Res = llvm::make_unique<HLResource>();
  638. if (DXIL::IsTyped(RK)) {
  639. Res->SetCompType(RP.Typed.CompType);
  640. } else if (DXIL::IsStructuredBuffer(RK)) {
  641. Res->SetElementStride(RP.StructStrideInBytes);
  642. }
  643. Res->SetRW(true);
  644. Res->SetROV(RP.Basic.IsROV);
  645. Res->SetGloballyCoherent(RP.Basic.IsGloballyCoherent);
  646. Res->SetHasCounter(RP.Basic.SamplerCmpOrHasCounter);
  647. Res->SetKind(RK);
  648. Res->SetGlobalSymbol(GV);
  649. Res->SetGlobalName(GV->getName());
  650. Res->SetRangeSize(rangeSize);
  651. R = Res.get();
  652. AddUAV(std::move(Res));
  653. } break;
  654. default:
  655. DXASSERT(0, "Invalid metadata for AddResourceWithGlobalVariableAndMDNode");
  656. }
  657. return R;
  658. }
  659. static uint64_t getRegBindingKey(unsigned CbID, unsigned ConstantIdx) {
  660. return (uint64_t)(CbID) << 32 | ConstantIdx;
  661. }
  662. void HLModule::AddRegBinding(unsigned CbID, unsigned ConstantIdx, unsigned Srv, unsigned Uav,
  663. unsigned Sampler) {
  664. uint64_t Key = getRegBindingKey(CbID, ConstantIdx);
  665. m_SrvBindingInCB[Key] = Srv;
  666. m_UavBindingInCB[Key] = Uav;
  667. m_SamplerBindingInCB[Key] = Sampler;
  668. }
  669. // Helper functions for resource in cbuffer.
  670. namespace {
  671. DXIL::ResourceClass GetRCFromType(StructType *ST, Module &M) {
  672. for (Function &F : M.functions()) {
  673. if (F.user_empty())
  674. continue;
  675. hlsl::HLOpcodeGroup group = hlsl::GetHLOpcodeGroup(&F);
  676. if (group != HLOpcodeGroup::HLAnnotateHandle)
  677. continue;
  678. Type *Ty = F.getFunctionType()->getParamType(
  679. HLOperandIndex::kAnnotateHandleResourceTypeOpIdx);
  680. if (Ty != ST)
  681. continue;
  682. CallInst *CI = cast<CallInst>(F.user_back());
  683. Constant *Props = cast<Constant>(CI->getArgOperand(
  684. HLOperandIndex::kAnnotateHandleResourcePropertiesOpIdx));
  685. DxilResourceProperties RP = resource_helper::loadPropsFromConstant(*Props);
  686. return RP.getResourceClass();
  687. }
  688. return DXIL::ResourceClass::Invalid;
  689. }
  690. unsigned CountResNum(Module &M, Type *Ty, DXIL::ResourceClass RC) {
  691. // Count num of RCs.
  692. unsigned ArraySize = 1;
  693. while (ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
  694. ArraySize *= AT->getNumElements();
  695. Ty = AT->getElementType();
  696. }
  697. if (!Ty->isAggregateType())
  698. return 0;
  699. StructType *ST = dyn_cast<StructType>(Ty);
  700. DXIL::ResourceClass TmpRC = GetRCFromType(ST, M);
  701. if (TmpRC == RC)
  702. return ArraySize;
  703. unsigned Size = 0;
  704. for (Type *EltTy : ST->elements()) {
  705. Size += CountResNum(M, EltTy, RC);
  706. }
  707. return Size * ArraySize;
  708. }
  709. // Note: the rule for register binding on struct array is like this:
  710. // struct X {
  711. // Texture2D x;
  712. // SamplerState s ;
  713. // Texture2D y;
  714. // };
  715. // X x[2] : register(t3) : register(s3);
  716. // x[0].x t3
  717. // x[0].s s3
  718. // x[0].y t4
  719. // x[1].x t5
  720. // x[1].s s4
  721. // x[1].y t6
  722. // So x[0].x and x[1].x not in an array.
  723. unsigned CalcRegBinding(gep_type_iterator GEPIt, gep_type_iterator E,
  724. Module &M, DXIL::ResourceClass RC) {
  725. unsigned NumRC = 0;
  726. // Count GEP offset when only count RC size.
  727. for (; GEPIt != E; GEPIt++) {
  728. Type *Ty = *GEPIt;
  729. Value *idx = GEPIt.getOperand();
  730. Constant *constIdx = dyn_cast<Constant>(idx);
  731. unsigned immIdx = constIdx->getUniqueInteger().getLimitedValue();
  732. // Not support dynamic indexing.
  733. // Array should be just 1d res array as global res.
  734. if (ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
  735. NumRC += immIdx * CountResNum(M, AT->getElementType(), RC);
  736. } else if (StructType *ST = dyn_cast<StructType>(Ty)) {
  737. for (unsigned i=0;i<immIdx;i++) {
  738. NumRC += CountResNum(M, ST->getElementType(i), RC);
  739. }
  740. }
  741. }
  742. return NumRC;
  743. }
  744. } // namespace
  745. unsigned HLModule::GetBindingForResourceInCB(GetElementPtrInst *CbPtr,
  746. GlobalVariable *CbGV,
  747. DXIL::ResourceClass RC) {
  748. if (!CbPtr->hasAllConstantIndices()) {
  749. // Not support dynmaic indexing resource array inside cb.
  750. string ErrorMsg("Index for resource array inside cbuffer must be a literal expression");
  751. dxilutil::EmitErrorOnInstruction(
  752. CbPtr,
  753. ErrorMsg);
  754. return UINT_MAX;
  755. }
  756. Module &M = *m_pModule;
  757. unsigned RegBinding = UINT_MAX;
  758. for (auto &CB : m_CBuffers) {
  759. if (CbGV != CB->GetGlobalSymbol())
  760. continue;
  761. gep_type_iterator GEPIt = gep_type_begin(CbPtr), E = gep_type_end(CbPtr);
  762. // The pointer index.
  763. GEPIt++;
  764. unsigned ID = CB->GetID();
  765. unsigned idx = cast<ConstantInt>(GEPIt.getOperand())->getLimitedValue();
  766. // The first level index to get current constant.
  767. GEPIt++;
  768. uint64_t Key = getRegBindingKey(ID, idx);
  769. switch (RC) {
  770. default:
  771. break;
  772. case DXIL::ResourceClass::SRV:
  773. if (m_SrvBindingInCB.count(Key))
  774. RegBinding = m_SrvBindingInCB[Key];
  775. break;
  776. case DXIL::ResourceClass::UAV:
  777. if (m_UavBindingInCB.count(Key))
  778. RegBinding = m_UavBindingInCB[Key];
  779. break;
  780. case DXIL::ResourceClass::Sampler:
  781. if (m_SamplerBindingInCB.count(Key))
  782. RegBinding = m_SamplerBindingInCB[Key];
  783. break;
  784. }
  785. if (RegBinding == UINT_MAX)
  786. break;
  787. // Calc RegBinding.
  788. RegBinding += CalcRegBinding(GEPIt, E, M, RC);
  789. break;
  790. }
  791. return RegBinding;
  792. }
  793. // TODO: Don't check names.
  794. bool HLModule::IsStreamOutputType(llvm::Type *Ty) {
  795. if (StructType *ST = dyn_cast<StructType>(Ty)) {
  796. StringRef name = ST->getName();
  797. if (name.startswith("class.PointStream"))
  798. return true;
  799. if (name.startswith("class.LineStream"))
  800. return true;
  801. if (name.startswith("class.TriangleStream"))
  802. return true;
  803. }
  804. return false;
  805. }
  806. bool HLModule::IsStreamOutputPtrType(llvm::Type *Ty) {
  807. if (!Ty->isPointerTy())
  808. return false;
  809. Ty = Ty->getPointerElementType();
  810. return IsStreamOutputType(Ty);
  811. }
  812. void HLModule::GetParameterRowsAndCols(Type *Ty, unsigned &rows, unsigned &cols,
  813. DxilParameterAnnotation &paramAnnotation) {
  814. if (Ty->isPointerTy())
  815. Ty = Ty->getPointerElementType();
  816. // For array input of HS, DS, GS,
  817. // we need to skip the first level which size is based on primitive type.
  818. DxilParamInputQual inputQual = paramAnnotation.GetParamInputQual();
  819. bool skipOneLevelArray = inputQual == DxilParamInputQual::InputPatch;
  820. skipOneLevelArray |= inputQual == DxilParamInputQual::OutputPatch;
  821. skipOneLevelArray |= inputQual == DxilParamInputQual::InputPrimitive;
  822. skipOneLevelArray |= inputQual == DxilParamInputQual::OutVertices;
  823. skipOneLevelArray |= inputQual == DxilParamInputQual::OutPrimitives;
  824. if (skipOneLevelArray) {
  825. if (Ty->isArrayTy())
  826. Ty = Ty->getArrayElementType();
  827. }
  828. unsigned arraySize = 1;
  829. while (Ty->isArrayTy()) {
  830. arraySize *= Ty->getArrayNumElements();
  831. Ty = Ty->getArrayElementType();
  832. }
  833. rows = 1;
  834. cols = 1;
  835. if (paramAnnotation.HasMatrixAnnotation()) {
  836. const DxilMatrixAnnotation &matrix = paramAnnotation.GetMatrixAnnotation();
  837. if (matrix.Orientation == MatrixOrientation::RowMajor) {
  838. rows = matrix.Rows;
  839. cols = matrix.Cols;
  840. } else {
  841. DXASSERT_NOMSG(matrix.Orientation == MatrixOrientation::ColumnMajor);
  842. cols = matrix.Rows;
  843. rows = matrix.Cols;
  844. }
  845. } else if (Ty->isVectorTy())
  846. cols = Ty->getVectorNumElements();
  847. rows *= arraySize;
  848. }
  849. static Value *MergeGEP(GEPOperator *SrcGEP, GetElementPtrInst *GEP) {
  850. IRBuilder<> Builder(GEP);
  851. SmallVector<Value *, 8> Indices;
  852. // Find out whether the last index in the source GEP is a sequential idx.
  853. bool EndsWithSequential = false;
  854. for (gep_type_iterator I = gep_type_begin(*SrcGEP), E = gep_type_end(*SrcGEP);
  855. I != E; ++I)
  856. EndsWithSequential = !(*I)->isStructTy();
  857. if (EndsWithSequential) {
  858. Value *Sum;
  859. Value *SO1 = SrcGEP->getOperand(SrcGEP->getNumOperands() - 1);
  860. Value *GO1 = GEP->getOperand(1);
  861. if (SO1 == Constant::getNullValue(SO1->getType())) {
  862. Sum = GO1;
  863. } else if (GO1 == Constant::getNullValue(GO1->getType())) {
  864. Sum = SO1;
  865. } else {
  866. // If they aren't the same type, then the input hasn't been processed
  867. // by the loop above yet (which canonicalizes sequential index types to
  868. // intptr_t). Just avoid transforming this until the input has been
  869. // normalized.
  870. if (SO1->getType() != GO1->getType())
  871. return nullptr;
  872. // Only do the combine when GO1 and SO1 are both constants. Only in
  873. // this case, we are sure the cost after the merge is never more than
  874. // that before the merge.
  875. if (!isa<Constant>(GO1) || !isa<Constant>(SO1))
  876. return nullptr;
  877. Sum = Builder.CreateAdd(SO1, GO1);
  878. }
  879. // Update the GEP in place if possible.
  880. if (SrcGEP->getNumOperands() == 2) {
  881. GEP->setOperand(0, SrcGEP->getOperand(0));
  882. GEP->setOperand(1, Sum);
  883. return GEP;
  884. }
  885. Indices.append(SrcGEP->op_begin() + 1, SrcGEP->op_end() - 1);
  886. Indices.push_back(Sum);
  887. Indices.append(GEP->op_begin() + 2, GEP->op_end());
  888. } else if (isa<Constant>(*GEP->idx_begin()) &&
  889. cast<Constant>(*GEP->idx_begin())->isNullValue() &&
  890. SrcGEP->getNumOperands() != 1) {
  891. // Otherwise we can do the fold if the first index of the GEP is a zero
  892. Indices.append(SrcGEP->op_begin() + 1, SrcGEP->op_end());
  893. Indices.append(GEP->idx_begin() + 1, GEP->idx_end());
  894. }
  895. if (!Indices.empty())
  896. return Builder.CreateInBoundsGEP(SrcGEP->getSourceElementType(),
  897. SrcGEP->getOperand(0), Indices,
  898. GEP->getName());
  899. else
  900. llvm_unreachable("must merge");
  901. }
  902. void HLModule::MergeGepUse(Value *V) {
  903. for (auto U = V->user_begin(); U != V->user_end();) {
  904. auto Use = U++;
  905. if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(*Use)) {
  906. if (GEPOperator *prevGEP = dyn_cast<GEPOperator>(V)) {
  907. // merge the 2 GEPs
  908. Value *newGEP = MergeGEP(prevGEP, GEP);
  909. // Don't need to replace when GEP is updated in place
  910. if (newGEP != GEP) {
  911. GEP->replaceAllUsesWith(newGEP);
  912. GEP->eraseFromParent();
  913. }
  914. MergeGepUse(newGEP);
  915. } else {
  916. MergeGepUse(*Use);
  917. }
  918. } else if (dyn_cast<GEPOperator>(*Use)) {
  919. if (GEPOperator *prevGEP = dyn_cast<GEPOperator>(V)) {
  920. // merge the 2 GEPs
  921. Value *newGEP = MergeGEP(prevGEP, GEP);
  922. // Don't need to replace when GEP is updated in place
  923. if (newGEP != GEP) {
  924. GEP->replaceAllUsesWith(newGEP);
  925. GEP->eraseFromParent();
  926. }
  927. MergeGepUse(newGEP);
  928. } else {
  929. MergeGepUse(*Use);
  930. }
  931. }
  932. }
  933. if (V->user_empty()) {
  934. // Only remove GEP here, root ptr will be removed by DCE.
  935. if (GetElementPtrInst *I = dyn_cast<GetElementPtrInst>(V))
  936. I->eraseFromParent();
  937. }
  938. }
  939. template
  940. CallInst *HLModule::EmitHLOperationCall(IRBuilder<> &Builder,
  941. HLOpcodeGroup group, unsigned opcode,
  942. Type *RetType,
  943. ArrayRef<Value *> paramList,
  944. llvm::Module &M);
  945. template<typename BuilderTy>
  946. CallInst *HLModule::EmitHLOperationCall(BuilderTy &Builder,
  947. HLOpcodeGroup group, unsigned opcode,
  948. Type *RetType,
  949. ArrayRef<Value *> paramList,
  950. llvm::Module &M) {
  951. SmallVector<llvm::Type *, 4> paramTyList;
  952. // Add the opcode param
  953. llvm::Type *opcodeTy = llvm::Type::getInt32Ty(M.getContext());
  954. paramTyList.emplace_back(opcodeTy);
  955. for (Value *param : paramList) {
  956. paramTyList.emplace_back(param->getType());
  957. }
  958. llvm::FunctionType *funcTy =
  959. llvm::FunctionType::get(RetType, paramTyList, false);
  960. Function *opFunc = GetOrCreateHLFunction(M, funcTy, group, opcode);
  961. SmallVector<Value *, 4> opcodeParamList;
  962. Value *opcodeConst = Constant::getIntegerValue(opcodeTy, APInt(32, opcode));
  963. opcodeParamList.emplace_back(opcodeConst);
  964. opcodeParamList.append(paramList.begin(), paramList.end());
  965. return Builder.CreateCall(opFunc, opcodeParamList);
  966. }
  967. unsigned HLModule::GetNumericCastOp(
  968. llvm::Type *SrcTy, bool SrcIsUnsigned, llvm::Type *DstTy, bool DstIsUnsigned) {
  969. DXASSERT(SrcTy != DstTy, "No-op conversions are not casts and should have been handled by the callee.");
  970. uint32_t SrcBitSize = SrcTy->getScalarSizeInBits();
  971. uint32_t DstBitSize = DstTy->getScalarSizeInBits();
  972. bool SrcIsInt = SrcTy->isIntOrIntVectorTy();
  973. bool DstIsInt = DstTy->isIntOrIntVectorTy();
  974. DXASSERT(DstBitSize != 1, "Conversions to bool are not a cast and should have been handled by the callee.");
  975. // Conversions from bools are like unsigned integer widening
  976. if (SrcBitSize == 1) SrcIsUnsigned = true;
  977. if (SrcIsInt) {
  978. if (DstIsInt) { // int to int
  979. if (SrcBitSize > DstBitSize) return Instruction::Trunc;
  980. // unsigned to unsigned: zext
  981. // unsigned to signed: zext (fully representable)
  982. // signed to signed: sext
  983. // signed to unsigned: sext (like C++)
  984. return SrcIsUnsigned ? Instruction::ZExt : Instruction::SExt;
  985. }
  986. else { // int to float
  987. return SrcIsUnsigned ? Instruction::UIToFP : Instruction::SIToFP;
  988. }
  989. }
  990. else {
  991. if (DstIsInt) { // float to int
  992. return DstIsUnsigned ? Instruction::FPToUI : Instruction::FPToSI;
  993. }
  994. else { // float to float
  995. return SrcBitSize > DstBitSize ? Instruction::FPTrunc : Instruction::FPExt;
  996. }
  997. }
  998. }
  999. bool HLModule::HasPreciseAttributeWithMetadata(Instruction *I) {
  1000. return DxilMDHelper::IsMarkedPrecise(I);
  1001. }
  1002. void HLModule::MarkPreciseAttributeWithMetadata(Instruction *I) {
  1003. return DxilMDHelper::MarkPrecise(I);
  1004. }
  1005. void HLModule::ClearPreciseAttributeWithMetadata(Instruction *I) {
  1006. I->setMetadata(DxilMDHelper::kDxilPreciseAttributeMDName, nullptr);
  1007. }
  1008. static void MarkPreciseAttribute(Function *F) {
  1009. LLVMContext &Ctx = F->getContext();
  1010. MDNode *preciseNode = MDNode::get(
  1011. Ctx, {MDString::get(Ctx, DxilMDHelper::kDxilPreciseAttributeMDName)});
  1012. F->setMetadata(DxilMDHelper::kDxilPreciseAttributeMDName, preciseNode);
  1013. }
  1014. template<typename BuilderTy>
  1015. void HLModule::MarkPreciseAttributeOnValWithFunctionCall(
  1016. llvm::Value *V, BuilderTy &Builder, llvm::Module &M) {
  1017. Type *Ty = V->getType();
  1018. Type *EltTy = Ty->getScalarType();
  1019. // TODO: Only do this on basic types.
  1020. FunctionType *preciseFuncTy =
  1021. FunctionType::get(Type::getVoidTy(M.getContext()), {EltTy}, false);
  1022. // The function will be deleted after precise propagate.
  1023. std::string preciseFuncName = "dx.attribute.precise.";
  1024. raw_string_ostream mangledNameStr(preciseFuncName);
  1025. EltTy->print(mangledNameStr);
  1026. mangledNameStr.flush();
  1027. Function *preciseFunc =
  1028. cast<Function>(M.getOrInsertFunction(preciseFuncName, preciseFuncTy));
  1029. if (!HLModule::HasPreciseAttribute(preciseFunc))
  1030. MarkPreciseAttribute(preciseFunc);
  1031. if (Ty->isVectorTy()) {
  1032. for (unsigned i = 0; i < Ty->getVectorNumElements(); i++) {
  1033. Value *Elt = Builder.CreateExtractElement(V, i);
  1034. Builder.CreateCall(preciseFunc, {Elt});
  1035. }
  1036. } else
  1037. Builder.CreateCall(preciseFunc, {V});
  1038. }
  1039. void HLModule::MarkPreciseAttributeOnPtrWithFunctionCall(llvm::Value *Ptr,
  1040. llvm::Module &M) {
  1041. for (User *U : Ptr->users()) {
  1042. // Skip load inst.
  1043. if (dyn_cast<LoadInst>(U))
  1044. continue;
  1045. if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
  1046. Value *V = SI->getValueOperand();
  1047. if (isa<Instruction>(V)) {
  1048. // Mark the Value with function call.
  1049. IRBuilder<> Builder(SI);
  1050. MarkPreciseAttributeOnValWithFunctionCall(V, Builder, M);
  1051. }
  1052. } else if (CallInst *CI = dyn_cast<CallInst>(U)) {
  1053. if (CI->getType()->isVoidTy()) {
  1054. IRBuilder<> Builder(CI);
  1055. // For void type, cannot use as function arg.
  1056. // Mark all arg for it?
  1057. for (auto &arg : CI->arg_operands()) {
  1058. MarkPreciseAttributeOnValWithFunctionCall(arg, Builder, M);
  1059. }
  1060. } else {
  1061. if (CI->getType()->isPointerTy()) {
  1062. // For instance, matrix subscript...
  1063. MarkPreciseAttributeOnPtrWithFunctionCall(CI, M);
  1064. } else {
  1065. IRBuilder<> Builder(CI->getNextNode());
  1066. MarkPreciseAttributeOnValWithFunctionCall(CI, Builder, M);
  1067. }
  1068. }
  1069. } else if (BitCastInst *BCI = dyn_cast<BitCastInst>(U)) {
  1070. // Do not mark bitcasts. We only expect them here due to lifetime intrinsics.
  1071. DXASSERT(onlyUsedByLifetimeMarkers(BCI),
  1072. "expected bitcast to only be used by lifetime intrinsics");
  1073. } else {
  1074. // Must be GEP here.
  1075. GetElementPtrInst *GEP = cast<GetElementPtrInst>(U);
  1076. MarkPreciseAttributeOnPtrWithFunctionCall(GEP, M);
  1077. }
  1078. }
  1079. }
  1080. bool HLModule::HasPreciseAttribute(Function *F) {
  1081. MDNode *preciseNode =
  1082. F->getMetadata(DxilMDHelper::kDxilPreciseAttributeMDName);
  1083. return preciseNode != nullptr;
  1084. }
  1085. static void AddDIGlobalVariable(DIBuilder &Builder, DIGlobalVariable *LocDIGV,
  1086. StringRef Name, DIType *DITy,
  1087. GlobalVariable *GV, DebugInfoFinder &DbgInfoFinder, bool removeLocDIGV) {
  1088. DIGlobalVariable *EltDIGV = Builder.createGlobalVariable(
  1089. LocDIGV->getScope(), Name, GV->getName(), LocDIGV->getFile(),
  1090. LocDIGV->getLine(), DITy, false, GV);
  1091. DICompileUnit *DICU = nullptr;
  1092. std::vector<Metadata *> AllGVs;
  1093. std::vector<Metadata *>::iterator locIt;
  1094. for (auto itDICU : DbgInfoFinder.compile_units()) {
  1095. MDTuple *GTuple = cast_or_null<MDTuple>(itDICU->getRawGlobalVariables());
  1096. if (!GTuple)
  1097. continue;
  1098. AllGVs.assign(GTuple->operands().begin(), GTuple->operands().end());
  1099. locIt = std::find(AllGVs.begin(), AllGVs.end(), LocDIGV);
  1100. if (locIt == AllGVs.end())
  1101. continue;
  1102. DICU = itDICU;
  1103. break;
  1104. }
  1105. DXASSERT_NOMSG(DICU);
  1106. if (!DICU)
  1107. return;
  1108. // Add global to CU.
  1109. if (removeLocDIGV) {
  1110. AllGVs.erase(locIt);
  1111. }
  1112. AllGVs.emplace_back(EltDIGV);
  1113. DICU->replaceGlobalVariables(MDTuple::get(GV->getContext(), AllGVs));
  1114. DXVERIFY_NOMSG(DbgInfoFinder.appendGlobalVariable(EltDIGV));
  1115. }
  1116. static unsigned GetCompositeTypeSize(DIType *Ty) {
  1117. DICompositeType *StructTy = nullptr;
  1118. DITypeIdentifierMap EmptyMap;
  1119. if (DIDerivedType *DerivedTy = dyn_cast<DIDerivedType>(Ty)) {
  1120. DXASSERT_NOMSG(DerivedTy->getTag() == dwarf::DW_TAG_const_type || DerivedTy->getTag() == dwarf::DW_TAG_typedef);
  1121. DIType *BaseTy = DerivedTy->getBaseType().resolve(EmptyMap);
  1122. return GetCompositeTypeSize(BaseTy);
  1123. }
  1124. else {
  1125. StructTy = cast<DICompositeType>(Ty);
  1126. }
  1127. return StructTy->getSizeInBits();
  1128. }
  1129. void HLModule::CreateElementGlobalVariableDebugInfo(
  1130. GlobalVariable *GV, DebugInfoFinder &DbgInfoFinder, GlobalVariable *EltGV,
  1131. unsigned sizeInBits, unsigned alignInBits, unsigned offsetInBits,
  1132. StringRef eltName) {
  1133. DIGlobalVariable *DIGV = dxilutil::FindGlobalVariableDebugInfo(GV, DbgInfoFinder);
  1134. DXASSERT_NOMSG(DIGV);
  1135. DIBuilder Builder(*GV->getParent());
  1136. DITypeIdentifierMap EmptyMap;
  1137. DIType *DITy = DIGV->getType().resolve(EmptyMap);
  1138. DIScope *DITyScope = DITy->getScope().resolve(EmptyMap);
  1139. // If element size is greater than base size make sure we're dealing with an empty struct.
  1140. unsigned compositeSize = GetCompositeTypeSize(DITy);
  1141. if (sizeInBits > compositeSize) {
  1142. DXASSERT_NOMSG(offsetInBits == 0 && compositeSize == 8);
  1143. sizeInBits = compositeSize;
  1144. }
  1145. // Create Elt type.
  1146. DIType *EltDITy =
  1147. Builder.createMemberType(DITyScope, DITy->getName().str() + eltName.str(),
  1148. DITy->getFile(), DITy->getLine(), sizeInBits,
  1149. alignInBits, offsetInBits, /*Flags*/ 0, DITy);
  1150. AddDIGlobalVariable(Builder, DIGV, DIGV->getName().str() + eltName.str(),
  1151. EltDITy, EltGV, DbgInfoFinder, /*removeDIGV*/false);
  1152. }
  1153. void HLModule::UpdateGlobalVariableDebugInfo(
  1154. llvm::GlobalVariable *GV, llvm::DebugInfoFinder &DbgInfoFinder,
  1155. llvm::GlobalVariable *NewGV) {
  1156. DIGlobalVariable *DIGV = dxilutil::FindGlobalVariableDebugInfo(GV, DbgInfoFinder);
  1157. DXASSERT_NOMSG(DIGV);
  1158. DIBuilder Builder(*GV->getParent());
  1159. DITypeIdentifierMap EmptyMap;
  1160. DIType *DITy = DIGV->getType().resolve(EmptyMap);
  1161. AddDIGlobalVariable(Builder, DIGV, DIGV->getName(), DITy, NewGV,
  1162. DbgInfoFinder,/*removeDIGV*/true);
  1163. }
  1164. DebugInfoFinder &HLModule::GetOrCreateDebugInfoFinder() {
  1165. if (m_pDebugInfoFinder == nullptr) {
  1166. m_pDebugInfoFinder = llvm::make_unique<llvm::DebugInfoFinder>();
  1167. m_pDebugInfoFinder->processModule(*m_pModule);
  1168. }
  1169. return *m_pDebugInfoFinder;
  1170. }
  1171. //------------------------------------------------------------------------------
  1172. //
  1173. // Subobject methods.
  1174. //
  1175. DxilSubobjects *HLModule::GetSubobjects() {
  1176. return m_pSubobjects.get();
  1177. }
  1178. const DxilSubobjects *HLModule::GetSubobjects() const {
  1179. return m_pSubobjects.get();
  1180. }
  1181. DxilSubobjects *HLModule::ReleaseSubobjects() {
  1182. return m_pSubobjects.release();
  1183. }
  1184. void HLModule::ResetSubobjects(DxilSubobjects *subobjects) {
  1185. m_pSubobjects.reset(subobjects);
  1186. }
  1187. //------------------------------------------------------------------------------
  1188. //
  1189. // Signature methods.
  1190. //
  1191. HLExtraPropertyHelper::HLExtraPropertyHelper(llvm::Module *pModule)
  1192. : DxilExtraPropertyHelper(pModule) {
  1193. }
  1194. void HLExtraPropertyHelper::EmitSignatureElementProperties(const DxilSignatureElement &SE,
  1195. vector<Metadata *> &MDVals) {
  1196. }
  1197. void HLExtraPropertyHelper::LoadSignatureElementProperties(const MDOperand &MDO,
  1198. DxilSignatureElement &SE) {
  1199. if (MDO.get() == nullptr)
  1200. return;
  1201. }
  1202. } // namespace hlsl
  1203. namespace llvm {
  1204. hlsl::HLModule &Module::GetOrCreateHLModule(bool skipInit) {
  1205. std::unique_ptr<hlsl::HLModule> M;
  1206. if (!HasHLModule()) {
  1207. M = llvm::make_unique<hlsl::HLModule>(this);
  1208. if (!skipInit) {
  1209. M->LoadHLMetadata();
  1210. }
  1211. SetHLModule(M.release());
  1212. }
  1213. return GetHLModule();
  1214. }
  1215. }