DxilPIXVirtualRegisters.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilPIXVirtualRegisters.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. // Defines functions for dealing with the virtual register annotations in //
  9. // DXIL instructions. //
  10. // //
  11. ///////////////////////////////////////////////////////////////////////////////
  12. #include "DxilPIXVirtualRegisters.h"
  13. #include "dxc/Support/Global.h"
  14. #include "llvm/IR/Constant.h"
  15. #include "llvm/IR/Constants.h"
  16. #include "llvm/IR/InstIterator.h"
  17. #include "llvm/IR/Instruction.h"
  18. #include "llvm/IR/Instructions.h"
  19. #include "llvm/IR/IRBuilder.h"
  20. #include "llvm/IR/Metadata.h"
  21. #include "llvm/IR/Type.h"
  22. static llvm::Metadata *MetadataForValue(llvm::Value *V) {
  23. if (auto *C = llvm::dyn_cast<llvm::Constant>(V)) {
  24. return llvm::ConstantAsMetadata::get(C);
  25. }
  26. return llvm::ValueAsMetadata::get(V);
  27. }
  28. void pix_dxil::PixDxilInstNum::AddMD(llvm::LLVMContext &Ctx, llvm::Instruction *pI, std::uint32_t InstNum) {
  29. llvm::IRBuilder<> B(Ctx);
  30. pI->setMetadata(
  31. llvm::StringRef(MDName),
  32. llvm::MDNode::get(Ctx, { llvm::ConstantAsMetadata::get(B.getInt32(ID)),
  33. llvm::ConstantAsMetadata::get(B.getInt32(InstNum)) }));
  34. }
  35. bool pix_dxil::PixDxilInstNum::FromInst(llvm::Instruction *pI, std::uint32_t *pInstNum) {
  36. *pInstNum = 0;
  37. auto *mdNodes = pI->getMetadata(MDName);
  38. if (mdNodes == nullptr) {
  39. return false;
  40. }
  41. if (mdNodes->getNumOperands() != 2) {
  42. return false;
  43. }
  44. auto *mdID = llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(0));
  45. if (mdID == nullptr || mdID->getLimitedValue() != ID) {
  46. return false;
  47. }
  48. auto *mdInstNum = llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(1));
  49. if (mdInstNum == nullptr) {
  50. return false;
  51. }
  52. *pInstNum = mdInstNum->getLimitedValue();
  53. return true;
  54. }
  55. void pix_dxil::PixDxilReg::AddMD(llvm::LLVMContext &Ctx, llvm::Instruction *pI, std::uint32_t RegNum) {
  56. llvm::IRBuilder<> B(Ctx);
  57. pI->setMetadata(
  58. llvm::StringRef(MDName),
  59. llvm::MDNode::get(Ctx, { llvm::ConstantAsMetadata::get(B.getInt32(ID)),
  60. llvm::ConstantAsMetadata::get(B.getInt32(RegNum)) }));
  61. }
  62. bool pix_dxil::PixDxilReg::FromInst(llvm::Instruction *pI, std::uint32_t *pRegNum) {
  63. *pRegNum = 0;
  64. auto *mdNodes = pI->getMetadata(MDName);
  65. if (mdNodes == nullptr) {
  66. return false;
  67. }
  68. if (mdNodes->getNumOperands() != 2) {
  69. return false;
  70. }
  71. auto *mdID = llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(0));
  72. if (mdID == nullptr || mdID->getLimitedValue() != ID) {
  73. return false;
  74. }
  75. auto *mdRegNum = llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(1));
  76. if (mdRegNum == nullptr) {
  77. return false;
  78. }
  79. *pRegNum = mdRegNum->getLimitedValue();
  80. return true;
  81. }
  82. static bool ParsePixAllocaReg(llvm::MDNode *MD, std::uint32_t *RegNum, std::uint32_t *Count) {
  83. if (MD->getNumOperands() != 3) {
  84. return false;
  85. }
  86. auto *mdID = llvm::mdconst::dyn_extract<llvm::ConstantInt>(MD->getOperand(0));
  87. if (mdID == nullptr || mdID->getLimitedValue() != pix_dxil::PixAllocaReg::ID) {
  88. return false;
  89. }
  90. auto *mdRegNum = llvm::mdconst::dyn_extract<llvm::ConstantInt>(MD->getOperand(1));
  91. auto *mdCount = llvm::mdconst::dyn_extract<llvm::ConstantInt>(MD->getOperand(2));
  92. if (mdRegNum == nullptr || mdCount == nullptr) {
  93. return false;
  94. }
  95. *RegNum = mdRegNum->getLimitedValue();
  96. *Count = mdCount->getLimitedValue();
  97. return true;
  98. }
  99. void pix_dxil::PixAllocaReg::AddMD(llvm::LLVMContext &Ctx, llvm::AllocaInst *pAlloca, std::uint32_t RegNum, std::uint32_t Count) {
  100. llvm::IRBuilder<> B(Ctx);
  101. pAlloca->setMetadata(
  102. llvm::StringRef(MDName),
  103. llvm::MDNode::get(Ctx, { llvm::ConstantAsMetadata::get(B.getInt32(ID)),
  104. llvm::ConstantAsMetadata::get(B.getInt32(RegNum)),
  105. llvm::ConstantAsMetadata::get(B.getInt32(Count)) }));
  106. }
  107. void pix_dxil::PixAllocaRegWrite::AddMD(llvm::LLVMContext &Ctx, llvm::StoreInst *pSt, llvm::MDNode *pAllocaReg, llvm::Value *Index) {
  108. llvm::IRBuilder<> B(Ctx);
  109. pSt->setMetadata(
  110. llvm::StringRef(MDName),
  111. llvm::MDNode::get(Ctx, { llvm::ConstantAsMetadata::get(B.getInt32(ID)),
  112. pAllocaReg,
  113. MetadataForValue(Index) }));
  114. }
  115. bool pix_dxil::PixAllocaRegWrite::FromInst(llvm::StoreInst *pI, std::uint32_t *pRegBase, std::uint32_t *pRegSize, llvm::Value **pIndex) {
  116. *pRegBase = 0;
  117. *pRegSize = 0;
  118. *pIndex = nullptr;
  119. auto *mdNodes = pI->getMetadata(MDName);
  120. if (mdNodes == nullptr || mdNodes->getNumOperands() != 3) {
  121. return false;
  122. }
  123. auto *mdID = llvm::mdconst::dyn_extract<llvm::ConstantInt>(mdNodes->getOperand(0));
  124. if (mdID == nullptr || mdID->getLimitedValue() != ID) {
  125. return false;
  126. }
  127. auto *mdAllocaReg = llvm::dyn_cast<llvm::MDNode>(mdNodes->getOperand(1));
  128. if (mdAllocaReg == nullptr || !ParsePixAllocaReg(mdAllocaReg, pRegBase, pRegSize)) {
  129. return false;
  130. }
  131. auto *mdIndex = llvm::dyn_cast<llvm::ValueAsMetadata>(mdNodes->getOperand(2));
  132. if (mdIndex == nullptr) {
  133. return false;
  134. }
  135. *pIndex = mdIndex->getValue();
  136. return true;
  137. }