xref: /llvm-project/polly/lib/Support/DumpFunctionPass.cpp (revision 36c6632eb43bf67e19c8a6a21981cf66e06389b4)
19cfab5e2SMichael Kruse //===------ DumpFunctionPass.cpp --------------------------------*- C++ -*-===//
29cfab5e2SMichael Kruse //
39cfab5e2SMichael Kruse // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
49cfab5e2SMichael Kruse // See https://llvm.org/LICENSE.txt for license information.
59cfab5e2SMichael Kruse // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69cfab5e2SMichael Kruse //
79cfab5e2SMichael Kruse //===----------------------------------------------------------------------===//
89cfab5e2SMichael Kruse //
99cfab5e2SMichael Kruse // Write a function to a file.
109cfab5e2SMichael Kruse //
119cfab5e2SMichael Kruse //===----------------------------------------------------------------------===//
129cfab5e2SMichael Kruse 
139cfab5e2SMichael Kruse #include "polly/Support/DumpFunctionPass.h"
149cfab5e2SMichael Kruse #include "llvm/IR/Module.h"
15*36c6632eSNikita Popov #include "llvm/IR/PassInstrumentation.h"
169cfab5e2SMichael Kruse #include "llvm/Pass.h"
179cfab5e2SMichael Kruse #include "llvm/Support/Debug.h"
189cfab5e2SMichael Kruse #include "llvm/Support/FileSystem.h"
199cfab5e2SMichael Kruse #include "llvm/Support/Path.h"
209cfab5e2SMichael Kruse #include "llvm/Support/ToolOutputFile.h"
219cfab5e2SMichael Kruse #include "llvm/Transforms/IPO/GlobalDCE.h"
229cfab5e2SMichael Kruse #include "llvm/Transforms/IPO/StripDeadPrototypes.h"
239cfab5e2SMichael Kruse #include "llvm/Transforms/Utils/Cloning.h"
249cfab5e2SMichael Kruse 
259cfab5e2SMichael Kruse #define DEBUG_TYPE "polly-dump-func"
269cfab5e2SMichael Kruse 
279cfab5e2SMichael Kruse using namespace llvm;
289cfab5e2SMichael Kruse using namespace polly;
299cfab5e2SMichael Kruse 
309cfab5e2SMichael Kruse namespace {
319cfab5e2SMichael Kruse 
runDumpFunction(llvm::Function & F,StringRef Suffix)329cfab5e2SMichael Kruse static void runDumpFunction(llvm::Function &F, StringRef Suffix) {
339cfab5e2SMichael Kruse   StringRef FName = F.getName();
349cfab5e2SMichael Kruse   Module *M = F.getParent();
359cfab5e2SMichael Kruse 
369cfab5e2SMichael Kruse   StringRef ModuleName = M->getName();
379cfab5e2SMichael Kruse   StringRef Stem = sys::path::stem(ModuleName);
389cfab5e2SMichael Kruse   std::string Dumpfile = (Twine(Stem) + "-" + FName + Suffix + ".ll").str();
399cfab5e2SMichael Kruse   LLVM_DEBUG(dbgs() << "Dumping function '" << FName << "' to '" << Dumpfile
409cfab5e2SMichael Kruse                     << "'...\n");
419cfab5e2SMichael Kruse 
429cfab5e2SMichael Kruse   ValueToValueMapTy VMap;
439cfab5e2SMichael Kruse   auto ShouldCloneDefinition = [&F](const GlobalValue *GV) -> bool {
449cfab5e2SMichael Kruse     return GV == &F;
459cfab5e2SMichael Kruse   };
469cfab5e2SMichael Kruse   std::unique_ptr<Module> CM = CloneModule(*M, VMap, ShouldCloneDefinition);
47e4f3f2c0SMichael Kruse   Function *NewF = cast<Function>(VMap.lookup(&F));
48e4f3f2c0SMichael Kruse   assert(NewF && "Expected selected function to be cloned");
499cfab5e2SMichael Kruse 
509cfab5e2SMichael Kruse   LLVM_DEBUG(dbgs() << "Global DCE...\n");
519cfab5e2SMichael Kruse 
52e4f3f2c0SMichael Kruse   // Stop F itself from being pruned
53e4f3f2c0SMichael Kruse   GlobalValue::LinkageTypes OrigLinkage = NewF->getLinkage();
54e4f3f2c0SMichael Kruse   NewF->setLinkage(GlobalValue::ExternalLinkage);
55e4f3f2c0SMichael Kruse 
569cfab5e2SMichael Kruse   {
579cfab5e2SMichael Kruse     ModuleAnalysisManager MAM;
589cfab5e2SMichael Kruse     ModulePassManager MPM;
599cfab5e2SMichael Kruse 
609cfab5e2SMichael Kruse     PassInstrumentationCallbacks PIC;
619cfab5e2SMichael Kruse     MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
629cfab5e2SMichael Kruse 
639cfab5e2SMichael Kruse     MPM.addPass(GlobalDCEPass());
649cfab5e2SMichael Kruse     MPM.addPass(StripDeadPrototypesPass());
659cfab5e2SMichael Kruse     MPM.run(*CM, MAM);
669cfab5e2SMichael Kruse   }
679cfab5e2SMichael Kruse 
68e4f3f2c0SMichael Kruse   // Restore old linkage
69e4f3f2c0SMichael Kruse   NewF->setLinkage(OrigLinkage);
70e4f3f2c0SMichael Kruse 
719cfab5e2SMichael Kruse   LLVM_DEBUG(dbgs() << "Write to file '" << Dumpfile << "'...\n");
729cfab5e2SMichael Kruse 
739cfab5e2SMichael Kruse   std::unique_ptr<ToolOutputFile> Out;
749cfab5e2SMichael Kruse   std::error_code EC;
759cfab5e2SMichael Kruse   Out.reset(new ToolOutputFile(Dumpfile, EC, sys::fs::OF_None));
769cfab5e2SMichael Kruse   if (EC) {
779cfab5e2SMichael Kruse     errs() << EC.message() << '\n';
789cfab5e2SMichael Kruse     return;
799cfab5e2SMichael Kruse   }
809cfab5e2SMichael Kruse 
819cfab5e2SMichael Kruse   CM->print(Out->os(), nullptr);
829cfab5e2SMichael Kruse   Out->keep();
839cfab5e2SMichael Kruse   LLVM_DEBUG(dbgs() << "Dump file " << Dumpfile << " written successfully\n");
849cfab5e2SMichael Kruse }
859cfab5e2SMichael Kruse 
86bd93df93SMichael Kruse class DumpFunctionWrapperPass final : public FunctionPass {
879cfab5e2SMichael Kruse private:
889cfab5e2SMichael Kruse   DumpFunctionWrapperPass(const DumpFunctionWrapperPass &) = delete;
899cfab5e2SMichael Kruse   const DumpFunctionWrapperPass &
909cfab5e2SMichael Kruse   operator=(const DumpFunctionWrapperPass &) = delete;
919cfab5e2SMichael Kruse 
929cfab5e2SMichael Kruse   std::string Suffix;
939cfab5e2SMichael Kruse 
949cfab5e2SMichael Kruse public:
959cfab5e2SMichael Kruse   static char ID;
969cfab5e2SMichael Kruse 
DumpFunctionWrapperPass()979cfab5e2SMichael Kruse   explicit DumpFunctionWrapperPass() : FunctionPass(ID), Suffix("-dump") {}
989cfab5e2SMichael Kruse 
DumpFunctionWrapperPass(std::string Suffix)999cfab5e2SMichael Kruse   explicit DumpFunctionWrapperPass(std::string Suffix)
1009cfab5e2SMichael Kruse       : FunctionPass(ID), Suffix(std::move(Suffix)) {}
1019cfab5e2SMichael Kruse 
1029cfab5e2SMichael Kruse   /// @name FunctionPass interface
1039cfab5e2SMichael Kruse   //@{
getAnalysisUsage(llvm::AnalysisUsage & AU) const1043f3930a4SKazu Hirata   void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
1059cfab5e2SMichael Kruse     AU.setPreservesAll();
1069cfab5e2SMichael Kruse   }
1079cfab5e2SMichael Kruse 
runOnFunction(llvm::Function & F)1083f3930a4SKazu Hirata   bool runOnFunction(llvm::Function &F) override {
1099cfab5e2SMichael Kruse     runDumpFunction(F, Suffix);
1109cfab5e2SMichael Kruse     return false;
1119cfab5e2SMichael Kruse   }
1129cfab5e2SMichael Kruse   //@}
1139cfab5e2SMichael Kruse };
1149cfab5e2SMichael Kruse 
1159cfab5e2SMichael Kruse char DumpFunctionWrapperPass::ID;
1169cfab5e2SMichael Kruse } // namespace
1179cfab5e2SMichael Kruse 
createDumpFunctionWrapperPass(std::string Suffix)1189cfab5e2SMichael Kruse FunctionPass *polly::createDumpFunctionWrapperPass(std::string Suffix) {
1199cfab5e2SMichael Kruse   return new DumpFunctionWrapperPass(std::move(Suffix));
1209cfab5e2SMichael Kruse }
1219cfab5e2SMichael Kruse 
run(Function & F,FunctionAnalysisManager & AM)1229cfab5e2SMichael Kruse llvm::PreservedAnalyses DumpFunctionPass::run(Function &F,
1239cfab5e2SMichael Kruse                                               FunctionAnalysisManager &AM) {
1249cfab5e2SMichael Kruse   runDumpFunction(F, Suffix);
1259cfab5e2SMichael Kruse   return PreservedAnalyses::all();
1269cfab5e2SMichael Kruse }
1279cfab5e2SMichael Kruse 
1289cfab5e2SMichael Kruse INITIALIZE_PASS_BEGIN(DumpFunctionWrapperPass, "polly-dump-function",
1299cfab5e2SMichael Kruse                       "Polly - Dump Function", false, false)
1309cfab5e2SMichael Kruse INITIALIZE_PASS_END(DumpFunctionWrapperPass, "polly-dump-function",
1319cfab5e2SMichael Kruse                     "Polly - Dump Function", false, false)
132