Skip to content

[Polly] Introduce PhaseManager and remove LPM support #125442

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 13 commits into
base: users/meinersbur/polly_CodePreparation
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions polly/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ In Polly |version| the following important changes have been incorporated.

* ScopInliner has been updated for the New Pass Manager.

* Polly now is a monolithic pass split into phases.

* Polly's support for the legacy pass manager has been removed.

8 changes: 0 additions & 8 deletions polly/include/polly/Canonicalization.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@

#include "llvm/Passes/PassBuilder.h"

namespace llvm {
namespace legacy {
class PassManagerBase;
}
} // namespace llvm

namespace polly {

/// Schedule a set of canonicalization passes to prepare for Polly.
Expand All @@ -26,8 +20,6 @@ namespace polly {
/// into a canonical form that simplifies the analysis and optimization passes
/// of Polly. The set of optimization passes scheduled here is probably not yet
/// optimal. TODO: Optimize the set of canonicalization passes.
void registerCanonicalicationPasses(llvm::legacy::PassManagerBase &PM);

llvm::FunctionPassManager
buildCanonicalicationPassesForNPM(llvm::ModulePassManager &MPM,
llvm::OptimizationLevel Level);
Expand Down
3 changes: 3 additions & 0 deletions polly/include/polly/CodeGen/CodeGeneration.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "llvm/IR/PassManager.h"

namespace polly {
class IslAstInfo;

enum VectorizerChoice {
VECTORIZER_NONE,
Expand All @@ -33,6 +34,8 @@ struct CodeGenerationPass final : PassInfoMixin<CodeGenerationPass> {
};

extern bool PerfMonitoring;

bool runCodeGeneration(Scop &S, llvm::RegionInfo &RI, IslAstInfo &AI);
} // namespace polly

#endif // POLLY_CODEGENERATION_H
36 changes: 4 additions & 32 deletions polly/include/polly/CodeGen/IslAst.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifndef POLLY_ISLAST_H
#define POLLY_ISLAST_H

#include "polly/DependenceInfo.h"
#include "polly/ScopPass.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/PassManager.h"
Expand Down Expand Up @@ -172,33 +173,6 @@ struct IslAstAnalysis : AnalysisInfoMixin<IslAstAnalysis> {
ScopStandardAnalysisResults &SAR);
};

class IslAstInfoWrapperPass final : public ScopPass {
std::unique_ptr<IslAstInfo> Ast;

public:
static char ID;

IslAstInfoWrapperPass() : ScopPass(ID) {}

IslAstInfo &getAI() { return *Ast; }
const IslAstInfo &getAI() const { return *Ast; }

/// Build the AST for the given SCoP @p S.
bool runOnScop(Scop &S) override;

/// Register all analyses and transformation required.
void getAnalysisUsage(AnalysisUsage &AU) const override;

/// Release the internal memory.
void releaseMemory() override;

/// Print a source code representation of the program.
void printScop(raw_ostream &OS, Scop &S) const override;
};

llvm::Pass *createIslAstInfoWrapperPassPass();
llvm::Pass *createIslAstInfoPrinterLegacyPass(llvm::raw_ostream &OS);

struct IslAstPrinterPass final : PassInfoMixin<IslAstPrinterPass> {
IslAstPrinterPass(raw_ostream &OS) : OS(OS) {}

Expand All @@ -207,11 +181,9 @@ struct IslAstPrinterPass final : PassInfoMixin<IslAstPrinterPass> {

raw_ostream &OS;
};
} // namespace polly

namespace llvm {
void initializeIslAstInfoWrapperPassPass(llvm::PassRegistry &);
void initializeIslAstInfoPrinterLegacyPassPass(llvm::PassRegistry &);
} // namespace llvm
std::unique_ptr<IslAstInfo> runIslAstGen(Scop &S,
DependenceAnalysis::Result &DA);
} // namespace polly

#endif // POLLY_ISLAST_H
9 changes: 9 additions & 0 deletions polly/include/polly/CodePreparation.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,20 @@

#include "llvm/IR/PassManager.h"

namespace llvm {
class DominatorTree;
class LoopInfo;
class RegionInfo;
} // namespace llvm

namespace polly {
struct CodePreparationPass final : llvm::PassInfoMixin<CodePreparationPass> {
llvm::PreservedAnalyses run(llvm::Function &F,
llvm::FunctionAnalysisManager &FAM);
};

bool runCodePreparation(llvm::Function &F, llvm::DominatorTree *DT,
llvm::LoopInfo *LI, llvm::RegionInfo *RI);
} // namespace polly

#endif /* POLLY_CODEPREPARATION_H */
11 changes: 1 addition & 10 deletions polly/include/polly/DeLICM.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,10 @@
#include "isl/isl-noexceptions.h"

namespace llvm {
class PassRegistry;
class Pass;
class raw_ostream;
} // namespace llvm

namespace polly {
/// Create a new DeLICM pass instance.
llvm::Pass *createDeLICMWrapperPass();
llvm::Pass *createDeLICMPrinterLegacyPass(llvm::raw_ostream &OS);

struct DeLICMPass final : llvm::PassInfoMixin<DeLICMPass> {
DeLICMPass() {}
Expand Down Expand Up @@ -59,11 +54,7 @@ bool isConflicting(isl::union_set ExistingOccupied,
isl::union_map ProposedWrites,
llvm::raw_ostream *OS = nullptr, unsigned Indent = 0);

bool runDeLICM(Scop &S);
} // namespace polly

namespace llvm {
void initializeDeLICMWrapperPassPass(llvm::PassRegistry &);
void initializeDeLICMPrinterLegacyPassPass(llvm::PassRegistry &);
} // namespace llvm

#endif /* POLLY_DELICM_H */
13 changes: 2 additions & 11 deletions polly/include/polly/DeadCodeElimination.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,10 @@
#ifndef POLLY_DEADCODEELIMINATION_H
#define POLLY_DEADCODEELIMINATION_H

#include "polly/DependenceInfo.h"
#include "polly/ScopPass.h"

namespace llvm {
class PassRegistry;
class Pass;
class raw_ostream;
} // namespace llvm

namespace polly {
llvm::Pass *createDeadCodeElimWrapperPass();

struct DeadCodeElimPass final : llvm::PassInfoMixin<DeadCodeElimPass> {
DeadCodeElimPass() {}
Expand All @@ -31,10 +25,7 @@ struct DeadCodeElimPass final : llvm::PassInfoMixin<DeadCodeElimPass> {
ScopStandardAnalysisResults &SAR, SPMUpdater &U);
};

bool runDeadCodeElim(Scop &S, DependenceAnalysis::Result &DA);
} // namespace polly

namespace llvm {
void initializeDeadCodeElimWrapperPassPass(llvm::PassRegistry &);
} // namespace llvm

#endif /* POLLY_DEADCODEELIMINATION_H */
106 changes: 3 additions & 103 deletions polly/include/polly/DependenceInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ class Dependences final {
friend struct DependenceAnalysis;
friend struct DependenceInfoPrinterPass;
friend class DependenceInfo;
friend class DependenceInfoWrapperPass;

/// Destructor that will free internal objects.
~Dependences() { releaseMemory(); }
Expand Down Expand Up @@ -192,6 +191,8 @@ class Dependences final {
const AnalysisLevel Level;
};

extern Dependences::AnalysisLevel OptAnalysisLevel;

struct DependenceAnalysis final : public AnalysisInfoMixin<DependenceAnalysis> {
static AnalysisKey Key;
struct Result {
Expand Down Expand Up @@ -232,108 +233,7 @@ struct DependenceInfoPrinterPass final
raw_ostream &OS;
};

class DependenceInfo final : public ScopPass {
public:
static char ID;

/// Construct a new DependenceInfo pass.
DependenceInfo() : ScopPass(ID) {}

/// Return the dependence information for the current SCoP.
///
/// @param Level The granularity of dependence analysis result.
///
/// @return The dependence analysis result
///
const Dependences &getDependences(Dependences::AnalysisLevel Level);

/// Recompute dependences from schedule and memory accesses.
const Dependences &recomputeDependences(Dependences::AnalysisLevel Level);

/// Invalidate the dependence information and recompute it when needed again.
/// May be required when the underlying Scop was changed in a way that would
/// add new dependencies (e.g. between new statement instances insierted into
/// the SCoP) or intentionally breaks existing ones. It is not required when
/// updating the schedule that conforms the existing dependencies.
void abandonDependences();

/// Compute the dependence information for the SCoP @p S.
bool runOnScop(Scop &S) override;

/// Print the dependences for the given SCoP to @p OS.
void printScop(raw_ostream &OS, Scop &) const override;

/// Release the internal memory.
void releaseMemory() override {
for (auto &d : D)
d.reset();
}

/// Register all analyses and transformation required.
void getAnalysisUsage(AnalysisUsage &AU) const override;

private:
Scop *S;

/// Dependences struct for the current SCoP.
std::unique_ptr<Dependences> D[Dependences::NumAnalysisLevels];
};

llvm::Pass *createDependenceInfoPass();
llvm::Pass *createDependenceInfoPrinterLegacyPass(llvm::raw_ostream &OS);

/// Construct a new DependenceInfoWrapper pass.
class DependenceInfoWrapperPass final : public FunctionPass {
public:
static char ID;

/// Construct a new DependenceInfoWrapper pass.
DependenceInfoWrapperPass() : FunctionPass(ID) {}

/// Return the dependence information for the given SCoP.
///
/// @param S SCoP object.
/// @param Level The granularity of dependence analysis result.
///
/// @return The dependence analysis result
///
const Dependences &getDependences(Scop *S, Dependences::AnalysisLevel Level);

/// Recompute dependences from schedule and memory accesses.
const Dependences &recomputeDependences(Scop *S,
Dependences::AnalysisLevel Level);

/// Compute the dependence information on-the-fly for the function.
bool runOnFunction(Function &F) override;

/// Print the dependences for the current function to @p OS.
void print(raw_ostream &OS, const Module *M = nullptr) const override;

/// Release the internal memory.
void releaseMemory() override { ScopToDepsMap.clear(); }

/// Register all analyses and transformation required.
void getAnalysisUsage(AnalysisUsage &AU) const override;

private:
using ScopToDepsMapTy = DenseMap<Scop *, std::unique_ptr<Dependences>>;

/// Scop to Dependence map for the current function.
ScopToDepsMapTy ScopToDepsMap;
};

llvm::Pass *createDependenceInfoWrapperPassPass();
llvm::Pass *
createDependenceInfoPrinterLegacyFunctionPass(llvm::raw_ostream &OS);

DependenceAnalysis::Result runDependenceAnalysis(Scop &S);
} // namespace polly

namespace llvm {
void initializeDependenceInfoPass(llvm::PassRegistry &);
void initializeDependenceInfoPrinterLegacyPassPass(llvm::PassRegistry &);
void initializeDependenceInfoWrapperPassPass(llvm::PassRegistry &);
void initializeDependenceInfoPrinterLegacyFunctionPassPass(
llvm::PassRegistry &);
} // namespace llvm

#endif
16 changes: 3 additions & 13 deletions polly/include/polly/FlattenSchedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,10 @@
#ifndef POLLY_FLATTENSCHEDULE_H
#define POLLY_FLATTENSCHEDULE_H

namespace llvm {
class PassRegistry;
class Pass;
class raw_ostream;
} // namespace llvm

namespace polly {
llvm::Pass *createFlattenSchedulePass();
llvm::Pass *createFlattenSchedulePrinterLegacyPass(llvm::raw_ostream &OS);
} // namespace polly
class Scop;

namespace llvm {
void initializeFlattenSchedulePass(llvm::PassRegistry &);
void initializeFlattenSchedulePrinterLegacyPassPass(llvm::PassRegistry &);
} // namespace llvm
void runFlattenSchedulePass(Scop &S);
} // namespace polly

#endif /* POLLY_FLATTENSCHEDULE_H */
20 changes: 9 additions & 11 deletions polly/include/polly/ForwardOpTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,7 @@

#include "polly/ScopPass.h"

namespace llvm {
class PassRegistry;
} // namespace llvm

namespace polly {
llvm::Pass *createForwardOpTreeWrapperPass();
llvm::Pass *createForwardOpTreePrinterLegacyPass(llvm::raw_ostream &OS);

struct ForwardOpTreePass final : llvm::PassInfoMixin<ForwardOpTreePass> {
ForwardOpTreePass() {}
Expand All @@ -41,11 +35,15 @@ struct ForwardOpTreePrinterPass final
llvm::raw_ostream &OS;
};

/// Pass that redirects scalar reads to array elements that are known to contain
/// the same value.
///
/// This reduces the number of scalar accesses and therefore potentially
/// increases the freedom of the scheduler. In the ideal case, all reads of a
/// scalar definition are redirected (We currently do not care about removing
/// the write in this case). This is also useful for the main DeLICM pass as
/// there are less scalars to be mapped.
bool runForwardOpTree(Scop &S);
} // namespace polly

namespace llvm {
void initializeForwardOpTreeWrapperPassPass(PassRegistry &);
void initializeForwardOpTreePrinterLegacyPassPass(PassRegistry &);
} // namespace llvm

#endif // POLLY_FORWARDOPTREE_H
Loading