[polly] r297415 - [Support] Add -polly-dump-module pass.

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 9 14:29:58 PST 2017


Author: meinersbur
Date: Thu Mar  9 16:29:58 2017
New Revision: 297415

URL: http://llvm.org/viewvc/llvm-project?rev=297415&view=rev
Log:
[Support] Add -polly-dump-module pass.

This pass allows writing the LLVM-IR just before and after the Polly
passes to a file.

Dumping the IR before Polly helps reproducing bugs that occur in code
generated by clang. It is the only reliable way to get the IR that
triggers a bug. The alternative is to emit the IR with

    clang -c -emit-llvm -S -o dump.ll

then pass it through all optimization passes

    opt dump.ll -basicaa -sroa ... -S -o optdump.ll

to then reproduce the error with

    opt optdump.ll -polly-opt-isl -polly-codegen -analyze

However, the IR is not the same. -O3 uses a PassBuilder than creates passes
with different parameters than the default.

Dumping the IR after Polly is useful to compare a miscompilation with
a known-good configuration.

Differential Revision: https://reviews.llvm.org/D30788

Added:
    polly/trunk/include/polly/Support/DumpModulePass.h
    polly/trunk/lib/Support/DumpModulePass.cpp
Modified:
    polly/trunk/include/polly/LinkAllPasses.h
    polly/trunk/lib/CMakeLists.txt
    polly/trunk/lib/Support/RegisterPasses.cpp

Modified: polly/trunk/include/polly/LinkAllPasses.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/LinkAllPasses.h?rev=297415&r1=297414&r2=297415&view=diff
==============================================================================
--- polly/trunk/include/polly/LinkAllPasses.h (original)
+++ polly/trunk/include/polly/LinkAllPasses.h Thu Mar  9 16:29:58 2017
@@ -16,6 +16,8 @@
 #define POLLY_LINKALLPASSES_H
 
 #include "polly/Config/config.h"
+#include "polly/Support/DumpModulePass.h"
+#include "llvm/ADT/StringRef.h"
 #include <cstdlib>
 
 namespace llvm {
@@ -84,6 +86,7 @@ struct PollyForcePassLinking {
     polly::createIslScheduleOptimizerPass();
     polly::createFlattenSchedulePass();
     polly::createDeLICMPass();
+    polly::createDumpModulePass("", true);
   }
 } PollyForcePassLinking; // Force link by creating a global definition.
 } // namespace

Added: polly/trunk/include/polly/Support/DumpModulePass.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/Support/DumpModulePass.h?rev=297415&view=auto
==============================================================================
--- polly/trunk/include/polly/Support/DumpModulePass.h (added)
+++ polly/trunk/include/polly/Support/DumpModulePass.h Thu Mar  9 16:29:58 2017
@@ -0,0 +1,40 @@
+//===------ DumpModulePass.cpp ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Write a module to a file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_SUPPORT_DUMPMODULEPASS_H
+#define POLLY_SUPPORT_DUMPMODULEPASS_H
+
+namespace llvm {
+class StringRef;
+class ModulePass;
+} // namespace llvm
+
+namespace polly {
+/// Create a pass that prints the module into a file.
+///
+/// The meaning of @p Filename depends on @p IsSuffix. If IsSuffix==false, then
+/// the module is written to the @p Filename. If it is true, the filename is
+/// generated from the module's name, @p Filename with an '.ll' extension.
+///
+/// The intent of IsSuffix is to avoid the file being overwritten when
+/// processing multiple modules and/or with multiple dump passes in the
+/// pipeline.
+llvm::ModulePass *createDumpModulePass(llvm::StringRef Filename, bool IsSuffix);
+} // namespace polly
+
+namespace llvm {
+class PassRegistry;
+void initializeDumpModulePass(llvm::PassRegistry &);
+} // namespace llvm
+
+#endif /* POLLY_SUPPORT_DUMPMODULEPASS_H */

Modified: polly/trunk/lib/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CMakeLists.txt?rev=297415&r1=297414&r2=297415&view=diff
==============================================================================
--- polly/trunk/lib/CMakeLists.txt (original)
+++ polly/trunk/lib/CMakeLists.txt Thu Mar  9 16:29:58 2017
@@ -51,6 +51,7 @@ add_polly_library(Polly
   Support/ScopHelper.cpp
   Support/ScopLocation.cpp
   Support/ISLTools.cpp
+  Support/DumpModulePass.cpp
   ${POLLY_JSON_FILES}
   Transform/Canonicalization.cpp
   Transform/CodePreparation.cpp

Added: polly/trunk/lib/Support/DumpModulePass.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/DumpModulePass.cpp?rev=297415&view=auto
==============================================================================
--- polly/trunk/lib/Support/DumpModulePass.cpp (added)
+++ polly/trunk/lib/Support/DumpModulePass.cpp Thu Mar  9 16:29:58 2017
@@ -0,0 +1,95 @@
+//===------ DumpModulePass.cpp ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Write a module to a file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/Support/DumpModulePass.h"
+
+#include "polly/Options.h"
+#include "llvm/IR/LegacyPassManagers.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include <string.h>
+#define DEBUG_TYPE "polly-dump-module"
+
+using namespace llvm;
+using namespace polly;
+
+namespace {
+
+class DumpModule : public ModulePass {
+private:
+  DumpModule(const DumpModule &) = delete;
+  const DumpModule &operator=(const DumpModule &) = delete;
+
+  std::string Filename;
+  bool IsSuffix;
+
+public:
+  static char ID;
+
+  /// This constructor is used e.g. if using opt -polly-dump-module.
+  ///
+  /// Provide a default suffix to not overwrite the original file.
+  explicit DumpModule() : ModulePass(ID), Filename("-dump"), IsSuffix(true) {}
+
+  explicit DumpModule(llvm::StringRef Filename, bool IsSuffix)
+      : ModulePass(ID), Filename(Filename), IsSuffix(IsSuffix) {}
+
+  /// @name ModulePass interface
+  //@{
+  virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+  }
+
+  virtual bool runOnModule(llvm::Module &M) override {
+    std::string Dumpfile;
+    if (IsSuffix) {
+      auto ModuleName = M.getName();
+      auto Stem = sys::path::stem(ModuleName);
+      Dumpfile = (Twine(Stem) + Filename + ".ll").str();
+    } else {
+      Dumpfile = Filename;
+    }
+    DEBUG(dbgs() << "Dumping module to " << Dumpfile << '\n');
+
+    std::unique_ptr<tool_output_file> Out;
+    std::error_code EC;
+    Out.reset(new tool_output_file(Dumpfile, EC, sys::fs::F_None));
+    if (EC) {
+      errs() << EC.message() << '\n';
+      return false;
+    }
+
+    M.print(Out->os(), nullptr);
+    Out->keep();
+
+    return false;
+  }
+  //@}
+};
+
+char DumpModule::ID;
+} // namespace
+
+ModulePass *polly::createDumpModulePass(llvm::StringRef Filename,
+                                        bool IsSuffix) {
+  return new DumpModule(Filename, IsSuffix);
+}
+
+INITIALIZE_PASS_BEGIN(DumpModule, "polly-dump-module", "Polly - Dump Module",
+                      false, false)
+INITIALIZE_PASS_END(DumpModule, "polly-dump-module", "Polly - Dump Module",
+                    false, false)

Modified: polly/trunk/lib/Support/RegisterPasses.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/RegisterPasses.cpp?rev=297415&r1=297414&r2=297415&view=diff
==============================================================================
--- polly/trunk/lib/Support/RegisterPasses.cpp (original)
+++ polly/trunk/lib/Support/RegisterPasses.cpp Thu Mar  9 16:29:58 2017
@@ -31,6 +31,7 @@
 #include "polly/PolyhedralInfo.h"
 #include "polly/ScopDetection.h"
 #include "polly/ScopInfo.h"
+#include "polly/Support/DumpModulePass.h"
 #include "llvm/Analysis/CFGPrinter.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/Transforms/IPO.h"
@@ -161,6 +162,28 @@ static cl::opt<bool>
                          cl::Hidden, cl::init(false), cl::cat(PollyCategory));
 
 static cl::opt<bool>
+    DumpBefore("polly-dump-before",
+               cl::desc("Dump module before Polly transformations into a file "
+                        "suffixed with \"-before\""),
+               cl::init(false), cl::cat(PollyCategory));
+
+static cl::list<std::string> DumpBeforeFile(
+    "polly-dump-before-file",
+    cl::desc("Dump module before Polly transformations to the given file"),
+    cl::cat(PollyCategory));
+
+static cl::opt<bool>
+    DumpAfter("polly-dump-after",
+              cl::desc("Dump module after Polly transformations into a file "
+                       "suffixed with \"-after\""),
+              cl::init(false), cl::cat(PollyCategory));
+
+static cl::list<std::string> DumpAfterFile(
+    "polly-dump-after-file",
+    cl::desc("Dump module after Polly transformations to the given file"),
+    cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool>
     EnableDeLICM("polly-enable-delicm",
                  cl::desc("Eliminate scalar loop carried dependences"),
                  cl::Hidden, cl::init(false), cl::cat(PollyCategory));
@@ -188,6 +211,7 @@ void initializePollyPasses(PassRegistry
   initializeCodegenCleanupPass(Registry);
   initializeFlattenSchedulePass(Registry);
   initializeDeLICMPass(Registry);
+  initializeDumpModulePass(Registry);
 }
 
 /// Register Polly passes such that they form a polyhedral optimizer.
@@ -217,6 +241,11 @@ void initializePollyPasses(PassRegistry
 ///
 /// Polly supports the isl internal code generator.
 void registerPollyPasses(llvm::legacy::PassManagerBase &PM) {
+  if (DumpBefore)
+    PM.add(polly::createDumpModulePass("-before", true));
+  for (auto &Filename : DumpBeforeFile)
+    PM.add(polly::createDumpModulePass(Filename, false));
+
   PM.add(polly::createScopDetectionPass());
 
   if (PollyDetectOnly)
@@ -282,6 +311,11 @@ void registerPollyPasses(llvm::legacy::P
   // force all analysis results to be recomputed.
   PM.add(createBarrierNoopPass());
 
+  if (DumpAfter)
+    PM.add(polly::createDumpModulePass("-after", true));
+  for (auto &Filename : DumpAfterFile)
+    PM.add(polly::createDumpModulePass(Filename, false));
+
   if (CFGPrinter)
     PM.add(llvm::createCFGPrinterLegacyPassPass());
 




More information about the llvm-commits mailing list