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/IR/PassInstrumentation.h"
16 #include "llvm/Pass.h"
17 #include "llvm/Support/Debug.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/Path.h"
20 #include "llvm/Support/ToolOutputFile.h"
21 #include "llvm/Transforms/IPO/GlobalDCE.h"
22 #include "llvm/Transforms/IPO/StripDeadPrototypes.h"
23 #include "llvm/Transforms/Utils/Cloning.h"
25 #define DEBUG_TYPE "polly-dump-func"
28 using namespace polly
;
32 static void runDumpFunction(llvm::Function
&F
, StringRef Suffix
) {
33 StringRef FName
= F
.getName();
34 Module
*M
= F
.getParent();
36 StringRef ModuleName
= M
->getName();
37 StringRef Stem
= sys::path::stem(ModuleName
);
38 std::string Dumpfile
= (Twine(Stem
) + "-" + FName
+ Suffix
+ ".ll").str();
39 LLVM_DEBUG(dbgs() << "Dumping function '" << FName
<< "' to '" << Dumpfile
42 ValueToValueMapTy VMap
;
43 auto ShouldCloneDefinition
= [&F
](const GlobalValue
*GV
) -> bool {
46 std::unique_ptr
<Module
> CM
= CloneModule(*M
, VMap
, ShouldCloneDefinition
);
47 Function
*NewF
= cast
<Function
>(VMap
.lookup(&F
));
48 assert(NewF
&& "Expected selected function to be cloned");
50 LLVM_DEBUG(dbgs() << "Global DCE...\n");
52 // Stop F itself from being pruned
53 GlobalValue::LinkageTypes OrigLinkage
= NewF
->getLinkage();
54 NewF
->setLinkage(GlobalValue::ExternalLinkage
);
57 ModuleAnalysisManager MAM
;
58 ModulePassManager MPM
;
60 PassInstrumentationCallbacks PIC
;
61 MAM
.registerPass([&] { return PassInstrumentationAnalysis(&PIC
); });
63 MPM
.addPass(GlobalDCEPass());
64 MPM
.addPass(StripDeadPrototypesPass());
68 // Restore old linkage
69 NewF
->setLinkage(OrigLinkage
);
71 LLVM_DEBUG(dbgs() << "Write to file '" << Dumpfile
<< "'...\n");
73 std::unique_ptr
<ToolOutputFile
> Out
;
75 Out
.reset(new ToolOutputFile(Dumpfile
, EC
, sys::fs::OF_None
));
77 errs() << EC
.message() << '\n';
81 CM
->print(Out
->os(), nullptr);
83 LLVM_DEBUG(dbgs() << "Dump file " << Dumpfile
<< " written successfully\n");
86 class DumpFunctionWrapperPass final
: public FunctionPass
{
88 DumpFunctionWrapperPass(const DumpFunctionWrapperPass
&) = delete;
89 const DumpFunctionWrapperPass
&
90 operator=(const DumpFunctionWrapperPass
&) = delete;
97 explicit DumpFunctionWrapperPass() : FunctionPass(ID
), Suffix("-dump") {}
99 explicit DumpFunctionWrapperPass(std::string Suffix
)
100 : FunctionPass(ID
), Suffix(std::move(Suffix
)) {}
102 /// @name FunctionPass interface
104 void getAnalysisUsage(llvm::AnalysisUsage
&AU
) const override
{
105 AU
.setPreservesAll();
108 bool runOnFunction(llvm::Function
&F
) override
{
109 runDumpFunction(F
, Suffix
);
115 char DumpFunctionWrapperPass::ID
;
118 FunctionPass
*polly::createDumpFunctionWrapperPass(std::string Suffix
) {
119 return new DumpFunctionWrapperPass(std::move(Suffix
));
122 llvm::PreservedAnalyses
DumpFunctionPass::run(Function
&F
,
123 FunctionAnalysisManager
&AM
) {
124 runDumpFunction(F
, Suffix
);
125 return PreservedAnalyses::all();
128 INITIALIZE_PASS_BEGIN(DumpFunctionWrapperPass
, "polly-dump-function",
129 "Polly - Dump Function", false, false)
130 INITIALIZE_PASS_END(DumpFunctionWrapperPass
, "polly-dump-function",
131 "Polly - Dump Function", false, false)