Index: include/polly/LinkAllPasses.h =================================================================== --- include/polly/LinkAllPasses.h +++ include/polly/LinkAllPasses.h @@ -38,6 +38,7 @@ llvm::Pass *createPollyCanonicalizePass(); llvm::Pass *createScopDetectionPass(); llvm::Pass *createScopInfoRegionPassPass(); +llvm::Pass *createScopInfoWrapperPassPass(); llvm::Pass *createIslAstInfoPass(); llvm::Pass *createCodeGenerationPass(); llvm::Pass *createIslScheduleOptimizerPass(); Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -2518,11 +2518,66 @@ void getAnalysisUsage(AnalysisUsage &AU) const override; }; +//===----------------------------------------------------------------------===// +/// @brief The legacy pass manager's analysis pass to compute scop information +/// for the whole function. +/// +/// This pass will maintain a map of the maximal region within a scop to its +/// scop object for all the feasible scops present in a function. +/// This pass is an alternative to the ScopInfoRegionPass in order to avoid a +/// region pass manager. +class ScopInfoWrapperPass : public FunctionPass { + +public: + using RegionToScopMapTy = DenseMap>; + using iterator = RegionToScopMapTy::iterator; + using const_iterator = RegionToScopMapTy::const_iterator; + +private: + /// @brief A map of Region to its Scop object containing + /// Polly IR of static control part + RegionToScopMapTy RegionToScopMap; + +public: + static char ID; // Pass identification, replacement for typeid + + ScopInfoWrapperPass() : FunctionPass(ID) {} + ~ScopInfoWrapperPass() {} + + /// @brief Get the Scop object for the given Region + /// + /// @return If the given region is the maximal region within a scop, return + /// the scop object. If the given region is a subregion, return a + /// nullptr. Top level region containing the entry block of a function + /// is not considered in the scop creation. + Scop *getScop(Region *R) const { + auto MapIt = RegionToScopMap.find(R); + if (MapIt != RegionToScopMap.end()) + return MapIt->second.get(); + return nullptr; + } + + iterator begin() { return RegionToScopMap.begin(); } + iterator end() { return RegionToScopMap.end(); } + const_iterator begin() const { return RegionToScopMap.begin(); } + const_iterator end() const { return RegionToScopMap.end(); } + + /// @brief Calculate all the polyhedral scops for a given function. + bool runOnFunction(Function &F) override; + + void releaseMemory() override { RegionToScopMap.clear(); } + + void print(raw_ostream &O, const Module *M = nullptr) const override; + + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + } // end namespace polly namespace llvm { class PassRegistry; void initializeScopInfoRegionPassPass(llvm::PassRegistry &); +void initializeScopInfoWrapperPassPass(llvm::PassRegistry &); } #endif Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -4936,3 +4936,72 @@ INITIALIZE_PASS_END(ScopInfoRegionPass, "polly-scops", "Polly - Create polyhedral description of Scops", false, false) + +//===----------------------------------------------------------------------===// +void ScopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + AU.addRequiredTransitive(); + AU.addRequiredTransitive(); + AU.addRequired(); + AU.addRequired(); + AU.setPreservesAll(); +} + +bool ScopInfoWrapperPass::runOnFunction(Function &F) { + auto &SD = getAnalysis(); + + auto &SE = getAnalysis().getSE(); + auto &LI = getAnalysis().getLoopInfo(); + auto &AA = getAnalysis().getAAResults(); + auto const &DL = F.getParent()->getDataLayout(); + auto &DT = getAnalysis().getDomTree(); + auto &AC = getAnalysis().getAssumptionCache(F); + + /// Create polyhedral descripton of scops for all the valid regions of a + /// function. + for (auto &It : SD) { + Region *R = const_cast(It); + if (!SD.isMaxRegionInScop(*R)) + continue; + + ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE); + bool Inserted = + RegionToScopMap.insert(std::make_pair(R, SB.getScop())).second; + assert(Inserted && "Building Scop for the same region twice!"); + (void)Inserted; + } + return false; +} + +void ScopInfoWrapperPass::print(raw_ostream &OS, const Module *) const { + for (auto &It : RegionToScopMap) { + if (It.second) + It.second->print(OS); + else + OS << "Invalid Scop!\n"; + } +} + +char ScopInfoWrapperPass::ID = 0; + +Pass *polly::createScopInfoWrapperPassPass() { + return new ScopInfoWrapperPass(); +} + +INITIALIZE_PASS_BEGIN( + ScopInfoWrapperPass, "polly-function-scops", + "Polly - Create polyhedral description of all Scops of a function", false, + false); +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass); +INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker); +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass); +INITIALIZE_PASS_DEPENDENCY(RegionInfoPass); +INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass); +INITIALIZE_PASS_DEPENDENCY(ScopDetection); +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass); +INITIALIZE_PASS_END( + ScopInfoWrapperPass, "polly-function-scops", + "Polly - Create polyhedral description of all Scops of a function", false, + false) Index: lib/Support/RegisterPasses.cpp =================================================================== --- lib/Support/RegisterPasses.cpp +++ lib/Support/RegisterPasses.cpp @@ -155,6 +155,7 @@ initializePollyCanonicalizePass(Registry); initializeScopDetectionPass(Registry); initializeScopInfoRegionPassPass(Registry); + initializeScopInfoWrapperPassPass(Registry); initializeCodegenCleanupPass(Registry); } Index: test/ScopInfo/assume_gep_bounds.ll =================================================================== --- test/ScopInfo/assume_gep_bounds.ll +++ test/ScopInfo/assume_gep_bounds.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-function-scops -analyze < %s | FileCheck %s ; void foo(float A[][20][30], long n, long m, long p) { ; for (long i = 0; i < n; i++) Index: test/ScopInfo/constant_factor_in_parameter.ll =================================================================== --- test/ScopInfo/constant_factor_in_parameter.ll +++ test/ScopInfo/constant_factor_in_parameter.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -analyze -polly-scops < %s | FileCheck %s +; RUN: opt %loadPolly -analyze -polly-function-scops < %s | FileCheck %s ; ; Check that the constant part of the N * M * 4 expression is not part of the ; parameter but explicit in the access function. This can avoid existentially Index: test/ScopInfo/invariant_load_loop_ub.ll =================================================================== --- test/ScopInfo/invariant_load_loop_ub.ll +++ test/ScopInfo/invariant_load_loop_ub.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -polly-process-unprofitable -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-function-scops -polly-process-unprofitable -analyze < %s | FileCheck %s ; ; CHECK: Invariant Accesses: ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] Index: test/ScopInfo/loop_affine_bound_0.ll =================================================================== --- test/ScopInfo/loop_affine_bound_0.ll +++ test/ScopInfo/loop_affine_bound_0.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-function-scops -analyze < %s | FileCheck %s ; void f(long a[][128], long N, long M) { ; long i, j; Index: test/ScopInfo/loop_affine_bound_1.ll =================================================================== --- test/ScopInfo/loop_affine_bound_1.ll +++ test/ScopInfo/loop_affine_bound_1.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-function-scops -analyze < %s | FileCheck %s ;void f(long a[][128], long N, long M) { ; long i, j; Index: test/ScopInfo/loop_affine_bound_2.ll =================================================================== --- test/ScopInfo/loop_affine_bound_2.ll +++ test/ScopInfo/loop_affine_bound_2.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-function-scops -analyze < %s | FileCheck %s ; void f(long a[][128], long N, long M) { ; long i, j; Index: test/ScopInfo/multidim_2d-diagonal-matrix.ll =================================================================== --- test/ScopInfo/multidim_2d-diagonal-matrix.ll +++ test/ScopInfo/multidim_2d-diagonal-matrix.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-function-scops -analyze < %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-S128" ; Derived from the following code: Index: test/ScopInfo/multidim_many_references.ll =================================================================== --- test/ScopInfo/multidim_many_references.ll +++ test/ScopInfo/multidim_many_references.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -analyze -polly-ignore-aliasing < %s | FileCheck %s +; RUN: opt %loadPolly -polly-function-scops -analyze -polly-ignore-aliasing < %s | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" Index: test/ScopInfo/multidim_nested_start_integer.ll =================================================================== --- test/ScopInfo/multidim_nested_start_integer.ll +++ test/ScopInfo/multidim_nested_start_integer.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-function-scops -analyze < %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-S128" ; void foo(long n, long m, long o, double A[n][m][o]) { Index: test/ScopInfo/multidim_single_and_multidim_array.ll =================================================================== --- test/ScopInfo/multidim_single_and_multidim_array.ll +++ test/ScopInfo/multidim_single_and_multidim_array.ll @@ -2,6 +2,10 @@ ; RUN: opt %loadPolly -polly-scops -polly-delinearize=false -polly-allow-nonaffine -analyze < %s | FileCheck %s --check-prefix=NONAFFINE ; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s --check-prefix=DELIN ; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine -analyze < %s | FileCheck %s --check-prefix=DELIN +; RUN: opt %loadPolly -polly-function-scops -polly-delinearize=false -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-function-scops -polly-delinearize=false -polly-allow-nonaffine -analyze < %s | FileCheck %s --check-prefix=NONAFFINE +; RUN: opt %loadPolly -polly-function-scops -analyze < %s | FileCheck %s --check-prefix=DELIN +; RUN: opt %loadPolly -polly-function-scops -polly-allow-nonaffine -analyze < %s | FileCheck %s --check-prefix=DELIN target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" Index: test/ScopInfo/non_affine_region_3.ll =================================================================== --- test/ScopInfo/non_affine_region_3.ll +++ test/ScopInfo/non_affine_region_3.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-function-scops -analyze < %s | FileCheck %s ; ; Verify the scalar x defined in a non-affine subregion is written as it ; escapes the region. In this test the two conditionals inside the region Index: test/ScopInfo/reduction_two_identical_reads.ll =================================================================== --- test/ScopInfo/reduction_two_identical_reads.ll +++ test/ScopInfo/reduction_two_identical_reads.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-function-scops -analyze < %s | FileCheck %s ; ; CHECK: Reduction Type: NONE ; Index: test/ScopInfo/scalar_to_array.ll =================================================================== --- test/ScopInfo/scalar_to_array.ll +++ test/ScopInfo/scalar_to_array.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -basicaa -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -basicaa -polly-function-scops -analyze < %s | FileCheck %s ; ModuleID = 'scalar_to_array.ll' 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" Index: test/ScopInfo/test-wrapping-in-condition.ll =================================================================== --- test/ScopInfo/test-wrapping-in-condition.ll +++ test/ScopInfo/test-wrapping-in-condition.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-function-scops -analyze < %s | FileCheck %s ; ; CHECK: Invalid Context: ; CHECK: [N] -> { : N >= 129 }