1 | //===------ DumpModulePass.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 module to a file. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "polly/Support/DumpModulePass.h" |
14 | #include "llvm/IR/Module.h" |
15 | #include "llvm/Pass.h" |
16 | #include "llvm/Support/Debug.h" |
17 | #include "llvm/Support/FileSystem.h" |
18 | #include "llvm/Support/Path.h" |
19 | #include "llvm/Support/ToolOutputFile.h" |
20 | |
21 | #define DEBUG_TYPE "polly-dump-module" |
22 | |
23 | using namespace llvm; |
24 | using namespace polly; |
25 | |
26 | namespace { |
27 | |
28 | static void runDumpModule(llvm::Module &M, StringRef Filename, bool IsSuffix) { |
29 | std::string Dumpfile; |
30 | if (IsSuffix) { |
31 | StringRef ModuleName = M.getName(); |
32 | StringRef Stem = sys::path::stem(path: ModuleName); |
33 | Dumpfile = (Twine(Stem) + Filename + ".ll" ).str(); |
34 | } else { |
35 | Dumpfile = Filename.str(); |
36 | } |
37 | LLVM_DEBUG(dbgs() << "Dumping module to " << Dumpfile << '\n'); |
38 | |
39 | std::unique_ptr<ToolOutputFile> Out; |
40 | std::error_code EC; |
41 | Out.reset(p: new ToolOutputFile(Dumpfile, EC, sys::fs::OF_None)); |
42 | if (EC) { |
43 | errs() << EC.message() << '\n'; |
44 | return; |
45 | } |
46 | |
47 | M.print(OS&: Out->os(), AAW: nullptr); |
48 | Out->keep(); |
49 | } |
50 | |
51 | class DumpModuleWrapperPass final : public ModulePass { |
52 | private: |
53 | DumpModuleWrapperPass(const DumpModuleWrapperPass &) = delete; |
54 | const DumpModuleWrapperPass & |
55 | operator=(const DumpModuleWrapperPass &) = delete; |
56 | |
57 | std::string Filename; |
58 | bool IsSuffix; |
59 | |
60 | public: |
61 | static char ID; |
62 | |
63 | /// This constructor is used e.g. if using opt -polly-dump-module. |
64 | /// |
65 | /// Provide a default suffix to not overwrite the original file. |
66 | explicit DumpModuleWrapperPass() |
67 | : ModulePass(ID), Filename("-dump" ), IsSuffix(true) {} |
68 | |
69 | explicit DumpModuleWrapperPass(std::string Filename, bool IsSuffix) |
70 | : ModulePass(ID), Filename(std::move(Filename)), IsSuffix(IsSuffix) {} |
71 | |
72 | /// @name ModulePass interface |
73 | //@{ |
74 | void getAnalysisUsage(llvm::AnalysisUsage &AU) const override { |
75 | AU.setPreservesAll(); |
76 | } |
77 | |
78 | bool runOnModule(llvm::Module &M) override { |
79 | runDumpModule(M, Filename, IsSuffix); |
80 | return false; |
81 | } |
82 | //@} |
83 | }; |
84 | |
85 | char DumpModuleWrapperPass::ID; |
86 | } // namespace |
87 | |
88 | ModulePass *polly::createDumpModuleWrapperPass(std::string Filename, |
89 | bool IsSuffix) { |
90 | return new DumpModuleWrapperPass(std::move(Filename), IsSuffix); |
91 | } |
92 | |
93 | llvm::PreservedAnalyses DumpModulePass::run(llvm::Module &M, |
94 | llvm::ModuleAnalysisManager &AM) { |
95 | runDumpModule(M, Filename, IsSuffix); |
96 | return PreservedAnalyses::all(); |
97 | } |
98 | |
99 | INITIALIZE_PASS_BEGIN(DumpModuleWrapperPass, "polly-dump-module" , |
100 | "Polly - Dump Module" , false, false) |
101 | INITIALIZE_PASS_END(DumpModuleWrapperPass, "polly-dump-module" , |
102 | "Polly - Dump Module" , false, false) |
103 | |