mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 22:00:10 +00:00
[Polly] Port DeLICM to the NewPM.
This commit is contained in:
parent
4c64d8ee3a
commit
7903d594ea
@ -17,6 +17,7 @@
|
||||
#ifndef POLLY_DELICM_H
|
||||
#define POLLY_DELICM_H
|
||||
|
||||
#include "polly/ScopPass.h"
|
||||
#include "isl/isl-noexceptions.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -27,7 +28,24 @@ class raw_ostream;
|
||||
|
||||
namespace polly {
|
||||
/// Create a new DeLICM pass instance.
|
||||
llvm::Pass *createDeLICMPass();
|
||||
llvm::Pass *createDeLICMWrapperPass();
|
||||
|
||||
struct DeLICMPass : llvm::PassInfoMixin<DeLICMPass> {
|
||||
DeLICMPass() {}
|
||||
|
||||
llvm::PreservedAnalyses run(Scop &S, ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &SAR, SPMUpdater &U);
|
||||
};
|
||||
|
||||
struct DeLICMPrinterPass : llvm::PassInfoMixin<DeLICMPrinterPass> {
|
||||
DeLICMPrinterPass(raw_ostream &OS) : OS(OS) {}
|
||||
|
||||
PreservedAnalyses run(Scop &S, ScopAnalysisManager &,
|
||||
ScopStandardAnalysisResults &SAR, SPMUpdater &);
|
||||
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
/// Determine whether two lifetimes are conflicting.
|
||||
///
|
||||
@ -39,10 +57,11 @@ bool isConflicting(isl::union_set ExistingOccupied,
|
||||
isl::union_set ProposedUnused, isl::union_map ProposedKnown,
|
||||
isl::union_map ProposedWrites,
|
||||
llvm::raw_ostream *OS = nullptr, unsigned Indent = 0);
|
||||
|
||||
} // namespace polly
|
||||
|
||||
namespace llvm {
|
||||
void initializeDeLICMPass(llvm::PassRegistry &);
|
||||
void initializeDeLICMWrapperPassPass(llvm::PassRegistry &);
|
||||
} // namespace llvm
|
||||
|
||||
#endif /* POLLY_DELICM_H */
|
||||
|
@ -58,7 +58,7 @@ createManagedMemoryRewritePassPass(GPUArch Arch = GPUArch::NVPTX64,
|
||||
llvm::Pass *createIslScheduleOptimizerPass();
|
||||
llvm::Pass *createFlattenSchedulePass();
|
||||
llvm::Pass *createForwardOpTreeWrapperPass();
|
||||
llvm::Pass *createDeLICMPass();
|
||||
llvm::Pass *createDeLICMWrapperPass();
|
||||
llvm::Pass *createMaximalStaticExpansionPass();
|
||||
|
||||
extern char &CodePreparationID;
|
||||
@ -97,7 +97,7 @@ struct PollyForcePassLinking {
|
||||
polly::createMaximalStaticExpansionPass();
|
||||
polly::createFlattenSchedulePass();
|
||||
polly::createForwardOpTreeWrapperPass();
|
||||
polly::createDeLICMPass();
|
||||
polly::createDeLICMWrapperPass();
|
||||
polly::createDumpModulePass("", true);
|
||||
polly::createSimplifyPass();
|
||||
polly::createPruneUnprofitablePass();
|
||||
@ -124,7 +124,7 @@ void initializeMaximalStaticExpanderPass(llvm::PassRegistry &);
|
||||
void initializePollyCanonicalizePass(llvm::PassRegistry &);
|
||||
void initializeFlattenSchedulePass(llvm::PassRegistry &);
|
||||
void initializeForwardOpTreeWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeDeLICMPass(llvm::PassRegistry &);
|
||||
void initializeDeLICMWrapperPassPass(llvm::PassRegistry &);
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -32,4 +32,6 @@ SCOP_PASS("polly-simplify", SimplifyPass())
|
||||
SCOP_PASS("print<polly-simplify>", SimplifyPrinterPass(outs()))
|
||||
SCOP_PASS("polly-optree", ForwardOpTreePass())
|
||||
SCOP_PASS("print<polly-optree>", ForwardOpTreePrinterPass(outs()))
|
||||
SCOP_PASS("polly-delicm", DeLICMPass())
|
||||
SCOP_PASS("print<polly-delicm>", DeLICMPrinterPass(outs()))
|
||||
#undef SCOP_PASS
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "polly/CodeGen/CodegenCleanup.h"
|
||||
#include "polly/CodeGen/IslAst.h"
|
||||
#include "polly/CodePreparation.h"
|
||||
#include "polly/DeLICM.h"
|
||||
#include "polly/DependenceInfo.h"
|
||||
#include "polly/ForwardOpTree.h"
|
||||
#include "polly/JSONExporter.h"
|
||||
@ -262,7 +263,7 @@ void initializePollyPasses(PassRegistry &Registry) {
|
||||
initializeCodegenCleanupPass(Registry);
|
||||
initializeFlattenSchedulePass(Registry);
|
||||
initializeForwardOpTreeWrapperPassPass(Registry);
|
||||
initializeDeLICMPass(Registry);
|
||||
initializeDeLICMWrapperPassPass(Registry);
|
||||
initializeSimplifyLegacyPassPass(Registry);
|
||||
initializeDumpModulePass(Registry);
|
||||
initializePruneUnprofitablePass(Registry);
|
||||
@ -323,7 +324,7 @@ void registerPollyPasses(llvm::legacy::PassManagerBase &PM) {
|
||||
if (EnableForwardOpTree)
|
||||
PM.add(polly::createForwardOpTreeWrapperPass());
|
||||
if (EnableDeLICM)
|
||||
PM.add(polly::createDeLICMPass());
|
||||
PM.add(polly::createDeLICMWrapperPass());
|
||||
if (EnableSimplify)
|
||||
PM.add(polly::createSimplifyPass(1));
|
||||
|
||||
@ -470,7 +471,8 @@ static void buildDefaultPollyPipeline(FunctionPassManager &PM,
|
||||
assert(!EnablePolyhedralInfo && "This option is not implemented");
|
||||
if (EnableForwardOpTree)
|
||||
SPM.addPass(ForwardOpTreePass());
|
||||
assert(!EnableDeLICM && "This option is not implemented");
|
||||
if (EnableDeLICM)
|
||||
SPM.addPass(DeLICMPass());
|
||||
assert(!EnableSimplify && "This option is not implemented");
|
||||
if (ImportJScop)
|
||||
SPM.addPass(JSONImportPass());
|
||||
|
@ -1180,9 +1180,6 @@ private:
|
||||
OS.indent(Indent) << "}\n";
|
||||
}
|
||||
|
||||
/// Return whether at least one transformation been applied.
|
||||
bool isModified() const { return NumberOfTargetsMapped > 0; }
|
||||
|
||||
public:
|
||||
DeLICMImpl(Scop *S, LoopInfo *LI) : ZoneAlgorithm("polly-delicm", S, LI) {}
|
||||
|
||||
@ -1352,35 +1349,81 @@ public:
|
||||
}
|
||||
printAccesses(OS, Indent);
|
||||
}
|
||||
|
||||
/// Return whether at least one transformation been applied.
|
||||
bool isModified() const { return NumberOfTargetsMapped > 0; }
|
||||
};
|
||||
|
||||
class DeLICM : public ScopPass {
|
||||
static std::unique_ptr<DeLICMImpl> collapseToUnused(Scop &S, LoopInfo &LI) {
|
||||
std::unique_ptr<DeLICMImpl> Impl = std::make_unique<DeLICMImpl>(&S, &LI);
|
||||
|
||||
if (!Impl->computeZone()) {
|
||||
LLVM_DEBUG(dbgs() << "Abort because cannot reliably compute lifetimes\n");
|
||||
return Impl;
|
||||
}
|
||||
|
||||
LLVM_DEBUG(dbgs() << "Collapsing scalars to unused array elements...\n");
|
||||
Impl->greedyCollapse();
|
||||
|
||||
LLVM_DEBUG(dbgs() << "\nFinal Scop:\n");
|
||||
LLVM_DEBUG(dbgs() << S);
|
||||
|
||||
return Impl;
|
||||
}
|
||||
|
||||
static std::unique_ptr<DeLICMImpl> runDeLICM(Scop &S, LoopInfo &LI) {
|
||||
std::unique_ptr<DeLICMImpl> Impl = collapseToUnused(S, LI);
|
||||
|
||||
Scop::ScopStatistics ScopStats = S.getStatistics();
|
||||
NumValueWrites += ScopStats.NumValueWrites;
|
||||
NumValueWritesInLoops += ScopStats.NumValueWritesInLoops;
|
||||
NumPHIWrites += ScopStats.NumPHIWrites;
|
||||
NumPHIWritesInLoops += ScopStats.NumPHIWritesInLoops;
|
||||
NumSingletonWrites += ScopStats.NumSingletonWrites;
|
||||
NumSingletonWritesInLoops += ScopStats.NumSingletonWritesInLoops;
|
||||
|
||||
return Impl;
|
||||
}
|
||||
|
||||
static PreservedAnalyses runDeLICMUsingNPM(Scop &S, ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &SAR,
|
||||
SPMUpdater &U, raw_ostream *OS) {
|
||||
LoopInfo &LI = SAR.LI;
|
||||
std::unique_ptr<DeLICMImpl> Impl = runDeLICM(S, LI);
|
||||
|
||||
if (OS) {
|
||||
*OS << "Printing analysis 'Polly - DeLICM/DePRE' for region: '"
|
||||
<< S.getName() << "' in function '" << S.getFunction().getName()
|
||||
<< "':\n";
|
||||
if (Impl) {
|
||||
assert(Impl->getScop() == &S);
|
||||
|
||||
*OS << "DeLICM result:\n";
|
||||
Impl->print(*OS);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Impl->isModified())
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
PreservedAnalyses PA;
|
||||
PA.preserveSet<AllAnalysesOn<Module>>();
|
||||
PA.preserveSet<AllAnalysesOn<Function>>();
|
||||
PA.preserveSet<AllAnalysesOn<Loop>>();
|
||||
return PA;
|
||||
}
|
||||
|
||||
class DeLICMWrapperPass : public ScopPass {
|
||||
private:
|
||||
DeLICM(const DeLICM &) = delete;
|
||||
const DeLICM &operator=(const DeLICM &) = delete;
|
||||
DeLICMWrapperPass(const DeLICMWrapperPass &) = delete;
|
||||
const DeLICMWrapperPass &operator=(const DeLICMWrapperPass &) = delete;
|
||||
|
||||
/// The pass implementation, also holding per-scop data.
|
||||
std::unique_ptr<DeLICMImpl> Impl;
|
||||
|
||||
void collapseToUnused(Scop &S) {
|
||||
auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
Impl = std::make_unique<DeLICMImpl>(&S, &LI);
|
||||
|
||||
if (!Impl->computeZone()) {
|
||||
LLVM_DEBUG(dbgs() << "Abort because cannot reliably compute lifetimes\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LLVM_DEBUG(dbgs() << "Collapsing scalars to unused array elements...\n");
|
||||
Impl->greedyCollapse();
|
||||
|
||||
LLVM_DEBUG(dbgs() << "\nFinal Scop:\n");
|
||||
LLVM_DEBUG(dbgs() << S);
|
||||
}
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
explicit DeLICM() : ScopPass(ID) {}
|
||||
explicit DeLICMWrapperPass() : ScopPass(ID) {}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequiredTransitive<ScopInfoRegionPass>();
|
||||
@ -1392,17 +1435,10 @@ public:
|
||||
// Free resources for previous scop's computation, if not yet done.
|
||||
releaseMemory();
|
||||
|
||||
collapseToUnused(S);
|
||||
auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
Impl = runDeLICM(S, LI);
|
||||
|
||||
auto ScopStats = S.getStatistics();
|
||||
NumValueWrites += ScopStats.NumValueWrites;
|
||||
NumValueWritesInLoops += ScopStats.NumValueWritesInLoops;
|
||||
NumPHIWrites += ScopStats.NumPHIWrites;
|
||||
NumPHIWritesInLoops += ScopStats.NumPHIWritesInLoops;
|
||||
NumSingletonWrites += ScopStats.NumSingletonWrites;
|
||||
NumSingletonWritesInLoops += ScopStats.NumSingletonWritesInLoops;
|
||||
|
||||
return false;
|
||||
return Impl->isModified();
|
||||
}
|
||||
|
||||
virtual void printScop(raw_ostream &OS, Scop &S) const override {
|
||||
@ -1417,17 +1453,30 @@ public:
|
||||
virtual void releaseMemory() override { Impl.reset(); }
|
||||
};
|
||||
|
||||
char DeLICM::ID;
|
||||
char DeLICMWrapperPass::ID;
|
||||
} // anonymous namespace
|
||||
|
||||
Pass *polly::createDeLICMPass() { return new DeLICM(); }
|
||||
Pass *polly::createDeLICMWrapperPass() { return new DeLICMWrapperPass(); }
|
||||
|
||||
INITIALIZE_PASS_BEGIN(DeLICM, "polly-delicm", "Polly - DeLICM/DePRE", false,
|
||||
false)
|
||||
INITIALIZE_PASS_BEGIN(DeLICMWrapperPass, "polly-delicm", "Polly - DeLICM/DePRE",
|
||||
false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(DeLICM, "polly-delicm", "Polly - DeLICM/DePRE", false,
|
||||
false)
|
||||
INITIALIZE_PASS_END(DeLICMWrapperPass, "polly-delicm", "Polly - DeLICM/DePRE",
|
||||
false, false)
|
||||
|
||||
llvm::PreservedAnalyses DeLICMPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &SAR,
|
||||
SPMUpdater &U) {
|
||||
return runDeLICMUsingNPM(S, SAM, SAR, U, nullptr);
|
||||
}
|
||||
|
||||
llvm::PreservedAnalyses DeLICMPrinterPass::run(Scop &S,
|
||||
ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &SAR,
|
||||
SPMUpdater &U) {
|
||||
return runDeLICMUsingNPM(S, SAM, SAR, U, &OS);
|
||||
}
|
||||
|
||||
bool polly::isConflicting(
|
||||
isl::union_set ExistingOccupied, isl::union_set ExistingUnused,
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-delicm -analyze < %s | FileCheck -match-full-lines %s
|
||||
; RUN: opt %loadPolly -polly-stmt-granularity=bb "-passes=scop(print<polly-delicm>)" -disable-output < %s | FileCheck -match-full-lines %s
|
||||
;
|
||||
; Check that PHI mapping works even in presence of a memset whose'
|
||||
; zero value is used.
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: opt %loadPolly -polly-delicm -analyze < %s | FileCheck %s
|
||||
; RUN: opt %loadPolly "-passes=scop(print<polly-delicm>)" -disable-output < %s | FileCheck %s
|
||||
;
|
||||
; Simple test for the existence of the DeLICM pass.
|
||||
;
|
||||
|
Loading…
Reference in New Issue
Block a user