[Polly][NewPM] Port Simplify to the new pass manager
Reviewed By: Meinersbur Differential Revision: https://reviews.llvm.org/D87328
This commit is contained in:
parent
d06485685d
commit
deb00cf0b5
|
@ -13,13 +13,109 @@
|
|||
#ifndef POLLY_TRANSFORM_SIMPLIFY_H
|
||||
#define POLLY_TRANSFORM_SIMPLIFY_H
|
||||
|
||||
#include "polly/ScopPass.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
namespace llvm {
|
||||
class PassRegistry;
|
||||
class Pass;
|
||||
} // namespace llvm
|
||||
|
||||
namespace {
|
||||
class SimplifyVisitor {
|
||||
private:
|
||||
/// The invocation id (if there are multiple instances in the pass manager's
|
||||
/// pipeline) to determine which statistics to update.
|
||||
int CallNo;
|
||||
|
||||
/// The last/current SCoP that is/has been processed.
|
||||
Scop *S;
|
||||
|
||||
/// Number of statements with empty domains removed from the SCoP.
|
||||
int EmptyDomainsRemoved = 0;
|
||||
|
||||
/// Number of writes that are overwritten anyway.
|
||||
int OverwritesRemoved = 0;
|
||||
|
||||
/// Number of combined writes.
|
||||
int WritesCoalesced = 0;
|
||||
|
||||
/// Number of redundant writes removed from this SCoP.
|
||||
int RedundantWritesRemoved = 0;
|
||||
|
||||
/// Number of writes with empty access domain removed.
|
||||
int EmptyPartialAccessesRemoved = 0;
|
||||
|
||||
/// Number of unused accesses removed from this SCoP.
|
||||
int DeadAccessesRemoved = 0;
|
||||
|
||||
/// Number of unused instructions removed from this SCoP.
|
||||
int DeadInstructionsRemoved = 0;
|
||||
|
||||
/// Number of unnecessary statements removed from the SCoP.
|
||||
int StmtsRemoved = 0;
|
||||
|
||||
/// Return whether at least one simplification has been applied.
|
||||
bool isModified() const;
|
||||
|
||||
/// Remove statements that are never executed due to their domains being
|
||||
/// empty.
|
||||
///
|
||||
/// In contrast to Scop::simplifySCoP, this removes based on the SCoP's
|
||||
/// effective domain, i.e. including the SCoP's context as used by some other
|
||||
/// simplification methods in this pass. This is necessary because the
|
||||
/// analysis on empty domains is unreliable, e.g. remove a scalar value
|
||||
/// definition MemoryAccesses, but not its use.
|
||||
void removeEmptyDomainStmts();
|
||||
|
||||
/// Remove writes that are overwritten unconditionally later in the same
|
||||
/// statement.
|
||||
///
|
||||
/// There must be no read of the same value between the write (that is to be
|
||||
/// removed) and the overwrite.
|
||||
void removeOverwrites();
|
||||
|
||||
/// Combine writes that write the same value if possible.
|
||||
///
|
||||
/// This function is able to combine:
|
||||
/// - Partial writes with disjoint domain.
|
||||
/// - Writes that write to the same array element.
|
||||
///
|
||||
/// In all cases, both writes must write the same values.
|
||||
void coalesceWrites();
|
||||
|
||||
/// Remove writes that just write the same value already stored in the
|
||||
/// element.
|
||||
void removeRedundantWrites();
|
||||
|
||||
/// Remove statements without side effects.
|
||||
void removeUnnecessaryStmts();
|
||||
|
||||
/// Remove accesses that have an empty domain.
|
||||
void removeEmptyPartialAccesses();
|
||||
|
||||
/// Mark all reachable instructions and access, and sweep those that are not
|
||||
/// reachable.
|
||||
void markAndSweep(LoopInfo *LI);
|
||||
|
||||
/// Print simplification statistics to @p OS.
|
||||
void printStatistics(llvm::raw_ostream &OS, int Indent = 0) const;
|
||||
|
||||
/// Print the current state of all MemoryAccesses to @p OS.
|
||||
void printAccesses(llvm::raw_ostream &OS, int Indent = 0) const;
|
||||
|
||||
public:
|
||||
explicit SimplifyVisitor(int CallNo = 0) : CallNo(CallNo) {}
|
||||
|
||||
bool visit(Scop &S, LoopInfo *LI);
|
||||
|
||||
void printScop(raw_ostream &OS, Scop &S) const;
|
||||
|
||||
void releaseMemory();
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace polly {
|
||||
|
||||
class MemoryAccess;
|
||||
|
@ -50,10 +146,29 @@ llvm::SmallVector<MemoryAccess *, 32> getAccessesInOrder(ScopStmt &Stmt);
|
|||
///
|
||||
/// @return The Simplify pass.
|
||||
llvm::Pass *createSimplifyPass(int CallNo = 0);
|
||||
|
||||
struct SimplifyPass : public PassInfoMixin<SimplifyPass> {
|
||||
SimplifyPass(int CallNo = 0) : Imp(CallNo) {}
|
||||
|
||||
llvm::PreservedAnalyses run(Scop &S, ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &AR, SPMUpdater &U);
|
||||
|
||||
SimplifyVisitor Imp;
|
||||
};
|
||||
|
||||
struct SimplifyPrinterPass : public PassInfoMixin<SimplifyPrinterPass> {
|
||||
SimplifyPrinterPass(raw_ostream &OS, int CallNo = 0) : OS(OS), Imp(CallNo) {}
|
||||
|
||||
PreservedAnalyses run(Scop &S, ScopAnalysisManager &,
|
||||
ScopStandardAnalysisResults &, SPMUpdater &);
|
||||
|
||||
raw_ostream &OS;
|
||||
SimplifyVisitor Imp;
|
||||
};
|
||||
} // namespace polly
|
||||
|
||||
namespace llvm {
|
||||
void initializeSimplifyPass(llvm::PassRegistry &);
|
||||
void initializeSimplifyLegacyPassPass(llvm::PassRegistry &);
|
||||
} // namespace llvm
|
||||
|
||||
#endif /* POLLY_TRANSFORM_SIMPLIFY_H */
|
||||
|
|
|
@ -28,4 +28,6 @@ SCOP_PASS("polly-import-jscop", JSONImportPass())
|
|||
SCOP_PASS("print<polly-ast>", IslAstPrinterPass(outs()))
|
||||
SCOP_PASS("print<polly-dependences>", DependenceInfoPrinterPass(outs()))
|
||||
SCOP_PASS("polly-codegen", CodeGenerationPass())
|
||||
SCOP_PASS("polly-simplify", SimplifyPass())
|
||||
SCOP_PASS("print<polly-simplify>", SimplifyPrinterPass(outs()))
|
||||
#undef SCOP_PASS
|
||||
|
|
|
@ -284,7 +284,7 @@ void initializePollyPasses(PassRegistry &Registry) {
|
|||
initializeFlattenSchedulePass(Registry);
|
||||
initializeForwardOpTreePass(Registry);
|
||||
initializeDeLICMPass(Registry);
|
||||
initializeSimplifyPass(Registry);
|
||||
initializeSimplifyLegacyPassPass(Registry);
|
||||
initializeDumpModulePass(Registry);
|
||||
initializePruneUnprofitablePass(Registry);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
|
||||
; RUN: opt %loadPolly -polly-stmt-granularity=bb "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck %s -match-full-lines
|
||||
;
|
||||
; Remove a dead load-instruction
|
||||
; (an load whose result is not used anywhere)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
|
||||
; RUN: opt %loadPolly -polly-stmt-granularity=bb "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck %s -match-full-lines
|
||||
;
|
||||
; Remove a dead PHI write/read pair
|
||||
; (accesses that are effectively not used)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
|
||||
; RUN: opt %loadPolly -polly-stmt-granularity=bb "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck %s -match-full-lines
|
||||
;
|
||||
; Remove a dead value write/read pair
|
||||
; (accesses that are effectively not used)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
|
||||
; RUN: opt %loadPolly -polly-stmt-granularity=bb "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck %s -match-full-lines
|
||||
;
|
||||
; Remove a dead instruction
|
||||
; (an instruction whose result is not used anywhere)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
|
||||
; RUN: opt %loadPolly "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck %s -match-full-lines
|
||||
;
|
||||
; Do not remove dependencies of a phi node in a region's exit block.
|
||||
;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
|
||||
; RUN: opt %loadPolly "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck %s -match-full-lines
|
||||
;
|
||||
; Do not remove dependencies of a phi node within a region statement (%phi).
|
||||
;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
|
||||
; RUN: opt %loadPolly "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck %s -match-full-lines
|
||||
;
|
||||
; Do not remove redundant stores in the middle of region statements.
|
||||
; The store in region_true could be removed, but in practice we do try to
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
|
||||
; RUN: opt %loadPolly -polly-stmt-granularity=bb "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck %s -match-full-lines
|
||||
;
|
||||
; Do not remove the scalar value write of %i.trunc in inner.for.
|
||||
; It is used by body.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-simplify -analyze < %s | FileCheck -match-full-lines %s
|
||||
; RUN: opt %loadPolly -polly-stmt-granularity=bb "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck -match-full-lines %s
|
||||
;
|
||||
; Remove a store that is overwritten by another store in the same statement.
|
||||
;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-simplify -analyze < %s | FileCheck -match-full-lines %s
|
||||
; RUN: opt %loadPolly -polly-stmt-granularity=bb "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck -match-full-lines %s
|
||||
;
|
||||
; Remove a store that is overwritten by another store in the same statement.
|
||||
; Check that even multiple stores are removed.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-simplify -analyze < %s | FileCheck -match-full-lines %s
|
||||
; RUN: opt %loadPolly "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck -match-full-lines %s
|
||||
;
|
||||
; Do not remove overwrites when the value is read before.
|
||||
;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-simplify -analyze < %s | FileCheck %s
|
||||
; RUN: opt %loadPolly -disable-output "-passes=scop(print<polly-simplify>)" < %s -aa-pipeline=basic-aa < %s | FileCheck %s
|
||||
;
|
||||
; Simple test for the existence of the Simplify pass.
|
||||
;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
|
||||
; RUN: opt %loadPolly "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck %s -match-full-lines
|
||||
;
|
||||
; The PHINode %cond91.sink.sink.us.sink.6 is in the middle of a region
|
||||
; statement.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
|
||||
; RUN: opt %loadPolly "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck %s -match-full-lines
|
||||
;
|
||||
; Remove redundant store (a store that writes the same value already
|
||||
; at the destination)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
|
||||
; RUN: opt %loadPolly "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck %s -match-full-lines
|
||||
;
|
||||
; A store that has a different index than the load it is storing is
|
||||
; not redundant.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt %loadPolly -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
|
||||
; RUN: opt %loadPolly "-passes=scop(print<polly-simplify>)" -disable-output -aa-pipeline=basic-aa < %s | FileCheck %s -match-full-lines
|
||||
;
|
||||
; Don't remove store where there is another store to the same target
|
||||
; in-between them.
|
||||
|
|
Loading…
Reference in New Issue