DumpFunctionPass.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. //===------ DumpFunctionPass.cpp --------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Write a function to a file.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "polly/Support/DumpFunctionPass.h"
  13. #include "llvm/IR/Module.h"
  14. #include "llvm/Pass.h"
  15. #include "llvm/Support/Debug.h"
  16. #include "llvm/Support/FileSystem.h"
  17. #include "llvm/Support/Path.h"
  18. #include "llvm/Support/ToolOutputFile.h"
  19. #include "llvm/Transforms/IPO/GlobalDCE.h"
  20. #include "llvm/Transforms/IPO/StripDeadPrototypes.h"
  21. #include "llvm/Transforms/Utils/Cloning.h"
  22. #define DEBUG_TYPE "polly-dump-func"
  23. using namespace llvm;
  24. using namespace polly;
  25. namespace {
  26. static void runDumpFunction(llvm::Function &F, StringRef Suffix) {
  27. StringRef FName = F.getName();
  28. Module *M = F.getParent();
  29. StringRef ModuleName = M->getName();
  30. StringRef Stem = sys::path::stem(ModuleName);
  31. std::string Dumpfile = (Twine(Stem) + "-" + FName + Suffix + ".ll").str();
  32. LLVM_DEBUG(dbgs() << "Dumping function '" << FName << "' to '" << Dumpfile
  33. << "'...\n");
  34. ValueToValueMapTy VMap;
  35. auto ShouldCloneDefinition = [&F](const GlobalValue *GV) -> bool {
  36. return GV == &F;
  37. };
  38. std::unique_ptr<Module> CM = CloneModule(*M, VMap, ShouldCloneDefinition);
  39. Function *NewF = cast<Function>(VMap.lookup(&F));
  40. assert(NewF && "Expected selected function to be cloned");
  41. LLVM_DEBUG(dbgs() << "Global DCE...\n");
  42. // Stop F itself from being pruned
  43. GlobalValue::LinkageTypes OrigLinkage = NewF->getLinkage();
  44. NewF->setLinkage(GlobalValue::ExternalLinkage);
  45. {
  46. ModuleAnalysisManager MAM;
  47. ModulePassManager MPM;
  48. PassInstrumentationCallbacks PIC;
  49. MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
  50. MPM.addPass(GlobalDCEPass());
  51. MPM.addPass(StripDeadPrototypesPass());
  52. MPM.run(*CM, MAM);
  53. }
  54. // Restore old linkage
  55. NewF->setLinkage(OrigLinkage);
  56. LLVM_DEBUG(dbgs() << "Write to file '" << Dumpfile << "'...\n");
  57. std::unique_ptr<ToolOutputFile> Out;
  58. std::error_code EC;
  59. Out.reset(new ToolOutputFile(Dumpfile, EC, sys::fs::OF_None));
  60. if (EC) {
  61. errs() << EC.message() << '\n';
  62. return;
  63. }
  64. CM->print(Out->os(), nullptr);
  65. Out->keep();
  66. LLVM_DEBUG(dbgs() << "Dump file " << Dumpfile << " written successfully\n");
  67. }
  68. class DumpFunctionWrapperPass final : public FunctionPass {
  69. private:
  70. DumpFunctionWrapperPass(const DumpFunctionWrapperPass &) = delete;
  71. const DumpFunctionWrapperPass &
  72. operator=(const DumpFunctionWrapperPass &) = delete;
  73. std::string Suffix;
  74. public:
  75. static char ID;
  76. explicit DumpFunctionWrapperPass() : FunctionPass(ID), Suffix("-dump") {}
  77. explicit DumpFunctionWrapperPass(std::string Suffix)
  78. : FunctionPass(ID), Suffix(std::move(Suffix)) {}
  79. /// @name FunctionPass interface
  80. //@{
  81. void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
  82. AU.setPreservesAll();
  83. }
  84. bool runOnFunction(llvm::Function &F) override {
  85. runDumpFunction(F, Suffix);
  86. return false;
  87. }
  88. //@}
  89. };
  90. char DumpFunctionWrapperPass::ID;
  91. } // namespace
  92. FunctionPass *polly::createDumpFunctionWrapperPass(std::string Suffix) {
  93. return new DumpFunctionWrapperPass(std::move(Suffix));
  94. }
  95. llvm::PreservedAnalyses DumpFunctionPass::run(Function &F,
  96. FunctionAnalysisManager &AM) {
  97. runDumpFunction(F, Suffix);
  98. return PreservedAnalyses::all();
  99. }
  100. INITIALIZE_PASS_BEGIN(DumpFunctionWrapperPass, "polly-dump-function",
  101. "Polly - Dump Function", false, false)
  102. INITIALIZE_PASS_END(DumpFunctionWrapperPass, "polly-dump-function",
  103. "Polly - Dump Function", false, false)