[Polly] Port DeadCodeElim to the NewPM.

GitOrigin-RevId: 8796451d6eee1d29b921fc25b62b4b474cdb5eba
diff --git a/include/polly/DeadCodeElimination.h b/include/polly/DeadCodeElimination.h
new file mode 100644
index 0000000..6d71bcf
--- /dev/null
+++ b/include/polly/DeadCodeElimination.h
@@ -0,0 +1,41 @@
+//===- DeadCodeElimination.h ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//  Eliminate dead iterations.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef POLLY_DEADCODEELIMINATION_H
+#define POLLY_DEADCODEELIMINATION_H
+
+#include "polly/ScopPass.h"
+
+namespace llvm {
+class PassRegistry;
+class Pass;
+class raw_ostream;
+} // namespace llvm
+
+namespace polly {
+llvm::Pass *createDeadCodeElimWrapperPass();
+
+struct DeadCodeElimPass : llvm::PassInfoMixin<DeadCodeElimPass> {
+  DeadCodeElimPass() {}
+
+  llvm::PreservedAnalyses run(Scop &S, ScopAnalysisManager &SAM,                              ScopStandardAnalysisResults &SAR, SPMUpdater &U);
+};
+
+
+} // namespace polly
+
+namespace llvm {
+void initializeDeadCodeElimWrapperPassPass(llvm::PassRegistry &);
+} // namespace llvm
+
+#endif /* POLLY_DEADCODEELIMINATION_H */
diff --git a/include/polly/LinkAllPasses.h b/include/polly/LinkAllPasses.h
index f59db17..1d1e455 100644
--- a/include/polly/LinkAllPasses.h
+++ b/include/polly/LinkAllPasses.h
@@ -28,7 +28,7 @@
 namespace polly {
 llvm::Pass *createCodePreparationPass();
 llvm::Pass *createScopInlinerPass();
-llvm::Pass *createDeadCodeElimPass();
+llvm::Pass *createDeadCodeElimWrapperPass();
 llvm::Pass *createDependenceInfoPass();
 llvm::Pass *createDependenceInfoWrapperPassPass();
 llvm::Pass *createDOTOnlyPrinterPass();
@@ -75,7 +75,7 @@
       return;
 
     polly::createCodePreparationPass();
-    polly::createDeadCodeElimPass();
+    polly::createDeadCodeElimWrapperPass();
     polly::createDependenceInfoPass();
     polly::createDOTOnlyPrinterPass();
     polly::createDOTOnlyViewerPass();
@@ -109,7 +109,7 @@
 class PassRegistry;
 void initializeCodePreparationPass(llvm::PassRegistry &);
 void initializeScopInlinerPass(llvm::PassRegistry &);
-void initializeDeadCodeElimPass(llvm::PassRegistry &);
+void initializeDeadCodeElimWrapperPassPass(llvm::PassRegistry &);
 void initializeJSONExporterPass(llvm::PassRegistry &);
 void initializeJSONImporterPass(llvm::PassRegistry &);
 void initializeIslAstInfoWrapperPassPass(llvm::PassRegistry &);
diff --git a/lib/Support/PollyPasses.def b/lib/Support/PollyPasses.def
index f2111e3..03b3dc8 100644
--- a/lib/Support/PollyPasses.def
+++ b/lib/Support/PollyPasses.def
@@ -38,4 +38,5 @@
 SCOP_PASS("polly-prune-unprofitable", PruneUnprofitablePass())
 SCOP_PASS("polly-opt-isl", IslScheduleOptimizerPass())
 SCOP_PASS("print<polly-opt-isl>", IslScheduleOptimizerPrinterPass(outs()))
+SCOP_PASS("polly-dce", DeadCodeElimPass())
 #undef SCOP_PASS
diff --git a/lib/Support/RegisterPasses.cpp b/lib/Support/RegisterPasses.cpp
index ebbce7c..05cad2b 100644
--- a/lib/Support/RegisterPasses.cpp
+++ b/lib/Support/RegisterPasses.cpp
@@ -25,6 +25,7 @@
 #include "polly/CodeGen/IslAst.h"
 #include "polly/CodePreparation.h"
 #include "polly/DeLICM.h"
+#include "polly/DeadCodeElimination.h"
 #include "polly/DependenceInfo.h"
 #include "polly/ForwardOpTree.h"
 #include "polly/JSONExporter.h"
@@ -248,7 +249,7 @@
   LLVMInitializeNVPTXAsmPrinter();
 #endif
   initializeCodePreparationPass(Registry);
-  initializeDeadCodeElimPass(Registry);
+  initializeDeadCodeElimWrapperPassPass(Registry);
   initializeDependenceInfoPass(Registry);
   initializeDependenceInfoWrapperPassPass(Registry);
   initializeJSONExporterPass(Registry);
@@ -336,7 +337,7 @@
     PM.add(polly::createJSONImporterPass());
 
   if (DeadCodeElim)
-    PM.add(polly::createDeadCodeElimPass());
+    PM.add(polly::createDeadCodeElimWrapperPass());
 
   if (FullyIndexedStaticExpansion)
     PM.add(polly::createMaximalStaticExpansionPass());
@@ -517,7 +518,7 @@
     SPM.addPass(JSONImportPass());
 
   if (DeadCodeElim)
-    report_fatal_error("Option -polly-run-dce not supported with NPM", false);
+    SPM.addPass(DeadCodeElimPass());
 
   if (FullyIndexedStaticExpansion)
     report_fatal_error("Option -polly-enable-mse not supported with NPM",
diff --git a/lib/Transform/DeadCodeElimination.cpp b/lib/Transform/DeadCodeElimination.cpp
index cc8923c..546f386 100644
--- a/lib/Transform/DeadCodeElimination.cpp
+++ b/lib/Transform/DeadCodeElimination.cpp
@@ -31,6 +31,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "polly/DeadCodeElimination.h"
 #include "polly/DependenceInfo.h"
 #include "polly/LinkAllPasses.h"
 #include "polly/Options.h"
@@ -50,43 +51,38 @@
              "before the actual dead code elimination."),
     cl::ZeroOrMore, cl::init(-1), cl::cat(PollyCategory));
 
-class DeadCodeElim : public ScopPass {
+class DeadCodeElimWrapperPass : public ScopPass {
 public:
   static char ID;
-  explicit DeadCodeElim() : ScopPass(ID) {}
+  explicit DeadCodeElimWrapperPass() : ScopPass(ID) {}
 
   /// Remove dead iterations from the schedule of @p S.
   bool runOnScop(Scop &S) override;
 
   /// Register all analyses and transformation required.
   void getAnalysisUsage(AnalysisUsage &AU) const override;
-
-private:
-  /// Return the set of live iterations.
-  ///
-  /// The set of live iterations are all iterations that write to memory and for
-  /// which we can not prove that there will be a later write that _must_
-  /// overwrite the same memory location and is consequently the only one that
-  /// is visible after the execution of the SCoP.
-  ///
-  isl::union_set getLiveOut(Scop &S);
-  bool eliminateDeadCode(Scop &S, int PreciseSteps);
 };
-} // namespace
 
-char DeadCodeElim::ID = 0;
+char DeadCodeElimWrapperPass::ID = 0;
 
-// To compute the live outs, we compute for the data-locations that are
-// must-written to the last statement that touches these locations. On top of
-// this we add all statements that perform may-write accesses.
-//
-// We could be more precise by removing may-write accesses for which we know
-// that they are overwritten by a must-write after. However, at the moment the
-// only may-writes we introduce access the full (unbounded) array, such that
-// bounded write accesses can not overwrite all of the data-locations. As
-// this means may-writes are in the current situation always live, there is
-// no point in trying to remove them from the live-out set.
-isl::union_set DeadCodeElim::getLiveOut(Scop &S) {
+/// Return the set of live iterations.
+///
+/// The set of live iterations are all iterations that write to memory and for
+/// which we can not prove that there will be a later write that _must_
+/// overwrite the same memory location and is consequently the only one that
+/// is visible after the execution of the SCoP.
+///
+/// To compute the live outs, we compute for the data-locations that are
+/// must-written to the last statement that touches these locations. On top of
+/// this we add all statements that perform may-write accesses.
+///
+/// We could be more precise by removing may-write accesses for which we know
+/// that they are overwritten by a must-write after. However, at the moment the
+/// only may-writes we introduce access the full (unbounded) array, such that
+/// bounded write accesses can not overwrite all of the data-locations. As
+/// this means may-writes are in the current situation always live, there is
+/// no point in trying to remove them from the live-out set.
+static isl::union_set getLiveOut(Scop &S) {
   isl::union_map Schedule = S.getSchedule();
   isl::union_map MustWrites = S.getMustWrites();
   isl::union_map WriteIterations = MustWrites.reverse();
@@ -110,10 +106,8 @@
 /// To ensure the set of live iterations does not get too complex we always
 /// combine a certain number of precise steps with one approximating step that
 /// simplifies the life set with an affine hull.
-bool DeadCodeElim::eliminateDeadCode(Scop &S, int PreciseSteps) {
-  DependenceInfo &DI = getAnalysis<DependenceInfo>();
-  const Dependences &D = DI.getDependences(Dependences::AL_Statement);
-
+static bool runDeadCodeElimination(Scop &S, int PreciseSteps,
+                                   const Dependences &D) {
   if (!D.hasValidDependences())
     return false;
 
@@ -147,29 +141,60 @@
 
   Live = Live.coalesce();
 
-  bool Changed = S.restrictDomains(Live);
+  return S.restrictDomains(Live);
+}
+
+bool DeadCodeElimWrapperPass::runOnScop(Scop &S) {
+  auto &DI = getAnalysis<DependenceInfo>();
+  const Dependences &Deps = DI.getDependences(Dependences::AL_Statement);
+
+  bool Changed = runDeadCodeElimination(S, DCEPreciseSteps, Deps);
 
   // FIXME: We can probably avoid the recomputation of all dependences by
   // updating them explicitly.
   if (Changed)
     DI.recomputeDependences(Dependences::AL_Statement);
-  return Changed;
+
+  return false;
 }
 
-bool DeadCodeElim::runOnScop(Scop &S) {
-  return eliminateDeadCode(S, DCEPreciseSteps);
-}
-
-void DeadCodeElim::getAnalysisUsage(AnalysisUsage &AU) const {
+void DeadCodeElimWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
   ScopPass::getAnalysisUsage(AU);
   AU.addRequired<DependenceInfo>();
 }
 
-Pass *polly::createDeadCodeElimPass() { return new DeadCodeElim(); }
+} // namespace
 
-INITIALIZE_PASS_BEGIN(DeadCodeElim, "polly-dce",
+Pass *polly::createDeadCodeElimWrapperPass() {
+  return new DeadCodeElimWrapperPass();
+}
+
+llvm::PreservedAnalyses DeadCodeElimPass::run(Scop &S, ScopAnalysisManager &SAM,
+                                              ScopStandardAnalysisResults &SAR,
+                                              SPMUpdater &U) {
+  DependenceAnalysis::Result &DA = SAM.getResult<DependenceAnalysis>(S, SAR);
+  const Dependences &Deps = DA.getDependences(Dependences::AL_Statement);
+
+  bool Changed = runDeadCodeElimination(S, DCEPreciseSteps, Deps);
+
+  // FIXME: We can probably avoid the recomputation of all dependences by
+  // updating them explicitly.
+  if (Changed)
+    DA.recomputeDependences(Dependences::AL_Statement);
+
+  if (!Changed)
+    return PreservedAnalyses::all();
+
+  PreservedAnalyses PA;
+  PA.preserveSet<AllAnalysesOn<Module>>();
+  PA.preserveSet<AllAnalysesOn<Function>>();
+  PA.preserveSet<AllAnalysesOn<Loop>>();
+  return PA;
+}
+
+INITIALIZE_PASS_BEGIN(DeadCodeElimWrapperPass, "polly-dce",
                       "Polly - Remove dead iterations", false, false)
 INITIALIZE_PASS_DEPENDENCY(DependenceInfo)
 INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass)
-INITIALIZE_PASS_END(DeadCodeElim, "polly-dce", "Polly - Remove dead iterations",
-                    false, false)
+INITIALIZE_PASS_END(DeadCodeElimWrapperPass, "polly-dce",
+                    "Polly - Remove dead iterations", false, false)
diff --git a/test/DeadCodeElimination/computeout.ll b/test/DeadCodeElimination/computeout.ll
index 6b40a09..d18ad44 100644
--- a/test/DeadCodeElimination/computeout.ll
+++ b/test/DeadCodeElimination/computeout.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -S %loadPolly -basic-aa -polly-dce -polly-ast -analyze < %s | FileCheck %s
+; RUN: opt -S %loadPolly "-passes=scop(polly-dce,print<polly-ast>)" < %s | FileCheck %s
 ; RUN: opt -S %loadPolly -basic-aa -polly-dce -polly-ast -analyze -polly-dependences-computeout=1 < %s | FileCheck %s -check-prefix=TIMEOUT
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
 
diff --git a/test/DeadCodeElimination/dead_iteration_elimination.ll b/test/DeadCodeElimination/dead_iteration_elimination.ll
index cc9851f..92442c7 100644
--- a/test/DeadCodeElimination/dead_iteration_elimination.ll
+++ b/test/DeadCodeElimination/dead_iteration_elimination.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -S %loadPolly -basic-aa -polly-dependences-analysis-type=value-based -polly-dce -polly-dce-precise-steps=2 -polly-ast -analyze < %s | FileCheck %s
+; RUN: opt -S %loadPolly "-passes=scop(polly-dce,print<polly-ast>)" -polly-dependences-analysis-type=value-based -polly-dce-precise-steps=2 < %s | FileCheck %s
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
 ;
 ; for(i = 0; i < 200; i++ )