Revert "[Polly] Update ScopInliner for NPM (#125427)"
This reverts commit 0b9a7b80c0674c5c6f746139912111bea7eae63b.
This is causing test failures under LLVM:
1. Other/pass-pipeline-parsing.ll
This broke premerge. This was notably not caught by premerge testing on
the original PR because the original PR only touches polly, and premerge
does not test LLVM when only polly is touched.
diff --git a/polly/docs/ReleaseNotes.rst b/polly/docs/ReleaseNotes.rst
index f5ea47b..f7c9689 100644
--- a/polly/docs/ReleaseNotes.rst
+++ b/polly/docs/ReleaseNotes.rst
@@ -11,5 +11,3 @@
the new features that have recently been committed to our development
branch.
- * ScopInliner has been updated for the New Pass Manager.
-
diff --git a/polly/include/polly/LinkAllPasses.h b/polly/include/polly/LinkAllPasses.h
index 9978344c..c3b68a7 100644
--- a/polly/include/polly/LinkAllPasses.h
+++ b/polly/include/polly/LinkAllPasses.h
@@ -119,7 +119,7 @@
namespace llvm {
void initializeCodePreparationPass(llvm::PassRegistry &);
-void initializeScopInlinerWrapperPassPass(llvm::PassRegistry &);
+void initializeScopInlinerPass(llvm::PassRegistry &);
void initializeScopDetectionWrapperPassPass(llvm::PassRegistry &);
void initializeScopDetectionPrinterLegacyPassPass(llvm::PassRegistry &);
void initializeScopInfoRegionPassPass(PassRegistry &);
diff --git a/polly/include/polly/ScopInliner.h b/polly/include/polly/ScopInliner.h
deleted file mode 100644
index 0146678..0000000
--- a/polly/include/polly/ScopInliner.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===------ ScopInliner.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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef POLLY_POLLYINLINER_H
-#define POLLY_POLLYINLINER_H
-
-#include "llvm/Analysis/CGSCCPassManager.h"
-#include "llvm/Analysis/LazyCallGraph.h"
-#include "llvm/IR/PassManager.h"
-
-namespace polly {
-class ScopInlinerPass : public llvm::PassInfoMixin<ScopInlinerPass> {
-public:
- ScopInlinerPass();
-
- llvm::PreservedAnalyses run(llvm::LazyCallGraph::SCC &C,
- llvm::CGSCCAnalysisManager &AM,
- llvm::LazyCallGraph &CG,
- llvm::CGSCCUpdateResult &UR);
-};
-
-llvm::Pass *createScopInlinerWrapperPass();
-} // namespace polly
-
-namespace llvm {
-void initializeScopInlinerWrapperPassPass(llvm::PassRegistry &);
-}
-
-#endif /* POLLY_POLLYINLINER_H */
diff --git a/polly/lib/Support/PollyPasses.def b/polly/lib/Support/PollyPasses.def
index 2c792a5..e068f31 100644
--- a/polly/lib/Support/PollyPasses.def
+++ b/polly/lib/Support/PollyPasses.def
@@ -1,9 +1,3 @@
-#ifndef CGSCC_PASS
-#define CGSCC_PASS(NAME, CREATE_PASS, PARSER)
-#endif
-CGSCC_PASS("polly-inline", ScopInlinerPass(), parseNoOptions)
-#undef CGSCC_PASS
-
#ifndef FUNCTION_ANALYSIS
#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)
#endif
diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp
index 1222222..0420dff 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -35,7 +35,6 @@
#include "polly/ScopDetection.h"
#include "polly/ScopGraphPrinter.h"
#include "polly/ScopInfo.h"
-#include "polly/ScopInliner.h"
#include "polly/Simplify.h"
#include "polly/Support/DumpFunctionPass.h"
#include "polly/Support/DumpModulePass.h"
@@ -47,13 +46,10 @@
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Error.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Transforms/IPO.h"
-using namespace llvm;
namespace cl = llvm::cl;
-using namespace polly;
using llvm::FunctionPassManager;
using llvm::OptimizationLevel;
@@ -237,7 +233,7 @@
initializePollyCanonicalizePass(Registry);
initializeScopDetectionWrapperPassPass(Registry);
initializeScopDetectionPrinterLegacyPassPass(Registry);
- initializeScopInlinerWrapperPassPass(Registry);
+ initializeScopInlinerPass(Registry);
initializeScopInfoRegionPassPass(Registry);
initializeScopInfoPrinterLegacyRegionPassPass(Registry);
initializeScopInfoWrapperPassPass(Registry);
@@ -438,16 +434,6 @@
false);
}
-static llvm::Expected<std::monostate> parseNoOptions(StringRef Params) {
- if (!Params.empty())
- return make_error<StringError>(
- formatv("'{0}' passed to pass that does not take any options", Params)
- .str(),
- inconvertibleErrorCode());
-
- return std::monostate{};
-}
-
static OwningScopAnalysisManagerFunctionProxy
createScopAnalyses(FunctionAnalysisManager &FAM,
PassInstrumentationCallbacks *PIC) {
@@ -475,25 +461,6 @@
FAM.registerPass([&FAM, PIC] { return createScopAnalyses(FAM, PIC); });
}
-static llvm::Expected<bool>
-parseCGPipeline(StringRef Name, llvm::CGSCCPassManager &CGPM,
- PassInstrumentationCallbacks *PIC,
- ArrayRef<PassBuilder::PipelineElement> Pipeline) {
- assert(Pipeline.empty());
-
-#define CGSCC_PASS(NAME, CREATE_PASS, PARSER) \
- if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
- auto Params = PassBuilder::parsePassParameters(PARSER, Name, NAME); \
- if (!Params) \
- return Params.takeError(); \
- CGPM.addPass(CREATE_PASS); \
- return true; \
- }
-#include "PollyPasses.def"
-
- return false;
-}
-
static bool
parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
ArrayRef<PassBuilder::PipelineElement> Pipeline) {
@@ -631,12 +598,6 @@
ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {
return parseScopPipeline(Name, FPM, PIC, Pipeline);
});
- PB.registerPipelineParsingCallback(
- [PIC](StringRef Name, CGSCCPassManager &CGPM,
- ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {
- ExitOnError Err("Unable to parse Polly call graph pass: ");
- return Err(parseCGPipeline(Name, CGPM, PIC, Pipeline));
- });
PB.registerParseTopLevelPipelineCallback(
[PIC](llvm::ModulePassManager &MPM,
ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {
diff --git a/polly/lib/Transform/ScopInliner.cpp b/polly/lib/Transform/ScopInliner.cpp
index c04ba34..b78206c 100644
--- a/polly/lib/Transform/ScopInliner.cpp
+++ b/polly/lib/Transform/ScopInliner.cpp
@@ -13,14 +13,10 @@
//
//===----------------------------------------------------------------------===//
-#include "polly/ScopInliner.h"
+#include "polly/LinkAllPasses.h"
#include "polly/ScopDetection.h"
-#include "polly/ScopInliner.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
-#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/Analysis/RegionInfo.h"
-#include "llvm/IR/Dominators.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
@@ -32,77 +28,13 @@
using namespace polly;
namespace {
-
-/// Inliner implementation that works with both, LPM (using SCC_t=CallGraph) and
-/// NPM (using SCC_t=LazyCallGraph::SCC)
-template <typename SCC_t> bool runScopInlinerImpl(Function *F, SCC_t &SCC) {
- // We do not try to inline non-trivial SCCs because this would lead to
- // "infinite" inlining if we are not careful.
- if (SCC.size() > 1)
- return false;
- assert(SCC.size() == 1 && "found empty SCC");
-
- // If the function is a nullptr, or the function is a declaration.
- if (!F)
- return false;
- if (F->isDeclaration()) {
- POLLY_DEBUG(dbgs() << "Skipping " << F->getName()
- << "because it is a declaration.\n");
- return false;
- }
-
- PassBuilder PB;
- // Populate analysis managers and register Polly-specific analyses.
- LoopAnalysisManager LAM;
- FunctionAnalysisManager FAM;
- CGSCCAnalysisManager CGAM;
- ModuleAnalysisManager MAM;
- PB.registerModuleAnalyses(MAM);
- PB.registerCGSCCAnalyses(CGAM);
- PB.registerFunctionAnalyses(FAM);
- PB.registerLoopAnalyses(LAM);
- PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
-
- auto &DT = FAM.getResult<DominatorTreeAnalysis>(*F);
- auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(*F);
- auto &LI = FAM.getResult<LoopAnalysis>(*F);
- auto &RI = FAM.getResult<RegionInfoAnalysis>(*F);
- auto &AA = FAM.getResult<AAManager>(*F);
- auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(*F);
- ScopDetection SD(DT, SE, LI, RI, AA, ORE);
- SD.detect(*F);
-
- const bool HasScopAsTopLevelRegion =
- SD.ValidRegions.contains(RI.getTopLevelRegion());
-
- bool Changed = false;
- if (HasScopAsTopLevelRegion) {
- POLLY_DEBUG(dbgs() << "Skipping " << F->getName()
- << " has scop as top level region");
- F->addFnAttr(llvm::Attribute::AlwaysInline);
-
- ModulePassManager MPM;
- MPM.addPass(AlwaysInlinerPass());
- Module *M = F->getParent();
- assert(M && "Function has illegal module");
- PreservedAnalyses PA = MPM.run(*M, MAM);
- if (!PA.areAllPreserved())
- Changed = true;
- } else {
- POLLY_DEBUG(dbgs() << F->getName()
- << " does NOT have scop as top level region\n");
- }
-
- return Changed;
-}
-
-class ScopInlinerWrapperPass final : public CallGraphSCCPass {
+class ScopInliner final : public CallGraphSCCPass {
using llvm::Pass::doInitialization;
public:
static char ID;
- ScopInlinerWrapperPass() : CallGraphSCCPass(ID) {}
+ ScopInliner() : CallGraphSCCPass(ID) {}
bool doInitialization(CallGraph &CG) override {
if (!polly::PollyAllowFullFunction) {
@@ -118,8 +50,60 @@
}
bool runOnSCC(CallGraphSCC &SCC) override {
+ // We do not try to inline non-trivial SCCs because this would lead to
+ // "infinite" inlining if we are not careful.
+ if (SCC.size() > 1)
+ return false;
+ assert(SCC.size() == 1 && "found empty SCC");
Function *F = (*SCC.begin())->getFunction();
- return runScopInlinerImpl(F, SCC);
+
+ // If the function is a nullptr, or the function is a declaration.
+ if (!F)
+ return false;
+ if (F->isDeclaration()) {
+ POLLY_DEBUG(dbgs() << "Skipping " << F->getName()
+ << "because it is a declaration.\n");
+ return false;
+ }
+
+ PassBuilder PB;
+ // Populate analysis managers and register Polly-specific analyses.
+ LoopAnalysisManager LAM;
+ FunctionAnalysisManager FAM;
+ CGSCCAnalysisManager CGAM;
+ ModuleAnalysisManager MAM;
+ FAM.registerPass([] { return ScopAnalysis(); });
+ PB.registerModuleAnalyses(MAM);
+ PB.registerCGSCCAnalyses(CGAM);
+ PB.registerFunctionAnalyses(FAM);
+ PB.registerLoopAnalyses(LAM);
+ PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
+
+ RegionInfo &RI = FAM.getResult<RegionInfoAnalysis>(*F);
+ ScopDetection &SD = FAM.getResult<ScopAnalysis>(*F);
+
+ const bool HasScopAsTopLevelRegion =
+ SD.ValidRegions.contains(RI.getTopLevelRegion());
+
+ bool Changed = false;
+ if (HasScopAsTopLevelRegion) {
+ POLLY_DEBUG(dbgs() << "Skipping " << F->getName()
+ << " has scop as top level region");
+ F->addFnAttr(llvm::Attribute::AlwaysInline);
+
+ ModulePassManager MPM;
+ MPM.addPass(AlwaysInlinerPass());
+ Module *M = F->getParent();
+ assert(M && "Function has illegal module");
+ PreservedAnalyses PA = MPM.run(*M, MAM);
+ if (!PA.areAllPreserved())
+ Changed = true;
+ } else {
+ POLLY_DEBUG(dbgs() << F->getName()
+ << " does NOT have scop as top level region\n");
+ }
+
+ return Changed;
};
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -127,39 +111,18 @@
}
};
} // namespace
-char ScopInlinerWrapperPass::ID;
+char ScopInliner::ID;
-Pass *polly::createScopInlinerWrapperPass() {
- ScopInlinerWrapperPass *pass = new ScopInlinerWrapperPass();
+Pass *polly::createScopInlinerPass() {
+ ScopInliner *pass = new ScopInliner();
return pass;
}
INITIALIZE_PASS_BEGIN(
- ScopInlinerWrapperPass, "polly-scop-inliner",
+ ScopInliner, "polly-scop-inliner",
"inline functions based on how much of the function is a scop.", false,
false)
INITIALIZE_PASS_END(
- ScopInlinerWrapperPass, "polly-scop-inliner",
+ ScopInliner, "polly-scop-inliner",
"inline functions based on how much of the function is a scop.", false,
false)
-
-polly::ScopInlinerPass::ScopInlinerPass() {
- if (!polly::PollyAllowFullFunction) {
- report_fatal_error(
- "Aborting from ScopInliner because it only makes sense to run with "
- "-polly-allow-full-function. "
- "The heurtistic for ScopInliner checks that the full function is a "
- "Scop, which happens if and only if polly-allow-full-function is "
- " enabled. "
- " If not, the entry block is not included in the Scop");
- }
-}
-
-PreservedAnalyses polly::ScopInlinerPass::run(llvm::LazyCallGraph::SCC &SCC,
- llvm::CGSCCAnalysisManager &AM,
- llvm::LazyCallGraph &CG,
- llvm::CGSCCUpdateResult &UR) {
- Function *F = &SCC.begin()->getFunction();
- bool Changed = runScopInlinerImpl(F, SCC);
- return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
-}
diff --git a/polly/test/ScopInliner/ignore-declares.ll b/polly/test/ScopInliner/ignore-declares.ll
index 5c0cfa1..11722dc 100644
--- a/polly/test/ScopInliner/ignore-declares.ll
+++ b/polly/test/ScopInliner/ignore-declares.ll
@@ -1,4 +1,5 @@
-; RUN: opt %loadNPMPolly -polly-detect-full-functions '-passes=cgscc(polly-inline),function(print<polly-function-scops>)' -disable-output < %s
+; RUN: opt %loadPolly -polly-detect-full-functions -polly-scop-inliner \
+; RUN: -polly-scops -disable-output < %s
; Check that we do not crash if there are declares. We should skip function
; declarations and not try to query for domtree.
diff --git a/polly/test/ScopInliner/invariant-load-func.ll b/polly/test/ScopInliner/invariant-load-func.ll
index 58c556a..ffd2ec9 100644
--- a/polly/test/ScopInliner/invariant-load-func.ll
+++ b/polly/test/ScopInliner/invariant-load-func.ll
@@ -1,9 +1,12 @@
-; RUN: opt %loadNPMPolly -polly-detect-full-functions -polly-invariant-load-hoisting '-passes=cgscc(polly-inline),function(print<polly-function-scops>)' -disable-output < %s 2>&1 | FileCheck %s
+; RUN: opt %loadNPMPolly -polly-detect-full-functions -polly-scop-inliner \
+; RUN: -polly-invariant-load-hoisting '-passes=print<polly-function-scops>' -disable-output < %s | FileCheck %s
; Check that we inline a function that requires invariant load hoisting
; correctly.
; CHECK: Max Loop Depth: 2
+; REQUIRES: pollyacc
+
; void to_be_inlined(int A[], int *begin, int *end) {
; for(int i = *begin; i < *end; i++) {
diff --git a/polly/test/ScopInliner/simple-inline-loop.ll b/polly/test/ScopInliner/simple-inline-loop.ll
index f12798a..a5e3483 100644
--- a/polly/test/ScopInliner/simple-inline-loop.ll
+++ b/polly/test/ScopInliner/simple-inline-loop.ll
@@ -1,4 +1,5 @@
-; RUN: opt %loadNPMPolly -polly-detect-full-functions '-passes=cgscc(polly-inline),function(print<polly-function-scops>)' -disable-output < %s 2>&1 | FileCheck %s
+; RUN: opt %loadPolly -polly-detect-full-functions -polly-scop-inliner \
+; RUN: -polly-print-scops -disable-output < %s | FileCheck %s
; Check that we get the 2 nested loops by inlining `to_be_inlined` into
; `inline_site`.