1 //===------ DumpFunctionPass.cpp --------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Write a function to a file.
11 //===----------------------------------------------------------------------===//
13 #include "polly/Support/DumpFunctionPass.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 #include "llvm/Transforms/IPO/GlobalDCE.h"
21 #include "llvm/Transforms/IPO/StripDeadPrototypes.h"
22 #include "llvm/Transforms/Utils/Cloning.h"
24 #define DEBUG_TYPE "polly-dump-func"
27 using namespace polly
;
31 static void runDumpFunction(llvm::Function
&F
, StringRef Suffix
) {
32 StringRef FName
= F
.getName();
33 Module
*M
= F
.getParent();
35 StringRef ModuleName
= M
->getName();
36 StringRef Stem
= sys::path::stem(ModuleName
);
37 std::string Dumpfile
= (Twine(Stem
) + "-" + FName
+ Suffix
+ ".ll").str();
38 LLVM_DEBUG(dbgs() << "Dumping function '" << FName
<< "' to '" << Dumpfile
41 ValueToValueMapTy VMap
;
42 auto ShouldCloneDefinition
= [&F
](const GlobalValue
*GV
) -> bool {
45 std::unique_ptr
<Module
> CM
= CloneModule(*M
, VMap
, ShouldCloneDefinition
);
46 Function
*NewF
= cast
<Function
>(VMap
.lookup(&F
));
47 assert(NewF
&& "Expected selected function to be cloned");
49 LLVM_DEBUG(dbgs() << "Global DCE...\n");
51 // Stop F itself from being pruned
52 GlobalValue::LinkageTypes OrigLinkage
= NewF
->getLinkage();
53 NewF
->setLinkage(GlobalValue::ExternalLinkage
);
56 ModuleAnalysisManager MAM
;
57 ModulePassManager MPM
;
59 PassInstrumentationCallbacks PIC
;
60 MAM
.registerPass([&] { return PassInstrumentationAnalysis(&PIC
); });
62 MPM
.addPass(GlobalDCEPass());
63 MPM
.addPass(StripDeadPrototypesPass());
67 // Restore old linkage
68 NewF
->setLinkage(OrigLinkage
);
70 LLVM_DEBUG(dbgs() << "Write to file '" << Dumpfile
<< "'...\n");
72 std::unique_ptr
<ToolOutputFile
> Out
;
74 Out
.reset(new ToolOutputFile(Dumpfile
, EC
, sys::fs::OF_None
));
76 errs() << EC
.message() << '\n';
80 CM
->print(Out
->os(), nullptr);
82 LLVM_DEBUG(dbgs() << "Dump file " << Dumpfile
<< " written successfully\n");
85 class DumpFunctionWrapperPass final
: public FunctionPass
{
87 DumpFunctionWrapperPass(const DumpFunctionWrapperPass
&) = delete;
88 const DumpFunctionWrapperPass
&
89 operator=(const DumpFunctionWrapperPass
&) = delete;
96 explicit DumpFunctionWrapperPass() : FunctionPass(ID
), Suffix("-dump") {}
98 explicit DumpFunctionWrapperPass(std::string Suffix
)
99 : FunctionPass(ID
), Suffix(std::move(Suffix
)) {}
101 /// @name FunctionPass interface
103 void getAnalysisUsage(llvm::AnalysisUsage
&AU
) const override
{
104 AU
.setPreservesAll();
107 bool runOnFunction(llvm::Function
&F
) override
{
108 runDumpFunction(F
, Suffix
);
114 char DumpFunctionWrapperPass::ID
;
117 FunctionPass
*polly::createDumpFunctionWrapperPass(std::string Suffix
) {
118 return new DumpFunctionWrapperPass(std::move(Suffix
));
121 llvm::PreservedAnalyses
DumpFunctionPass::run(Function
&F
,
122 FunctionAnalysisManager
&AM
) {
123 runDumpFunction(F
, Suffix
);
124 return PreservedAnalyses::all();
127 INITIALIZE_PASS_BEGIN(DumpFunctionWrapperPass
, "polly-dump-function",
128 "Polly - Dump Function", false, false)
129 INITIALIZE_PASS_END(DumpFunctionWrapperPass
, "polly-dump-function",
130 "Polly - Dump Function", false, false)