mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-27 02:09:54 +00:00
[GSoC 2016]New function pass ScopInfoWrapperPass
This patch adds a new function pass ScopInfoWrapperPass so that the polyhedral description of a region, the SCoP, can be constructed and used in a function pass. Patch by Utpal Bora <cs14mtech11017@iith.ac.in> Differential Revision: http://reviews.llvm.org/D20962 llvm-svn: 273856
This commit is contained in:
parent
b7e9713563
commit
4ba65a5622
@ -38,6 +38,7 @@ llvm::Pass *createJSONImporterPass();
|
||||
llvm::Pass *createPollyCanonicalizePass();
|
||||
llvm::Pass *createScopDetectionPass();
|
||||
llvm::Pass *createScopInfoRegionPassPass();
|
||||
llvm::Pass *createScopInfoWrapperPassPass();
|
||||
llvm::Pass *createIslAstInfoPass();
|
||||
llvm::Pass *createCodeGenerationPass();
|
||||
llvm::Pass *createIslScheduleOptimizerPass();
|
||||
|
@ -2518,11 +2518,66 @@ public:
|
||||
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<Region *, std::unique_ptr<Scop>>;
|
||||
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 &);
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -4936,3 +4936,72 @@ INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
|
||||
INITIALIZE_PASS_END(ScopInfoRegionPass, "polly-scops",
|
||||
"Polly - Create polyhedral description of Scops", false,
|
||||
false)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
void ScopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<LoopInfoWrapperPass>();
|
||||
AU.addRequired<RegionInfoPass>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
|
||||
AU.addRequiredTransitive<ScopDetection>();
|
||||
AU.addRequired<AAResultsWrapperPass>();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
bool ScopInfoWrapperPass::runOnFunction(Function &F) {
|
||||
auto &SD = getAnalysis<ScopDetection>();
|
||||
|
||||
auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||
auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
auto const &DL = F.getParent()->getDataLayout();
|
||||
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
|
||||
/// Create polyhedral descripton of scops for all the valid regions of a
|
||||
/// function.
|
||||
for (auto &It : SD) {
|
||||
Region *R = const_cast<Region *>(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)
|
||||
|
@ -155,6 +155,7 @@ void initializePollyPasses(PassRegistry &Registry) {
|
||||
initializePollyCanonicalizePass(Registry);
|
||||
initializeScopDetectionPass(Registry);
|
||||
initializeScopInfoRegionPassPass(Registry);
|
||||
initializeScopInfoWrapperPassPass(Registry);
|
||||
initializeCodegenCleanupPass(Registry);
|
||||
}
|
||||
|
||||
|
@ -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++)
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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]) {
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
;
|
||||
|
@ -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"
|
||||
|
@ -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 }
|
||||
|
Loading…
Reference in New Issue
Block a user