HLModule.cpp 46 KB

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