PauseResumePasses.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // PauseResumePasses.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. // Passes to pause/resume pipeline. //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #include "dxc/HLSL/DxilGenerationPass.h"
  12. #include "llvm/Pass.h"
  13. #include "llvm/IR/Metadata.h"
  14. #include "llvm/IR/Module.h"
  15. using namespace llvm;
  16. using namespace hlsl;
  17. static const char kPauseResumeMDName[] = "pauseresume";
  18. static const char kPauseResumeNumFields = 2;
  19. static const char kPauseResumePassNameToPause = 0;
  20. static const char kPauseResumePassNameToResume = 1;
  21. namespace hlsl {
  22. bool ClearPauseResumePasses(Module &M) {
  23. NamedMDNode *N = M.getNamedMetadata(kPauseResumeMDName);
  24. if (N) {
  25. M.eraseNamedMetadata(N);
  26. return true;
  27. }
  28. return false;
  29. }
  30. void GetPauseResumePasses(Module &M, StringRef &pause, StringRef &resume) {
  31. NamedMDNode *N = M.getNamedMetadata(kPauseResumeMDName);
  32. if (N && N->getNumOperands() > 0) {
  33. MDNode *MD = N->getOperand(0);
  34. pause = dyn_cast<MDString>(MD->getOperand(kPauseResumePassNameToPause).get())->getString();
  35. resume = dyn_cast<MDString>(MD->getOperand(kPauseResumePassNameToResume).get())->getString();
  36. }
  37. }
  38. void SetPauseResumePasses(Module &M, StringRef pause, StringRef resume) {
  39. LLVMContext &Ctx = M.getContext();
  40. NamedMDNode *N = M.getOrInsertNamedMetadata(kPauseResumeMDName);
  41. Metadata *MDs[kPauseResumeNumFields];
  42. MDs[(int)kPauseResumePassNameToPause] = MDString::get(Ctx, pause);
  43. MDs[(int)kPauseResumePassNameToResume] = MDString::get(Ctx, resume);
  44. if (N->getNumOperands() == 0)
  45. N->addOperand(MDNode::get(Ctx, MDs));
  46. else
  47. N->setOperand(kPauseResumePassNameToPause, MDNode::get(Ctx, MDs));
  48. }
  49. }
  50. namespace {
  51. class NoPausePasses : public ModulePass {
  52. public:
  53. static char ID; // Pass identification, replacement for typeid
  54. explicit NoPausePasses() : ModulePass(ID) {}
  55. const char *getPassName() const override { return "NoPausePasses"; }
  56. bool runOnModule(Module &M) override {
  57. return ClearPauseResumePasses(M);
  58. }
  59. };
  60. class PausePasses : public ModulePass {
  61. public:
  62. static char ID; // Pass identification, replacement for typeid
  63. explicit PausePasses() : ModulePass(ID) {}
  64. const char *getPassName() const override { return "PausePasses"; }
  65. bool runOnModule(Module &M) override {
  66. StringRef pause, resume;
  67. hlsl::GetPauseResumePasses(M, pause, resume);
  68. if (!pause.empty()) {
  69. const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(pause);
  70. std::unique_ptr<ModulePass> pass((ModulePass *)PI->createPass());
  71. pass->setOSOverride(OSOverride);
  72. return pass->runOnModule(M);
  73. }
  74. return false;
  75. }
  76. };
  77. class ResumePasses : public ModulePass {
  78. public:
  79. static char ID; // Pass identification, replacement for typeid
  80. explicit ResumePasses() : ModulePass(ID) {}
  81. const char *getPassName() const override { return "ResumePasses"; }
  82. bool runOnModule(Module &M) override {
  83. StringRef pause, resume;
  84. hlsl::GetPauseResumePasses(M, pause, resume);
  85. if (!resume.empty()) {
  86. const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(resume);
  87. std::unique_ptr<ModulePass> pass((ModulePass *)PI->createPass());
  88. pass->setOSOverride(OSOverride);
  89. return pass->runOnModule(M);
  90. }
  91. return false;
  92. }
  93. };
  94. char NoPausePasses::ID = 0;
  95. char PausePasses::ID = 0;
  96. char ResumePasses::ID = 0;
  97. }
  98. ModulePass *llvm::createNoPausePassesPass() {
  99. return new NoPausePasses();
  100. }
  101. ModulePass *llvm::createPausePassesPass() {
  102. return new PausePasses();
  103. }
  104. ModulePass *llvm::createResumePassesPass() {
  105. return new ResumePasses();
  106. }
  107. INITIALIZE_PASS(NoPausePasses,
  108. "hlsl-passes-nopause",
  109. "Clears metadata used for pause and resume", false, false)
  110. INITIALIZE_PASS(PausePasses,
  111. "hlsl-passes-pause",
  112. "Prepare to pause passes", false, false)
  113. INITIALIZE_PASS(ResumePasses,
  114. "hlsl-passes-resume",
  115. "Prepare to resume passes", false, false)