mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 02:38:07 +08:00
Reapply of a22d1c2225. Using this PR for
pre-merge CI.
Instead of relying on any pass manager to schedule Polly's passes, add
Polly's own pipeline manager which is seen as a monolithic pass in
LLVM's pass manager. Polly's former passes are now phases of the new
PhaseManager component.
Relying on LLVM's pass manager (the legacy as well as the New Pass
Manager) to manage Polly's phases never was a good fit that the
PhaseManager resolves:
* Polly passes were modifying analysis results, in particular RegionInfo
and ScopInfo. This means that there was not just one unique and
"definite" analysis result, the actual result depended on which analyses
ran prior, and the pass manager was not allowed to throw away cached
analyses or prior SCoP optimizations would have been forgotten. The LLVM
pass manger's persistance of analysis results is not contractual but
designed for caching.
* Polly depends on a particular execution order of passes and regions
(e.g. regression tests, invalidation of consecutive SCoPs). LLVM's pass
manager does not guarantee any excecution order.
* Polly does not completely preserve DominatorTree, RegionInfo,
LoopInfo, or ScalarEvolution, but only as-needed for Polly's own uses.
Because the ScopDetection object stores references to those analyses, it
still had to lie to the pass manager that they would be preserved, or
the pass manager would have released and recomputed the invalidated
analysis objects that ScopDetection/ScopInfo was still referencing. To
ensure that no non-Polly pass would see these not-completely-preserved
analyses, all analyses still had to be thrown away after the
ScopPassManager, respectively with a BarrierNoopPass in case of the LPM.
* The NPM's PassInstrumentation wraps the IR unit into an `llvm::Any`
object, but implementations such as PrintIRInstrumentation call
llvm_unreachable on encountering an unknown IR unit, such as SCoPs, with
no extension points to add support. Hence LLVM crashes when dumping IR
between SCoP passes (such as `-print-before-changed` with Polly being
active).
The new PhaseManager uses some command line options that previously
belonged to Polly's legacy passes, such as `-polly-print-detect` (so the
option will continue to work). Hence the LPM support is incompatible
with the new approach and support for it is removed.
This commit is contained in:
@@ -413,7 +413,7 @@ bool LoopVersioningLICM::legalLoopInstructions() {
|
||||
LLVM_DEBUG(dbgs() << " Found a read-only loop!\n");
|
||||
return false;
|
||||
}
|
||||
// Profitablity check:
|
||||
// Profitability check:
|
||||
// Check invariant threshold, should be in limit.
|
||||
if (InvariantCounter * 100 < InvariantThreshold * LoadAndStoreCounter) {
|
||||
LLVM_DEBUG(
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -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);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
namespace polly {
|
||||
class IslAstInfo;
|
||||
|
||||
enum VectorizerChoice {
|
||||
VECTORIZER_NONE,
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
@@ -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) {}
|
||||
|
||||
@@ -207,11 +181,9 @@ struct IslAstPrinterPass final : PassInfoMixin<IslAstPrinterPass> {
|
||||
|
||||
raw_ostream &OS;
|
||||
};
|
||||
|
||||
std::unique_ptr<IslAstInfo> runIslAstGen(Scop &S,
|
||||
DependenceAnalysis::Result &DA);
|
||||
} // namespace polly
|
||||
|
||||
namespace llvm {
|
||||
void initializeIslAstInfoWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeIslAstInfoPrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
} // namespace llvm
|
||||
|
||||
#endif // POLLY_ISLAST_H
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
|
||||
#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,
|
||||
|
||||
@@ -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() {}
|
||||
@@ -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,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() {}
|
||||
@@ -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 */
|
||||
|
||||
@@ -145,7 +145,6 @@ public:
|
||||
friend struct DependenceAnalysis;
|
||||
friend struct DependenceInfoPrinterPass;
|
||||
friend class DependenceInfo;
|
||||
friend class DependenceInfoWrapperPass;
|
||||
|
||||
/// Destructor that will free internal objects.
|
||||
~Dependences() { releaseMemory(); }
|
||||
@@ -192,6 +191,8 @@ private:
|
||||
const AnalysisLevel Level;
|
||||
};
|
||||
|
||||
extern Dependences::AnalysisLevel OptAnalysisLevel;
|
||||
|
||||
struct DependenceAnalysis final : public AnalysisInfoMixin<DependenceAnalysis> {
|
||||
static AnalysisKey Key;
|
||||
struct Result {
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
class Scop;
|
||||
|
||||
void runFlattenSchedulePass(Scop &S);
|
||||
} // namespace polly
|
||||
|
||||
namespace llvm {
|
||||
void initializeFlattenSchedulePass(llvm::PassRegistry &);
|
||||
void initializeFlattenSchedulePrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
} // namespace llvm
|
||||
|
||||
#endif /* POLLY_FLATTENSCHEDULE_H */
|
||||
|
||||
@@ -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() {}
|
||||
@@ -41,11 +35,15 @@ private:
|
||||
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
|
||||
|
||||
@@ -9,13 +9,11 @@
|
||||
#ifndef POLLY_JSONEXPORTER_H
|
||||
#define POLLY_JSONEXPORTER_H
|
||||
|
||||
#include "polly/DependenceInfo.h"
|
||||
#include "polly/ScopPass.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
namespace polly {
|
||||
llvm::Pass *createJSONExporterPass();
|
||||
llvm::Pass *createJSONImporterPass();
|
||||
llvm::Pass *createJSONImporterPrinterLegacyPass(llvm::raw_ostream &OS);
|
||||
|
||||
/// This pass exports a scop to a jscop file. The filename is generated from the
|
||||
/// concatenation of the function and scop name.
|
||||
@@ -30,12 +28,9 @@ struct JSONImportPass final : llvm::PassInfoMixin<JSONExportPass> {
|
||||
llvm::PreservedAnalyses run(Scop &, ScopAnalysisManager &,
|
||||
ScopStandardAnalysisResults &, SPMUpdater &);
|
||||
};
|
||||
|
||||
void runImportJSON(Scop &S, DependenceAnalysis::Result &DA);
|
||||
void runExportJSON(Scop &S);
|
||||
} // namespace polly
|
||||
|
||||
namespace llvm {
|
||||
void initializeJSONExporterPass(llvm::PassRegistry &);
|
||||
void initializeJSONImporterPass(llvm::PassRegistry &);
|
||||
void initializeJSONImporterPrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
} // namespace llvm
|
||||
|
||||
#endif /* POLLY_JSONEXPORTER_H */
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
//===- polly/LinkAllPasses.h ----------- Reference All Passes ---*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This header file pulls in all transformation and analysis passes for tools
|
||||
// like opt and bugpoint that need this functionality.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef POLLY_LINKALLPASSES_H
|
||||
#define POLLY_LINKALLPASSES_H
|
||||
|
||||
#include "polly/Config/config.h"
|
||||
#include "polly/Support/DumpFunctionPass.h"
|
||||
#include "polly/Support/DumpModulePass.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/AlwaysTrue.h"
|
||||
|
||||
namespace llvm {
|
||||
class Pass;
|
||||
class PassRegistry;
|
||||
} // namespace llvm
|
||||
|
||||
namespace polly {
|
||||
llvm::Pass *createCodePreparationPass();
|
||||
llvm::Pass *createScopInlinerPass();
|
||||
llvm::Pass *createDeadCodeElimWrapperPass();
|
||||
llvm::Pass *createDependenceInfoPass();
|
||||
llvm::Pass *createDependenceInfoPrinterLegacyPass(llvm::raw_ostream &OS);
|
||||
llvm::Pass *createDependenceInfoWrapperPassPass();
|
||||
llvm::Pass *
|
||||
createDependenceInfoPrinterLegacyFunctionPass(llvm::raw_ostream &OS);
|
||||
llvm::Pass *createDOTOnlyPrinterWrapperPass();
|
||||
llvm::Pass *createDOTOnlyViewerWrapperPass();
|
||||
llvm::Pass *createDOTPrinterWrapperPass();
|
||||
llvm::Pass *createDOTViewerWrapperPass();
|
||||
llvm::Pass *createJSONExporterPass();
|
||||
llvm::Pass *createJSONImporterPass();
|
||||
llvm::Pass *createJSONImporterPrinterLegacyPass(llvm::raw_ostream &OS);
|
||||
llvm::Pass *createPollyCanonicalizePass();
|
||||
llvm::Pass *createScopDetectionWrapperPassPass();
|
||||
llvm::Pass *createScopDetectionPrinterLegacyPass(llvm::raw_ostream &OS);
|
||||
llvm::Pass *createScopInfoRegionPassPass();
|
||||
llvm::Pass *createScopInfoPrinterLegacyRegionPass(llvm::raw_ostream &OS);
|
||||
llvm::Pass *createScopInfoWrapperPassPass();
|
||||
llvm::Pass *createScopInfoPrinterLegacyFunctionPass(llvm::raw_ostream &OS);
|
||||
llvm::Pass *createIslAstInfoWrapperPassPass();
|
||||
llvm::Pass *createIslAstInfoPrinterLegacyPass(llvm::raw_ostream &OS);
|
||||
llvm::Pass *createCodeGenerationPass();
|
||||
llvm::Pass *createIslScheduleOptimizerWrapperPass();
|
||||
llvm::Pass *createIslScheduleOptimizerPrinterLegacyPass(llvm::raw_ostream &OS);
|
||||
llvm::Pass *createFlattenSchedulePass();
|
||||
llvm::Pass *createFlattenSchedulePrinterLegacyPass(llvm::raw_ostream &OS);
|
||||
llvm::Pass *createForwardOpTreeWrapperPass();
|
||||
llvm::Pass *createForwardOpTreePrinterLegacyPass(llvm::raw_ostream &OS);
|
||||
llvm::Pass *createDeLICMWrapperPass();
|
||||
llvm::Pass *createDeLICMPrinterLegacyPass(llvm::raw_ostream &OS);
|
||||
llvm::Pass *createMaximalStaticExpansionPass();
|
||||
llvm::Pass *createSimplifyWrapperPass(int);
|
||||
llvm::Pass *createSimplifyPrinterLegacyPass(llvm::raw_ostream &OS);
|
||||
llvm::Pass *createPruneUnprofitableWrapperPass();
|
||||
|
||||
extern char &CodePreparationID;
|
||||
} // namespace polly
|
||||
|
||||
namespace {
|
||||
struct PollyForcePassLinking {
|
||||
PollyForcePassLinking() {
|
||||
// We must reference the passes in such a way that compilers will not delete
|
||||
// it all as dead code, even with whole program optimization, yet is
|
||||
// effectively a NO-OP.
|
||||
if (llvm::getNonFoldableAlwaysTrue())
|
||||
return;
|
||||
|
||||
polly::createCodePreparationPass();
|
||||
polly::createDeadCodeElimWrapperPass();
|
||||
polly::createDependenceInfoPass();
|
||||
polly::createDependenceInfoPrinterLegacyPass(llvm::outs());
|
||||
polly::createDependenceInfoWrapperPassPass();
|
||||
polly::createDependenceInfoPrinterLegacyFunctionPass(llvm::outs());
|
||||
polly::createDOTOnlyPrinterWrapperPass();
|
||||
polly::createDOTOnlyViewerWrapperPass();
|
||||
polly::createDOTPrinterWrapperPass();
|
||||
polly::createDOTViewerWrapperPass();
|
||||
polly::createJSONExporterPass();
|
||||
polly::createJSONImporterPass();
|
||||
polly::createJSONImporterPrinterLegacyPass(llvm::outs());
|
||||
polly::createScopDetectionWrapperPassPass();
|
||||
polly::createScopDetectionPrinterLegacyPass(llvm::outs());
|
||||
polly::createScopInfoRegionPassPass();
|
||||
polly::createScopInfoPrinterLegacyRegionPass(llvm::outs());
|
||||
polly::createScopInfoWrapperPassPass();
|
||||
polly::createScopInfoPrinterLegacyFunctionPass(llvm::outs());
|
||||
polly::createPollyCanonicalizePass();
|
||||
polly::createIslAstInfoWrapperPassPass();
|
||||
polly::createIslAstInfoPrinterLegacyPass(llvm::outs());
|
||||
polly::createCodeGenerationPass();
|
||||
polly::createIslScheduleOptimizerWrapperPass();
|
||||
polly::createIslScheduleOptimizerPrinterLegacyPass(llvm::outs());
|
||||
polly::createMaximalStaticExpansionPass();
|
||||
polly::createFlattenSchedulePass();
|
||||
polly::createFlattenSchedulePrinterLegacyPass(llvm::errs());
|
||||
polly::createForwardOpTreeWrapperPass();
|
||||
polly::createForwardOpTreePrinterLegacyPass(llvm::errs());
|
||||
polly::createDeLICMWrapperPass();
|
||||
polly::createDeLICMPrinterLegacyPass(llvm::outs());
|
||||
polly::createDumpModuleWrapperPass("", true);
|
||||
polly::createDumpFunctionWrapperPass("");
|
||||
polly::createSimplifyWrapperPass(0);
|
||||
polly::createSimplifyPrinterLegacyPass(llvm::outs());
|
||||
polly::createPruneUnprofitableWrapperPass();
|
||||
}
|
||||
} PollyForcePassLinking; // Force link by creating a global definition.
|
||||
} // namespace
|
||||
|
||||
namespace llvm {
|
||||
void initializeCodePreparationPass(llvm::PassRegistry &);
|
||||
void initializeScopInlinerWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeScopDetectionWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeScopDetectionPrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
void initializeScopInfoRegionPassPass(PassRegistry &);
|
||||
void initializeScopInfoPrinterLegacyRegionPassPass(llvm::PassRegistry &);
|
||||
void initializeScopInfoWrapperPassPass(PassRegistry &);
|
||||
void initializeScopInfoPrinterLegacyFunctionPassPass(PassRegistry &);
|
||||
void initializeDeadCodeElimWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeJSONExporterPass(llvm::PassRegistry &);
|
||||
void initializeJSONImporterPass(llvm::PassRegistry &);
|
||||
void initializeJSONImporterPrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
void initializeDependenceInfoPass(llvm::PassRegistry &);
|
||||
void initializeDependenceInfoPrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
void initializeDependenceInfoWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeDependenceInfoPrinterLegacyFunctionPassPass(
|
||||
llvm::PassRegistry &);
|
||||
void initializeIslAstInfoWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeIslAstInfoPrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
void initializeCodeGenerationPass(llvm::PassRegistry &);
|
||||
void initializeIslScheduleOptimizerWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeIslScheduleOptimizerPrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
void initializeMaximalStaticExpanderWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializePollyCanonicalizePass(llvm::PassRegistry &);
|
||||
void initializeFlattenSchedulePass(llvm::PassRegistry &);
|
||||
void initializeFlattenSchedulePrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
void initializeForwardOpTreeWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeForwardOpTreePrinterLegacyPassPass(PassRegistry &);
|
||||
void initializeDeLICMWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeDeLICMPrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
void initializeSimplifyWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeSimplifyPrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
void initializePruneUnprofitableWrapperPassPass(llvm::PassRegistry &);
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
@@ -14,6 +14,7 @@
|
||||
#ifndef POLLY_MAXIMALSTATICEXPANSION_H
|
||||
#define POLLY_MAXIMALSTATICEXPANSION_H
|
||||
|
||||
#include "polly/DependenceInfo.h"
|
||||
#include "polly/ScopPass.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
@@ -37,6 +38,7 @@ private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
void runMaximalStaticExpansion(Scop &S, DependenceAnalysis::Result &DI);
|
||||
} // namespace polly
|
||||
|
||||
#endif /* POLLY_MAXIMALSTATICEXPANSION_H */
|
||||
|
||||
127
polly/include/polly/Pass/PhaseManager.h
Normal file
127
polly/include/polly/Pass/PhaseManager.h
Normal file
@@ -0,0 +1,127 @@
|
||||
//===------ PhaseManager.h --------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Implements the sequence of operations on SCoPs, called phases. It is itelf
|
||||
// not a pass in either pass manager, but used from PollyFunctionPass or
|
||||
// PollyModulePass.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef POLLY_PASS_PHASEMANAGER_H_
|
||||
#define POLLY_PASS_PHASEMANAGER_H_
|
||||
|
||||
#include "polly/DependenceInfo.h"
|
||||
#include "llvm/ADT/Bitset.h"
|
||||
#include <stddef.h>
|
||||
|
||||
namespace llvm {
|
||||
class Function;
|
||||
class Error;
|
||||
} // namespace llvm
|
||||
|
||||
namespace polly {
|
||||
|
||||
/// Phases (in execution order) within the Polly pass.
|
||||
enum class PassPhase {
|
||||
None,
|
||||
|
||||
Prepare,
|
||||
|
||||
Detection,
|
||||
PrintDetect,
|
||||
DotScops,
|
||||
DotScopsOnly,
|
||||
ViewScops,
|
||||
ViewScopsOnly,
|
||||
|
||||
ScopInfo,
|
||||
PrintScopInfo,
|
||||
|
||||
Flatten,
|
||||
|
||||
Dependences,
|
||||
PrintDependences,
|
||||
|
||||
ImportJScop,
|
||||
Simplify0,
|
||||
Optree,
|
||||
DeLICM,
|
||||
Simplify1,
|
||||
DeadCodeElimination,
|
||||
MaximumStaticExtension,
|
||||
PruneUnprofitable,
|
||||
Optimization,
|
||||
ExportJScop,
|
||||
AstGen,
|
||||
CodeGen,
|
||||
|
||||
PassPhaseFirst = Prepare,
|
||||
PassPhaseLast = CodeGen
|
||||
};
|
||||
|
||||
StringRef getPhaseName(PassPhase Phase);
|
||||
PassPhase parsePhase(StringRef Name);
|
||||
bool dependsOnDependenceInfo(PassPhase Phase);
|
||||
|
||||
/// Options for the Polly pass.
|
||||
class PollyPassOptions {
|
||||
/// For each Polly phase, whether it should be executed.
|
||||
/// Since PassPhase::None is unused, bit positions are shifted by one.
|
||||
llvm::Bitset<static_cast<size_t>(PassPhase::PassPhaseLast) -
|
||||
static_cast<size_t>(PassPhase::PassPhaseFirst) + 1>
|
||||
PhaseEnabled;
|
||||
|
||||
public:
|
||||
bool ViewAll = false;
|
||||
std::string ViewFilter;
|
||||
Dependences::AnalysisLevel PrintDepsAnalysisLevel = Dependences::AL_Statement;
|
||||
|
||||
bool isPhaseEnabled(PassPhase Phase) const {
|
||||
assert(Phase != PassPhase::None);
|
||||
unsigned BitPos = static_cast<size_t>(Phase) -
|
||||
static_cast<size_t>(PassPhase::PassPhaseFirst);
|
||||
return PhaseEnabled[BitPos];
|
||||
}
|
||||
|
||||
void setPhaseEnabled(PassPhase Phase, bool Enabled = true) {
|
||||
assert(Phase != PassPhase::None);
|
||||
unsigned BitPos = static_cast<size_t>(Phase) -
|
||||
static_cast<size_t>(PassPhase::PassPhaseFirst);
|
||||
if (Enabled)
|
||||
PhaseEnabled.set(BitPos);
|
||||
else
|
||||
PhaseEnabled.reset(BitPos);
|
||||
}
|
||||
|
||||
/// Enable all phases that are necessary for a roundtrip from LLVM-IR back to
|
||||
/// LLVM-IR.
|
||||
void enableEnd2End();
|
||||
|
||||
/// Enabled the default optimization phases.
|
||||
void enableDefaultOpts();
|
||||
|
||||
/// Disable all phases following \p Phase.
|
||||
/// Useful when regression testing that particular phase and everything after
|
||||
/// it is not of interest.
|
||||
void disableAfter(PassPhase Phase);
|
||||
|
||||
/// Check whether the options are coherent relative to each other.
|
||||
llvm::Error checkConsistency() const;
|
||||
};
|
||||
|
||||
/// Run Polly and its phases on \p F.
|
||||
bool runPollyPass(Function &F, llvm::FunctionAnalysisManager &FAM,
|
||||
PollyPassOptions Opts);
|
||||
} // namespace polly
|
||||
|
||||
/// Make llvm::enum_seq<PassPhase> work.
|
||||
template <> struct llvm::enum_iteration_traits<polly::PassPhase> {
|
||||
static constexpr bool is_iterable = true;
|
||||
};
|
||||
|
||||
#endif /* POLLY_PASS_PHASEMANAGER_H_ */
|
||||
32
polly/include/polly/Pass/PollyFunctionPass.h
Normal file
32
polly/include/polly/Pass/PollyFunctionPass.h
Normal file
@@ -0,0 +1,32 @@
|
||||
//===------ PollyFunctionPass.h - Polly function pass ---------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef POLLY_PASS_POLLYFUNCTIONPASS_H_
|
||||
#define POLLY_PASS_POLLYFUNCTIONPASS_H_
|
||||
|
||||
#include "polly/Pass/PhaseManager.h"
|
||||
#include "llvm/IR/Analysis.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include <utility>
|
||||
|
||||
namespace polly {
|
||||
|
||||
class PollyFunctionPass : public llvm::PassInfoMixin<PollyFunctionPass> {
|
||||
public:
|
||||
PollyFunctionPass() {}
|
||||
PollyFunctionPass(PollyPassOptions Opts) : Opts(std::move(Opts)) {}
|
||||
|
||||
llvm::PreservedAnalyses run(llvm::Function &F,
|
||||
llvm::FunctionAnalysisManager &);
|
||||
|
||||
private:
|
||||
PollyPassOptions Opts;
|
||||
};
|
||||
} // namespace polly
|
||||
|
||||
#endif /* POLLY_PASS_POLLYFUNCTIONPASS_H_ */
|
||||
30
polly/include/polly/Pass/PollyModulePass.h
Normal file
30
polly/include/polly/Pass/PollyModulePass.h
Normal file
@@ -0,0 +1,30 @@
|
||||
//===------ PollyModulePass.h - Polly module pass -------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef POLLY_PASS_POLLYMODULEPASS_H_
|
||||
#define POLLY_PASS_POLLYMODULEPASS_H_
|
||||
|
||||
#include "polly/Pass/PhaseManager.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
namespace polly {
|
||||
|
||||
class PollyModulePass : public llvm::PassInfoMixin<PollyModulePass> {
|
||||
public:
|
||||
PollyModulePass() {}
|
||||
PollyModulePass(PollyPassOptions Opts) : Opts(std::move(Opts)) {}
|
||||
|
||||
llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &);
|
||||
|
||||
private:
|
||||
PollyPassOptions Opts;
|
||||
};
|
||||
|
||||
} // namespace polly
|
||||
|
||||
#endif /* POLLY_PASS_POLLYMODULEPASS_H_ */
|
||||
@@ -15,13 +15,7 @@
|
||||
|
||||
#include "polly/ScopPass.h"
|
||||
|
||||
namespace llvm {
|
||||
class Pass;
|
||||
class PassRegistry;
|
||||
} // namespace llvm
|
||||
|
||||
namespace polly {
|
||||
llvm::Pass *createPruneUnprofitableWrapperPass();
|
||||
|
||||
struct PruneUnprofitablePass final
|
||||
: llvm::PassInfoMixin<PruneUnprofitablePass> {
|
||||
@@ -30,10 +24,8 @@ struct PruneUnprofitablePass final
|
||||
llvm::PreservedAnalyses run(Scop &S, ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &SAR, SPMUpdater &U);
|
||||
};
|
||||
|
||||
bool runPruneUnprofitable(Scop &S);
|
||||
} // namespace polly
|
||||
|
||||
namespace llvm {
|
||||
void initializePruneUnprofitableWrapperPassPass(PassRegistry &);
|
||||
}
|
||||
|
||||
#endif // POLLY_PRUNEUNPROFITABLE_H
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#define POLLY_REGISTER_PASSES_H
|
||||
|
||||
namespace llvm {
|
||||
class PassRegistry;
|
||||
class PassBuilder;
|
||||
struct PassPluginLibraryInfo;
|
||||
namespace legacy {
|
||||
@@ -23,7 +22,6 @@ class PassManagerBase;
|
||||
} // namespace llvm
|
||||
|
||||
namespace polly {
|
||||
void initializePollyPasses(llvm::PassRegistry &Registry);
|
||||
void registerPollyPasses(llvm::PassBuilder &PB);
|
||||
} // namespace polly
|
||||
|
||||
|
||||
@@ -9,16 +9,10 @@
|
||||
#ifndef POLLY_SCHEDULEOPTIMIZER_H
|
||||
#define POLLY_SCHEDULEOPTIMIZER_H
|
||||
|
||||
#include "polly/DependenceInfo.h"
|
||||
#include "polly/ScopPass.h"
|
||||
|
||||
namespace llvm {
|
||||
class Pass;
|
||||
class PassRegistry;
|
||||
} // namespace llvm
|
||||
|
||||
namespace polly {
|
||||
llvm::Pass *createIslScheduleOptimizerWrapperPass();
|
||||
llvm::Pass *createIslScheduleOptimizerPrinterLegacyPass(llvm::raw_ostream &OS);
|
||||
|
||||
struct IslScheduleOptimizerPass final
|
||||
: llvm::PassInfoMixin<IslScheduleOptimizerPass> {
|
||||
@@ -38,11 +32,9 @@ struct IslScheduleOptimizerPrinterPass final
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
void runIslScheduleOptimizer(Scop &S, llvm::TargetTransformInfo *TTI,
|
||||
DependenceAnalysis::Result &Deps);
|
||||
} // namespace polly
|
||||
|
||||
namespace llvm {
|
||||
void initializeIslScheduleOptimizerWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeIslScheduleOptimizerPrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
} // namespace llvm
|
||||
|
||||
#endif // POLLY_SCHEDULEOPTIMIZER_H
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
#include "llvm/Analysis/AliasSetTracker.h"
|
||||
#include "llvm/Analysis/RegionInfo.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include <set>
|
||||
|
||||
namespace polly {
|
||||
@@ -68,7 +67,6 @@ using llvm::DenseMap;
|
||||
using llvm::DominatorTree;
|
||||
using llvm::Function;
|
||||
using llvm::FunctionAnalysisManager;
|
||||
using llvm::FunctionPass;
|
||||
using llvm::IntrinsicInst;
|
||||
using llvm::LoopInfo;
|
||||
using llvm::Module;
|
||||
@@ -631,31 +629,6 @@ struct ScopAnalysisPrinterPass final : PassInfoMixin<ScopAnalysisPrinterPass> {
|
||||
|
||||
raw_ostream &OS;
|
||||
};
|
||||
|
||||
class ScopDetectionWrapperPass final : public FunctionPass {
|
||||
std::unique_ptr<ScopDetection> Result;
|
||||
|
||||
public:
|
||||
ScopDetectionWrapperPass();
|
||||
|
||||
/// @name FunctionPass interface
|
||||
///@{
|
||||
static char ID;
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
void releaseMemory() override;
|
||||
bool runOnFunction(Function &F) override;
|
||||
void print(raw_ostream &OS, const Module *M = nullptr) const override;
|
||||
///@}
|
||||
|
||||
ScopDetection &getSD() const { return *Result; }
|
||||
};
|
||||
|
||||
llvm::Pass *createScopDetectionPrinterLegacyPass(llvm::raw_ostream &OS);
|
||||
} // namespace polly
|
||||
|
||||
namespace llvm {
|
||||
void initializeScopDetectionWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeScopDetectionPrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
} // namespace llvm
|
||||
|
||||
#endif // POLLY_SCOPDETECTION_H
|
||||
|
||||
@@ -70,6 +70,9 @@ struct DOTGraphTraits<polly::ScopDetection *> : DOTGraphTraits<RegionNode *> {
|
||||
|
||||
namespace polly {
|
||||
|
||||
extern std::string ViewFilter;
|
||||
extern bool ViewAll;
|
||||
|
||||
struct ScopViewer final : llvm::DOTGraphTraitsViewer<ScopAnalysis, false> {
|
||||
ScopViewer() : llvm::DOTGraphTraitsViewer<ScopAnalysis, false>("scops") {}
|
||||
|
||||
|
||||
@@ -23,13 +23,11 @@
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/Analysis/RegionPass.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "isl/isl-noexceptions.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
@@ -55,8 +53,6 @@ using llvm::MemIntrinsic;
|
||||
using llvm::PassInfoMixin;
|
||||
using llvm::PHINode;
|
||||
using llvm::RegionNode;
|
||||
using llvm::RegionPass;
|
||||
using llvm::RGPassManager;
|
||||
using llvm::SetVector;
|
||||
using llvm::SmallPtrSetImpl;
|
||||
using llvm::SmallVector;
|
||||
@@ -2674,39 +2670,6 @@ public:
|
||||
/// Print Scop scop to raw_ostream OS.
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Scop &scop);
|
||||
|
||||
/// The legacy pass manager's analysis pass to compute scop information
|
||||
/// for a region.
|
||||
class ScopInfoRegionPass final : public RegionPass {
|
||||
/// The Scop pointer which is used to construct a Scop.
|
||||
std::unique_ptr<Scop> S;
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
|
||||
ScopInfoRegionPass() : RegionPass(ID) {}
|
||||
~ScopInfoRegionPass() override = default;
|
||||
|
||||
/// Build Scop object, the Polly IR of static control
|
||||
/// part for the current SESE-Region.
|
||||
///
|
||||
/// @return If the current region is a valid for a static control part,
|
||||
/// return the Polly IR representing this static control part,
|
||||
/// return null otherwise.
|
||||
Scop *getScop() { return S.get(); }
|
||||
const Scop *getScop() const { return S.get(); }
|
||||
|
||||
/// Calculate the polyhedral scop information for a given Region.
|
||||
bool runOnRegion(Region *R, RGPassManager &RGM) override;
|
||||
|
||||
void releaseMemory() override { S.reset(); }
|
||||
|
||||
void print(raw_ostream &O, const Module *M = nullptr) const override;
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
};
|
||||
|
||||
llvm::Pass *createScopInfoPrinterLegacyRegionPass(raw_ostream &OS);
|
||||
|
||||
class ScopInfo {
|
||||
public:
|
||||
using RegionToScopMapTy = MapVector<Region *, std::unique_ptr<Scop>>;
|
||||
@@ -2781,45 +2744,6 @@ struct ScopInfoPrinterPass final : PassInfoMixin<ScopInfoPrinterPass> {
|
||||
|
||||
raw_ostream &Stream;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// 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 final : public FunctionPass {
|
||||
std::unique_ptr<ScopInfo> Result;
|
||||
|
||||
public:
|
||||
ScopInfoWrapperPass() : FunctionPass(ID) {}
|
||||
~ScopInfoWrapperPass() override = default;
|
||||
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
|
||||
ScopInfo *getSI() { return Result.get(); }
|
||||
const ScopInfo *getSI() const { return Result.get(); }
|
||||
|
||||
/// Calculate all the polyhedral scops for a given function.
|
||||
bool runOnFunction(Function &F) override;
|
||||
|
||||
void releaseMemory() override { Result.reset(); }
|
||||
|
||||
void print(raw_ostream &O, const Module *M = nullptr) const override;
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
};
|
||||
|
||||
llvm::Pass *createScopInfoPrinterLegacyFunctionPass(llvm::raw_ostream &OS);
|
||||
} // end namespace polly
|
||||
|
||||
namespace llvm {
|
||||
void initializeScopInfoRegionPassPass(PassRegistry &);
|
||||
void initializeScopInfoPrinterLegacyRegionPassPass(PassRegistry &);
|
||||
void initializeScopInfoWrapperPassPass(PassRegistry &);
|
||||
void initializeScopInfoPrinterLegacyFunctionPassPass(PassRegistry &);
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // POLLY_SCOPINFO_H
|
||||
|
||||
@@ -23,12 +23,6 @@ public:
|
||||
llvm::LazyCallGraph &CG,
|
||||
llvm::CGSCCUpdateResult &UR);
|
||||
};
|
||||
|
||||
llvm::Pass *createScopInlinerWrapperPass();
|
||||
} // namespace polly
|
||||
|
||||
namespace llvm {
|
||||
void initializeScopInlinerWrapperPassPass(llvm::PassRegistry &);
|
||||
}
|
||||
|
||||
#endif /* POLLY_POLLYINLINER_H */
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "polly/ScopInfo.h"
|
||||
#include "llvm/ADT/PriorityWorklist.h"
|
||||
#include "llvm/Analysis/RegionPass.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/PassManagerImpl.h"
|
||||
@@ -155,33 +154,6 @@ using ScopPassManager =
|
||||
PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &,
|
||||
SPMUpdater &>;
|
||||
|
||||
/// ScopPass - This class adapts the RegionPass interface to allow convenient
|
||||
/// creation of passes that operate on the Polly IR. Instead of overriding
|
||||
/// runOnRegion, subclasses override runOnScop.
|
||||
class ScopPass : public RegionPass {
|
||||
Scop *S;
|
||||
|
||||
protected:
|
||||
explicit ScopPass(char &ID) : RegionPass(ID), S(nullptr) {}
|
||||
|
||||
/// runOnScop - This method must be overloaded to perform the
|
||||
/// desired Polyhedral transformation or analysis.
|
||||
///
|
||||
virtual bool runOnScop(Scop &S) = 0;
|
||||
|
||||
/// Print method for SCoPs.
|
||||
virtual void printScop(raw_ostream &OS, Scop &S) const {}
|
||||
|
||||
/// getAnalysisUsage - Subclasses that override getAnalysisUsage
|
||||
/// must call this.
|
||||
///
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
|
||||
private:
|
||||
bool runOnRegion(Region *R, RGPassManager &RGM) override;
|
||||
void print(raw_ostream &OS, const Module *) const override;
|
||||
};
|
||||
|
||||
struct ScopStandardAnalysisResults {
|
||||
DominatorTree &DT;
|
||||
ScopInfo &SI;
|
||||
|
||||
@@ -16,11 +16,6 @@
|
||||
#include "polly/ScopPass.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace llvm {
|
||||
class PassRegistry;
|
||||
class Pass;
|
||||
} // namespace llvm
|
||||
|
||||
namespace polly {
|
||||
class MemoryAccess;
|
||||
class ScopStmt;
|
||||
@@ -41,17 +36,6 @@ class ScopStmt;
|
||||
/// undefined.
|
||||
llvm::SmallVector<MemoryAccess *, 32> getAccessesInOrder(ScopStmt &Stmt);
|
||||
|
||||
/// Create a Simplify pass
|
||||
///
|
||||
/// @param CallNo Disambiguates this instance for when there are multiple
|
||||
/// instances of this pass in the pass manager. It is used only to
|
||||
/// keep the statistics apart and has no influence on the
|
||||
/// simplification itself.
|
||||
///
|
||||
/// @return The Simplify pass.
|
||||
llvm::Pass *createSimplifyWrapperPass(int CallNo = 0);
|
||||
llvm::Pass *createSimplifyPrinterLegacyPass(llvm::raw_ostream &OS);
|
||||
|
||||
struct SimplifyPass final : PassInfoMixin<SimplifyPass> {
|
||||
SimplifyPass(int CallNo = 0) : CallNo(CallNo) {}
|
||||
|
||||
@@ -73,11 +57,8 @@ private:
|
||||
raw_ostream &OS;
|
||||
int CallNo;
|
||||
};
|
||||
|
||||
bool runSimplify(Scop &S, int CallNo);
|
||||
} // namespace polly
|
||||
|
||||
namespace llvm {
|
||||
void initializeSimplifyWrapperPassPass(llvm::PassRegistry &);
|
||||
void initializeSimplifyPrinterLegacyPassPass(llvm::PassRegistry &);
|
||||
} // namespace llvm
|
||||
|
||||
#endif /* POLLY_TRANSFORM_SIMPLIFY_H */
|
||||
|
||||
@@ -16,13 +16,7 @@
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class FunctionPass;
|
||||
class ModulePass;
|
||||
} // namespace llvm
|
||||
|
||||
namespace polly {
|
||||
llvm::FunctionPass *createDumpFunctionWrapperPass(std::string Suffix);
|
||||
|
||||
/// A pass that isolates a function into a new Module and writes it into a file.
|
||||
struct DumpFunctionPass final : llvm::PassInfoMixin<DumpFunctionPass> {
|
||||
@@ -33,12 +27,6 @@ struct DumpFunctionPass final : llvm::PassInfoMixin<DumpFunctionPass> {
|
||||
llvm::PreservedAnalyses run(llvm::Function &F,
|
||||
llvm::FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
} // namespace polly
|
||||
|
||||
namespace llvm {
|
||||
class PassRegistry;
|
||||
void initializeDumpFunctionWrapperPassPass(llvm::PassRegistry &);
|
||||
} // namespace llvm
|
||||
|
||||
#endif /* POLLY_SUPPORT_DUMPFUNCTIONPASS_H */
|
||||
|
||||
@@ -16,12 +16,8 @@
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class ModulePass;
|
||||
} // namespace llvm
|
||||
|
||||
namespace polly {
|
||||
/// Create a pass that prints the module into a file.
|
||||
/// A pass that prints the module into a file.
|
||||
///
|
||||
/// The meaning of @p Filename depends on @p IsSuffix. If IsSuffix==false, then
|
||||
/// the module is written to the @p Filename. If it is true, the filename is
|
||||
@@ -30,10 +26,6 @@ namespace polly {
|
||||
/// The intent of IsSuffix is to avoid the file being overwritten when
|
||||
/// processing multiple modules and/or with multiple dump passes in the
|
||||
/// pipeline.
|
||||
llvm::ModulePass *createDumpModuleWrapperPass(std::string Filename,
|
||||
bool IsSuffix);
|
||||
|
||||
/// A pass that prints the module into a file.
|
||||
struct DumpModulePass final : llvm::PassInfoMixin<DumpModulePass> {
|
||||
std::string Filename;
|
||||
bool IsSuffix;
|
||||
@@ -46,9 +38,4 @@ struct DumpModulePass final : llvm::PassInfoMixin<DumpModulePass> {
|
||||
|
||||
} // namespace polly
|
||||
|
||||
namespace llvm {
|
||||
class PassRegistry;
|
||||
void initializeDumpModuleWrapperPassPass(llvm::PassRegistry &);
|
||||
} // namespace llvm
|
||||
|
||||
#endif /* POLLY_SUPPORT_DUMPMODULEPASS_H */
|
||||
|
||||
@@ -358,14 +358,6 @@ namespace polly {
|
||||
void simplifyRegion(llvm::Region *R, llvm::DominatorTree *DT,
|
||||
llvm::LoopInfo *LI, llvm::RegionInfo *RI);
|
||||
|
||||
/// Split the entry block of a function to store the newly inserted
|
||||
/// allocations outside of all Scops.
|
||||
///
|
||||
/// @param EntryBlock The entry block of the current function.
|
||||
/// @param P The pass that currently running.
|
||||
///
|
||||
void splitEntryBlockForAlloca(llvm::BasicBlock *EntryBlock, llvm::Pass *P);
|
||||
|
||||
/// Split the entry block of a function to store the newly inserted
|
||||
/// allocations outside of all Scops.
|
||||
///
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
#include "polly/DependenceInfo.h"
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/Options.h"
|
||||
#include "polly/ScopInfo.h"
|
||||
#include "polly/Support/GICHelper.h"
|
||||
@@ -42,6 +41,10 @@ using namespace llvm;
|
||||
#include "polly/Support/PollyDebug.h"
|
||||
#define DEBUG_TYPE "polly-dependence"
|
||||
|
||||
namespace polly {
|
||||
Dependences::AnalysisLevel OptAnalysisLevel;
|
||||
}
|
||||
|
||||
static cl::opt<int> OptComputeOut(
|
||||
"polly-dependences-computeout",
|
||||
cl::desc("Bound the dependence analysis by a maximal amount of "
|
||||
@@ -69,9 +72,10 @@ static cl::opt<enum AnalysisType> OptAnalysisType(
|
||||
"Overapproximation of dependences")),
|
||||
cl::Hidden, cl::init(VALUE_BASED_ANALYSIS), cl::cat(PollyCategory));
|
||||
|
||||
static cl::opt<Dependences::AnalysisLevel> OptAnalysisLevel(
|
||||
static cl::opt<Dependences::AnalysisLevel, true> XOptAnalysisLevel(
|
||||
"polly-dependences-analysis-level",
|
||||
cl::desc("The level of dependence analysis"),
|
||||
cl::location(OptAnalysisLevel),
|
||||
cl::values(clEnumValN(Dependences::AL_Statement, "statement-wise",
|
||||
"Statement-level analysis"),
|
||||
clEnumValN(Dependences::AL_Reference, "reference-wise",
|
||||
@@ -881,213 +885,7 @@ DependenceInfoPrinterPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
const Dependences &
|
||||
DependenceInfo::getDependences(Dependences::AnalysisLevel Level) {
|
||||
if (Dependences *d = D[Level].get())
|
||||
return *d;
|
||||
|
||||
return recomputeDependences(Level);
|
||||
DependenceAnalysis::Result polly::runDependenceAnalysis(Scop &S) {
|
||||
DependenceAnalysis::Result Result{S, {}};
|
||||
return Result;
|
||||
}
|
||||
|
||||
const Dependences &
|
||||
DependenceInfo::recomputeDependences(Dependences::AnalysisLevel Level) {
|
||||
D[Level].reset(new Dependences(S->getSharedIslCtx(), Level));
|
||||
D[Level]->calculateDependences(*S);
|
||||
return *D[Level];
|
||||
}
|
||||
|
||||
void DependenceInfo::abandonDependences() {
|
||||
for (std::unique_ptr<Dependences> &Deps : D)
|
||||
Deps.release();
|
||||
}
|
||||
|
||||
bool DependenceInfo::runOnScop(Scop &ScopVar) {
|
||||
S = &ScopVar;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Print the dependences for the given SCoP to @p OS.
|
||||
|
||||
void polly::DependenceInfo::printScop(raw_ostream &OS, Scop &S) const {
|
||||
if (auto d = D[OptAnalysisLevel].get()) {
|
||||
d->print(OS);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise create the dependences on-the-fly and print it
|
||||
Dependences D(S.getSharedIslCtx(), OptAnalysisLevel);
|
||||
D.calculateDependences(S);
|
||||
D.print(OS);
|
||||
}
|
||||
|
||||
void DependenceInfo::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequiredTransitive<ScopInfoRegionPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
char DependenceInfo::ID = 0;
|
||||
|
||||
Pass *polly::createDependenceInfoPass() { return new DependenceInfo(); }
|
||||
|
||||
INITIALIZE_PASS_BEGIN(DependenceInfo, "polly-dependences",
|
||||
"Polly - Calculate dependences", false, false);
|
||||
INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass);
|
||||
INITIALIZE_PASS_END(DependenceInfo, "polly-dependences",
|
||||
"Polly - Calculate dependences", false, false)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
/// Print result from DependenceAnalysis.
|
||||
class DependenceInfoPrinterLegacyPass final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
DependenceInfoPrinterLegacyPass() : DependenceInfoPrinterLegacyPass(outs()) {}
|
||||
|
||||
explicit DependenceInfoPrinterLegacyPass(llvm::raw_ostream &OS)
|
||||
: ScopPass(ID), OS(OS) {}
|
||||
|
||||
bool runOnScop(Scop &S) override {
|
||||
DependenceInfo &P = getAnalysis<DependenceInfo>();
|
||||
|
||||
OS << "Printing analysis '" << P.getPassName() << "' for "
|
||||
<< "region: '" << S.getRegion().getNameStr() << "' in function '"
|
||||
<< S.getFunction().getName() << "':\n";
|
||||
P.printScop(OS, S);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<DependenceInfo>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
char DependenceInfoPrinterLegacyPass::ID = 0;
|
||||
} // namespace
|
||||
|
||||
Pass *polly::createDependenceInfoPrinterLegacyPass(raw_ostream &OS) {
|
||||
return new DependenceInfoPrinterLegacyPass(OS);
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(DependenceInfoPrinterLegacyPass,
|
||||
"polly-print-dependences", "Polly - Print dependences",
|
||||
false, false);
|
||||
INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
|
||||
INITIALIZE_PASS_END(DependenceInfoPrinterLegacyPass, "polly-print-dependences",
|
||||
"Polly - Print dependences", false, false)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
const Dependences &
|
||||
DependenceInfoWrapperPass::getDependences(Scop *S,
|
||||
Dependences::AnalysisLevel Level) {
|
||||
auto It = ScopToDepsMap.find(S);
|
||||
if (It != ScopToDepsMap.end())
|
||||
if (It->second) {
|
||||
if (It->second->getDependenceLevel() == Level)
|
||||
return *It->second;
|
||||
}
|
||||
return recomputeDependences(S, Level);
|
||||
}
|
||||
|
||||
const Dependences &DependenceInfoWrapperPass::recomputeDependences(
|
||||
Scop *S, Dependences::AnalysisLevel Level) {
|
||||
std::unique_ptr<Dependences> D(new Dependences(S->getSharedIslCtx(), Level));
|
||||
D->calculateDependences(*S);
|
||||
auto Inserted = ScopToDepsMap.insert(std::make_pair(S, std::move(D)));
|
||||
return *Inserted.first->second;
|
||||
}
|
||||
|
||||
bool DependenceInfoWrapperPass::runOnFunction(Function &F) {
|
||||
auto &SI = *getAnalysis<ScopInfoWrapperPass>().getSI();
|
||||
for (auto &It : SI) {
|
||||
assert(It.second && "Invalid SCoP object!");
|
||||
recomputeDependences(It.second.get(), Dependences::AL_Access);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DependenceInfoWrapperPass::print(raw_ostream &OS, const Module *M) const {
|
||||
for (auto &It : ScopToDepsMap) {
|
||||
assert((It.first && It.second) && "Invalid Scop or Dependence object!\n");
|
||||
It.second->print(OS);
|
||||
}
|
||||
}
|
||||
|
||||
void DependenceInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequiredTransitive<ScopInfoWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
char DependenceInfoWrapperPass::ID = 0;
|
||||
|
||||
Pass *polly::createDependenceInfoWrapperPassPass() {
|
||||
return new DependenceInfoWrapperPass();
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(
|
||||
DependenceInfoWrapperPass, "polly-function-dependences",
|
||||
"Polly - Calculate dependences for all the SCoPs of a function", false,
|
||||
false)
|
||||
INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass);
|
||||
INITIALIZE_PASS_END(
|
||||
DependenceInfoWrapperPass, "polly-function-dependences",
|
||||
"Polly - Calculate dependences for all the SCoPs of a function", false,
|
||||
false)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
/// Print result from DependenceInfoWrapperPass.
|
||||
class DependenceInfoPrinterLegacyFunctionPass final : public FunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
DependenceInfoPrinterLegacyFunctionPass()
|
||||
: DependenceInfoPrinterLegacyFunctionPass(outs()) {}
|
||||
|
||||
explicit DependenceInfoPrinterLegacyFunctionPass(llvm::raw_ostream &OS)
|
||||
: FunctionPass(ID), OS(OS) {}
|
||||
|
||||
bool runOnFunction(Function &F) override {
|
||||
DependenceInfoWrapperPass &P = getAnalysis<DependenceInfoWrapperPass>();
|
||||
|
||||
OS << "Printing analysis '" << P.getPassName() << "' for function '"
|
||||
<< F.getName() << "':\n";
|
||||
P.print(OS);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
FunctionPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<DependenceInfoWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
char DependenceInfoPrinterLegacyFunctionPass::ID = 0;
|
||||
} // namespace
|
||||
|
||||
Pass *polly::createDependenceInfoPrinterLegacyFunctionPass(raw_ostream &OS) {
|
||||
return new DependenceInfoPrinterLegacyFunctionPass(OS);
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(
|
||||
DependenceInfoPrinterLegacyFunctionPass, "polly-print-function-dependences",
|
||||
"Polly - Print dependences for all the SCoPs of a function", false, false);
|
||||
INITIALIZE_PASS_DEPENDENCY(DependenceInfoWrapperPass);
|
||||
INITIALIZE_PASS_END(DependenceInfoPrinterLegacyFunctionPass,
|
||||
"polly-print-function-dependences",
|
||||
"Polly - Print dependences for all the SCoPs of a function",
|
||||
false, false)
|
||||
|
||||
@@ -55,8 +55,9 @@ static void updateStatistics(Scop &S, bool Pruned) {
|
||||
NumAffineLoops += ScopStats.NumAffineLoops;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
static bool runPruneUnprofitable(Scop &S) {
|
||||
bool polly::runPruneUnprofitable(Scop &S) {
|
||||
if (PollyProcessUnprofitable) {
|
||||
POLLY_DEBUG(
|
||||
dbgs() << "NOTE: -polly-process-unprofitable active, won't prune "
|
||||
@@ -79,35 +80,6 @@ static bool runPruneUnprofitable(Scop &S) {
|
||||
return false;
|
||||
}
|
||||
|
||||
class PruneUnprofitableWrapperPass final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
explicit PruneUnprofitableWrapperPass() : ScopPass(ID) {}
|
||||
PruneUnprofitableWrapperPass(const PruneUnprofitableWrapperPass &) = delete;
|
||||
PruneUnprofitableWrapperPass &
|
||||
operator=(const PruneUnprofitableWrapperPass &) = delete;
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<ScopInfoRegionPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
bool runOnScop(Scop &S) override { return runPruneUnprofitable(S); }
|
||||
};
|
||||
} // namespace
|
||||
|
||||
char PruneUnprofitableWrapperPass::ID;
|
||||
|
||||
Pass *polly::createPruneUnprofitableWrapperPass() {
|
||||
return new PruneUnprofitableWrapperPass();
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(PruneUnprofitableWrapperPass, "polly-prune-unprofitable",
|
||||
"Polly - Prune unprofitable SCoPs", false, false)
|
||||
INITIALIZE_PASS_END(PruneUnprofitableWrapperPass, "polly-prune-unprofitable",
|
||||
"Polly - Prune unprofitable SCoPs", false, false)
|
||||
|
||||
llvm::PreservedAnalyses
|
||||
PruneUnprofitablePass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &SAR, SPMUpdater &U) {
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
#include <deque>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace polly;
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "polly/ScopDetection.h"
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/Options.h"
|
||||
#include "polly/ScopDetectionDiagnostic.h"
|
||||
#include "polly/Support/SCEVValidator.h"
|
||||
@@ -75,8 +74,6 @@
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/InitializePasses.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/Regex.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@@ -1983,53 +1980,12 @@ void ScopDetection::verifyAnalysis() {
|
||||
verifyRegion(*R);
|
||||
}
|
||||
|
||||
bool ScopDetectionWrapperPass::runOnFunction(Function &F) {
|
||||
auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
auto &RI = getAnalysis<RegionInfoPass>().getRegionInfo();
|
||||
auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
|
||||
|
||||
Result = std::make_unique<ScopDetection>(DT, SE, LI, RI, AA, ORE);
|
||||
Result->detect(F);
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScopDetectionWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<LoopInfoWrapperPass>();
|
||||
AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
|
||||
// We also need AA and RegionInfo when we are verifying analysis.
|
||||
AU.addRequiredTransitive<AAResultsWrapperPass>();
|
||||
AU.addRequiredTransitive<RegionInfoPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
void ScopDetectionWrapperPass::print(raw_ostream &OS, const Module *) const {
|
||||
for (const Region *R : Result->ValidRegions)
|
||||
OS << "Valid Region for Scop: " << R->getNameStr() << '\n';
|
||||
|
||||
OS << "\n";
|
||||
}
|
||||
|
||||
ScopDetectionWrapperPass::ScopDetectionWrapperPass() : FunctionPass(ID) {
|
||||
// Disable runtime alias checks if we ignore aliasing all together.
|
||||
if (IgnoreAliasing)
|
||||
PollyUseRuntimeAliasChecks = false;
|
||||
}
|
||||
|
||||
ScopAnalysis::ScopAnalysis() {
|
||||
// Disable runtime alias checks if we ignore aliasing all together.
|
||||
if (IgnoreAliasing)
|
||||
PollyUseRuntimeAliasChecks = false;
|
||||
}
|
||||
|
||||
void ScopDetectionWrapperPass::releaseMemory() { Result.reset(); }
|
||||
|
||||
char ScopDetectionWrapperPass::ID;
|
||||
|
||||
AnalysisKey ScopAnalysis::Key;
|
||||
|
||||
ScopDetection ScopAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
|
||||
@@ -2055,66 +2011,3 @@ PreservedAnalyses ScopAnalysisPrinterPass::run(Function &F,
|
||||
OS << "\n";
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
Pass *polly::createScopDetectionWrapperPassPass() {
|
||||
return new ScopDetectionWrapperPass();
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(ScopDetectionWrapperPass, "polly-detect",
|
||||
"Polly - Detect static control parts (SCoPs)", false,
|
||||
false);
|
||||
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass);
|
||||
INITIALIZE_PASS_END(ScopDetectionWrapperPass, "polly-detect",
|
||||
"Polly - Detect static control parts (SCoPs)", false, false)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
/// Print result from ScopDetectionWrapperPass.
|
||||
class ScopDetectionPrinterLegacyPass final : public FunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
ScopDetectionPrinterLegacyPass() : ScopDetectionPrinterLegacyPass(outs()) {}
|
||||
|
||||
explicit ScopDetectionPrinterLegacyPass(llvm::raw_ostream &OS)
|
||||
: FunctionPass(ID), OS(OS) {}
|
||||
|
||||
bool runOnFunction(Function &F) override {
|
||||
ScopDetectionWrapperPass &P = getAnalysis<ScopDetectionWrapperPass>();
|
||||
|
||||
OS << "Printing analysis '" << P.getPassName() << "' for function '"
|
||||
<< F.getName() << "':\n";
|
||||
P.print(OS);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
FunctionPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<ScopDetectionWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
char ScopDetectionPrinterLegacyPass::ID = 0;
|
||||
} // namespace
|
||||
|
||||
Pass *polly::createScopDetectionPrinterLegacyPass(raw_ostream &OS) {
|
||||
return new ScopDetectionPrinterLegacyPass(OS);
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(ScopDetectionPrinterLegacyPass, "polly-print-detect",
|
||||
"Polly - Print static control parts (SCoPs)", false,
|
||||
false);
|
||||
INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass);
|
||||
INITIALIZE_PASS_END(ScopDetectionPrinterLegacyPass, "polly-print-detect",
|
||||
"Polly - Print static control parts (SCoPs)", false, false)
|
||||
|
||||
@@ -14,20 +14,26 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "polly/ScopGraphPrinter.h"
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/ScopDetection.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
using namespace polly;
|
||||
using namespace llvm;
|
||||
static cl::opt<std::string>
|
||||
ViewFilter("polly-view-only",
|
||||
cl::desc("Only view functions that match this pattern"),
|
||||
cl::Hidden, cl::init(""));
|
||||
|
||||
static cl::opt<bool> ViewAll("polly-view-all",
|
||||
cl::desc("Also show functions without any scops"),
|
||||
cl::Hidden, cl::init(false));
|
||||
namespace polly {
|
||||
std::string ViewFilter;
|
||||
bool ViewAll;
|
||||
} // namespace polly
|
||||
|
||||
static cl::opt<std::string, true>
|
||||
XViewFilter("polly-view-only",
|
||||
cl::desc("Only view functions that match this pattern"),
|
||||
cl::location(ViewFilter), cl::Hidden, cl::init(""));
|
||||
|
||||
static cl::opt<bool, true>
|
||||
XViewAll("polly-view-all",
|
||||
cl::desc("Also show functions without any scops"),
|
||||
cl::location(ViewAll), cl::Hidden, cl::init(false));
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -134,104 +140,6 @@ void DOTGraphTraits<ScopDetection *>::addCustomGraphFeatures(
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
struct ScopDetectionAnalysisGraphTraits {
|
||||
static ScopDetection *getGraph(ScopDetectionWrapperPass *Analysis) {
|
||||
return &Analysis->getSD();
|
||||
}
|
||||
};
|
||||
|
||||
struct ScopViewerWrapperPass
|
||||
: DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
|
||||
ScopDetection *,
|
||||
ScopDetectionAnalysisGraphTraits> {
|
||||
static char ID;
|
||||
ScopViewerWrapperPass()
|
||||
: DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
|
||||
ScopDetection *,
|
||||
ScopDetectionAnalysisGraphTraits>(
|
||||
"scops", ID) {}
|
||||
bool processFunction(Function &F, ScopDetectionWrapperPass &SD) override {
|
||||
if (ViewFilter != "" && !F.getName().count(ViewFilter))
|
||||
return false;
|
||||
|
||||
if (ViewAll)
|
||||
return true;
|
||||
|
||||
// Check that at least one scop was detected.
|
||||
return std::distance(SD.getSD().begin(), SD.getSD().end()) > 0;
|
||||
}
|
||||
};
|
||||
char ScopViewerWrapperPass::ID = 0;
|
||||
|
||||
struct ScopOnlyViewerWrapperPass
|
||||
: DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
|
||||
ScopDetection *,
|
||||
ScopDetectionAnalysisGraphTraits> {
|
||||
static char ID;
|
||||
ScopOnlyViewerWrapperPass()
|
||||
: DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
|
||||
ScopDetection *,
|
||||
ScopDetectionAnalysisGraphTraits>(
|
||||
"scopsonly", ID) {}
|
||||
};
|
||||
char ScopOnlyViewerWrapperPass::ID = 0;
|
||||
|
||||
struct ScopPrinterWrapperPass
|
||||
: DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, false,
|
||||
ScopDetection *,
|
||||
ScopDetectionAnalysisGraphTraits> {
|
||||
static char ID;
|
||||
ScopPrinterWrapperPass()
|
||||
: DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, false,
|
||||
ScopDetection *,
|
||||
ScopDetectionAnalysisGraphTraits>(
|
||||
"scops", ID) {}
|
||||
};
|
||||
char ScopPrinterWrapperPass::ID = 0;
|
||||
|
||||
struct ScopOnlyPrinterWrapperPass
|
||||
: DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, true,
|
||||
ScopDetection *,
|
||||
ScopDetectionAnalysisGraphTraits> {
|
||||
static char ID;
|
||||
ScopOnlyPrinterWrapperPass()
|
||||
: DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, true,
|
||||
ScopDetection *,
|
||||
ScopDetectionAnalysisGraphTraits>(
|
||||
"scopsonly", ID) {}
|
||||
};
|
||||
char ScopOnlyPrinterWrapperPass::ID = 0;
|
||||
|
||||
static RegisterPass<ScopViewerWrapperPass> X("view-scops",
|
||||
"Polly - View Scops of function");
|
||||
|
||||
static RegisterPass<ScopOnlyViewerWrapperPass>
|
||||
Y("view-scops-only",
|
||||
"Polly - View Scops of function (with no function bodies)");
|
||||
|
||||
static RegisterPass<ScopPrinterWrapperPass>
|
||||
M("dot-scops", "Polly - Print Scops of function");
|
||||
|
||||
static RegisterPass<ScopOnlyPrinterWrapperPass>
|
||||
N("dot-scops-only",
|
||||
"Polly - Print Scops of function (with no function bodies)");
|
||||
|
||||
Pass *polly::createDOTViewerWrapperPass() {
|
||||
return new ScopViewerWrapperPass();
|
||||
}
|
||||
|
||||
Pass *polly::createDOTOnlyViewerWrapperPass() {
|
||||
return new ScopOnlyViewerWrapperPass();
|
||||
}
|
||||
|
||||
Pass *polly::createDOTPrinterWrapperPass() {
|
||||
return new ScopPrinterWrapperPass();
|
||||
}
|
||||
|
||||
Pass *polly::createDOTOnlyPrinterWrapperPass() {
|
||||
return new ScopOnlyPrinterWrapperPass();
|
||||
}
|
||||
|
||||
bool ScopViewer::processFunction(Function &F, const ScopDetection &SD) {
|
||||
if (ViewFilter != "" && !F.getName().count(ViewFilter))
|
||||
return false;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "polly/ScopInfo.h"
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/Options.h"
|
||||
#include "polly/ScopBuilder.h"
|
||||
#include "polly/ScopDetection.h"
|
||||
@@ -57,7 +56,6 @@
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/InitializePasses.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
@@ -2544,19 +2542,6 @@ raw_ostream &polly::operator<<(raw_ostream &OS, const Scop &scop) {
|
||||
return OS;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
void ScopInfoRegionPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<LoopInfoWrapperPass>();
|
||||
AU.addRequired<RegionInfoPass>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
|
||||
AU.addRequiredTransitive<ScopDetectionWrapperPass>();
|
||||
AU.addRequired<AAResultsWrapperPass>();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
void updateLoopCountStatistic(ScopDetection::LoopStats Stats,
|
||||
Scop::ScopStatistics ScopStats) {
|
||||
assert(Stats.NumLoops == ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops);
|
||||
@@ -2592,112 +2577,6 @@ void updateLoopCountStatistic(ScopDetection::LoopStats Stats,
|
||||
NumSingletonWritesInLoops += ScopStats.NumSingletonWritesInLoops;
|
||||
}
|
||||
|
||||
bool ScopInfoRegionPass::runOnRegion(Region *R, RGPassManager &RGM) {
|
||||
auto &SD = getAnalysis<ScopDetectionWrapperPass>().getSD();
|
||||
|
||||
if (!SD.isMaxRegionInScop(*R))
|
||||
return false;
|
||||
|
||||
Function *F = R->getEntry()->getParent();
|
||||
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);
|
||||
auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
|
||||
|
||||
ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE, ORE);
|
||||
S = SB.getScop(); // take ownership of scop object
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
|
||||
if (S) {
|
||||
ScopDetection::LoopStats Stats =
|
||||
ScopDetection::countBeneficialLoops(&S->getRegion(), SE, LI, 0);
|
||||
updateLoopCountStatistic(Stats, S->getStatistics());
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScopInfoRegionPass::print(raw_ostream &OS, const Module *) const {
|
||||
if (S)
|
||||
S->print(OS, PollyPrintInstructions);
|
||||
else
|
||||
OS << "Invalid Scop!\n";
|
||||
}
|
||||
|
||||
char ScopInfoRegionPass::ID = 0;
|
||||
|
||||
Pass *polly::createScopInfoRegionPassPass() { return new ScopInfoRegionPass(); }
|
||||
|
||||
INITIALIZE_PASS_BEGIN(ScopInfoRegionPass, "polly-scops",
|
||||
"Polly - Create polyhedral description of Scops", 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(ScopDetectionWrapperPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
|
||||
INITIALIZE_PASS_END(ScopInfoRegionPass, "polly-scops",
|
||||
"Polly - Create polyhedral description of Scops", false,
|
||||
false)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
|
||||
/// Print result from ScopInfoRegionPass.
|
||||
class ScopInfoPrinterLegacyRegionPass final : public RegionPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
ScopInfoPrinterLegacyRegionPass() : ScopInfoPrinterLegacyRegionPass(outs()) {}
|
||||
|
||||
explicit ScopInfoPrinterLegacyRegionPass(llvm::raw_ostream &OS)
|
||||
: RegionPass(ID), OS(OS) {}
|
||||
|
||||
bool runOnRegion(Region *R, RGPassManager &RGM) override {
|
||||
ScopInfoRegionPass &P = getAnalysis<ScopInfoRegionPass>();
|
||||
|
||||
OS << "Printing analysis '" << P.getPassName() << "' for region: '"
|
||||
<< R->getNameStr() << "' in function '"
|
||||
<< R->getEntry()->getParent()->getName() << "':\n";
|
||||
P.print(OS);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
RegionPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<ScopInfoRegionPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
char ScopInfoPrinterLegacyRegionPass::ID = 0;
|
||||
} // namespace
|
||||
|
||||
Pass *polly::createScopInfoPrinterLegacyRegionPass(raw_ostream &OS) {
|
||||
return new ScopInfoPrinterLegacyRegionPass(OS);
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(ScopInfoPrinterLegacyRegionPass, "polly-print-scops",
|
||||
"Polly - Print polyhedral description of Scops", false,
|
||||
false);
|
||||
INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass);
|
||||
INITIALIZE_PASS_END(ScopInfoPrinterLegacyRegionPass, "polly-print-scops",
|
||||
"Polly - Print polyhedral description of Scops", false,
|
||||
false)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
ScopInfo::ScopInfo(const DataLayout &DL, ScopDetection &SD, ScalarEvolution &SE,
|
||||
LoopInfo &LI, AliasAnalysis &AA, DominatorTree &DT,
|
||||
AssumptionCache &AC, OptimizationRemarkEmitter &ORE)
|
||||
@@ -2771,110 +2650,3 @@ PreservedAnalyses ScopInfoPrinterPass::run(Function &F,
|
||||
}
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
void ScopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<LoopInfoWrapperPass>();
|
||||
AU.addRequired<RegionInfoPass>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
|
||||
AU.addRequiredTransitive<ScopDetectionWrapperPass>();
|
||||
AU.addRequired<AAResultsWrapperPass>();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
bool ScopInfoWrapperPass::runOnFunction(Function &F) {
|
||||
auto &SD = getAnalysis<ScopDetectionWrapperPass>().getSD();
|
||||
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);
|
||||
auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
|
||||
|
||||
Result.reset(new ScopInfo{DL, SD, SE, LI, AA, DT, AC, ORE});
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScopInfoWrapperPass::print(raw_ostream &OS, const Module *) const {
|
||||
for (auto &It : *Result) {
|
||||
if (It.second)
|
||||
It.second->print(OS, PollyPrintInstructions);
|
||||
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(ScopDetectionWrapperPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
|
||||
INITIALIZE_PASS_END(
|
||||
ScopInfoWrapperPass, "polly-function-scops",
|
||||
"Polly - Create polyhedral description of all Scops of a function", false,
|
||||
false)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
/// Print result from ScopInfoWrapperPass.
|
||||
class ScopInfoPrinterLegacyFunctionPass final : public FunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
ScopInfoPrinterLegacyFunctionPass()
|
||||
: ScopInfoPrinterLegacyFunctionPass(outs()) {}
|
||||
explicit ScopInfoPrinterLegacyFunctionPass(llvm::raw_ostream &OS)
|
||||
: FunctionPass(ID), OS(OS) {}
|
||||
|
||||
bool runOnFunction(Function &F) override {
|
||||
ScopInfoWrapperPass &P = getAnalysis<ScopInfoWrapperPass>();
|
||||
|
||||
OS << "Printing analysis '" << P.getPassName() << "' for function '"
|
||||
<< F.getName() << "':\n";
|
||||
P.print(OS);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
FunctionPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<ScopInfoWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
char ScopInfoPrinterLegacyFunctionPass::ID = 0;
|
||||
} // namespace
|
||||
|
||||
Pass *polly::createScopInfoPrinterLegacyFunctionPass(raw_ostream &OS) {
|
||||
return new ScopInfoPrinterLegacyFunctionPass(OS);
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(
|
||||
ScopInfoPrinterLegacyFunctionPass, "polly-print-function-scops",
|
||||
"Polly - Print polyhedral description of all Scops of a function", false,
|
||||
false);
|
||||
INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass);
|
||||
INITIALIZE_PASS_END(
|
||||
ScopInfoPrinterLegacyFunctionPass, "polly-print-function-scops",
|
||||
"Polly - Print polyhedral description of all Scops of a function", false,
|
||||
false)
|
||||
|
||||
@@ -24,42 +24,6 @@
|
||||
using namespace llvm;
|
||||
using namespace polly;
|
||||
|
||||
bool ScopPass::runOnRegion(Region *R, RGPassManager &RGM) {
|
||||
S = nullptr;
|
||||
|
||||
if (skipRegion(*R))
|
||||
return false;
|
||||
|
||||
if ((S = getAnalysis<ScopInfoRegionPass>().getScop()))
|
||||
return runOnScop(*S);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScopPass::print(raw_ostream &OS, const Module *M) const {
|
||||
if (S)
|
||||
printScop(OS, *S);
|
||||
}
|
||||
|
||||
void ScopPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<ScopInfoRegionPass>();
|
||||
|
||||
AU.addPreserved<AAResultsWrapperPass>();
|
||||
AU.addPreserved<BasicAAWrapperPass>();
|
||||
AU.addPreserved<LoopInfoWrapperPass>();
|
||||
AU.addPreserved<DominatorTreeWrapperPass>();
|
||||
AU.addPreserved<GlobalsAAWrapperPass>();
|
||||
AU.addPreserved<ScopDetectionWrapperPass>();
|
||||
AU.addPreserved<ScalarEvolutionWrapperPass>();
|
||||
AU.addPreserved<SCEVAAWrapperPass>();
|
||||
AU.addPreserved<OptimizationRemarkEmitterWrapperPass>();
|
||||
AU.addPreserved<LazyBlockFrequencyInfoPass>();
|
||||
AU.addPreserved<LazyBranchProbabilityInfoPass>();
|
||||
AU.addPreserved<RegionInfoPass>();
|
||||
AU.addPreserved<ScopInfoRegionPass>();
|
||||
AU.addPreserved<TargetTransformInfoWrapperPass>();
|
||||
}
|
||||
|
||||
namespace polly {
|
||||
template class OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,9 @@ add_llvm_pass_plugin(Polly
|
||||
CodeGen/RuntimeDebugBuilder.cpp
|
||||
CodeGen/PerfMonitor.cpp
|
||||
Exchange/JSONExporter.cpp
|
||||
Pass/PhaseManager.cpp
|
||||
Pass/PollyFunctionPass.cpp
|
||||
Pass/PollyModulePass.cpp
|
||||
Support/GICHelper.cpp
|
||||
Support/PollyDebug.cpp
|
||||
Support/SCEVAffinator.cpp
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "polly/CodeGen/PerfMonitor.h"
|
||||
#include "polly/CodeGen/Utils.h"
|
||||
#include "polly/DependenceInfo.h"
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/Options.h"
|
||||
#include "polly/ScopInfo.h"
|
||||
#include "polly/Support/ScopHelper.h"
|
||||
@@ -37,7 +36,6 @@
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/InitializePasses.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@@ -320,59 +318,6 @@ static bool generateCode(Scop &S, IslAstInfo &AI, LoopInfo &LI,
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class CodeGeneration final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
/// The data layout used.
|
||||
const DataLayout *DL;
|
||||
|
||||
/// @name The analysis passes we need to generate code.
|
||||
///
|
||||
///{
|
||||
LoopInfo *LI;
|
||||
IslAstInfo *AI;
|
||||
DominatorTree *DT;
|
||||
ScalarEvolution *SE;
|
||||
RegionInfo *RI;
|
||||
///}
|
||||
|
||||
CodeGeneration() : ScopPass(ID) {}
|
||||
|
||||
/// Generate LLVM-IR for the SCoP @p S.
|
||||
bool runOnScop(Scop &S) override {
|
||||
AI = &getAnalysis<IslAstInfoWrapperPass>().getAI();
|
||||
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||
DL = &S.getFunction().getDataLayout();
|
||||
RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
|
||||
return generateCode(S, *AI, *LI, *DT, *SE, *RI);
|
||||
}
|
||||
|
||||
/// Register all analyses and transformation required.
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequired<IslAstInfoWrapperPass>();
|
||||
AU.addRequired<RegionInfoPass>();
|
||||
AU.addRequired<ScalarEvolutionWrapperPass>();
|
||||
AU.addRequired<ScopDetectionWrapperPass>();
|
||||
AU.addRequired<ScopInfoRegionPass>();
|
||||
AU.addRequired<LoopInfoWrapperPass>();
|
||||
|
||||
AU.addPreserved<DependenceInfo>();
|
||||
AU.addPreserved<IslAstInfoWrapperPass>();
|
||||
|
||||
// FIXME: We do not yet add regions for the newly generated code to the
|
||||
// region tree.
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
PreservedAnalyses CodeGenerationPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &AR,
|
||||
SPMUpdater &U) {
|
||||
@@ -385,17 +330,6 @@ PreservedAnalyses CodeGenerationPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
char CodeGeneration::ID = 1;
|
||||
|
||||
Pass *polly::createCodeGenerationPass() { return new CodeGeneration(); }
|
||||
|
||||
INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen",
|
||||
"Polly - Create LLVM-IR from SCoPs", false, false);
|
||||
INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass);
|
||||
INITIALIZE_PASS_END(CodeGeneration, "polly-codegen",
|
||||
"Polly - Create LLVM-IR from SCoPs", false, false)
|
||||
bool polly::runCodeGeneration(Scop &S, RegionInfo &RI, IslAstInfo &AI) {
|
||||
return generateCode(S, AI, *S.getLI(), *S.getDT(), *S.getSE(), RI);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "polly/CodeGen/IslAst.h"
|
||||
#include "polly/CodeGen/CodeGeneration.h"
|
||||
#include "polly/DependenceInfo.h"
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/Options.h"
|
||||
#include "polly/ScopDetection.h"
|
||||
#include "polly/ScopInfo.h"
|
||||
@@ -83,6 +82,11 @@ static cl::opt<bool> DetectParallel("polly-ast-detect-parallel",
|
||||
cl::desc("Detect parallelism"), cl::Hidden,
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PollyPrintAst("polly-print-ast",
|
||||
cl::desc("Print the ISL abstract syntax tree"),
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
STATISTIC(ScopsProcessed, "Number of SCoPs processed");
|
||||
STATISTIC(ScopsBeneficial, "Number of beneficial SCoPs");
|
||||
STATISTIC(BeneficialAffineLoops, "Number of beneficial affine loops");
|
||||
@@ -776,90 +780,19 @@ PreservedAnalyses IslAstPrinterPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
void IslAstInfoWrapperPass::releaseMemory() { Ast.reset(); }
|
||||
|
||||
bool IslAstInfoWrapperPass::runOnScop(Scop &Scop) {
|
||||
auto GetDeps = [this](Dependences::AnalysisLevel Lvl) -> const Dependences & {
|
||||
return getAnalysis<DependenceInfo>().getDependences(Lvl);
|
||||
std::unique_ptr<IslAstInfo>
|
||||
polly::runIslAstGen(Scop &S, DependenceAnalysis::Result &DA) {
|
||||
auto GetDeps = [&](Dependences::AnalysisLevel Lvl) -> const Dependences & {
|
||||
return DA.getDependences(Lvl);
|
||||
};
|
||||
|
||||
Ast = runIslAst(Scop, GetDeps);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void IslAstInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
// Get the Common analysis usage of ScopPasses.
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
AU.addRequiredTransitive<ScopInfoRegionPass>();
|
||||
AU.addRequired<DependenceInfo>();
|
||||
|
||||
AU.addPreserved<DependenceInfo>();
|
||||
}
|
||||
|
||||
void IslAstInfoWrapperPass::printScop(raw_ostream &OS, Scop &S) const {
|
||||
OS << "Printing analysis 'Polly - Generate an AST of the SCoP (isl)'"
|
||||
<< S.getName() << "' in function '" << S.getFunction().getName() << "':\n";
|
||||
if (Ast)
|
||||
Ast->print(OS);
|
||||
}
|
||||
|
||||
char IslAstInfoWrapperPass::ID = 0;
|
||||
|
||||
Pass *polly::createIslAstInfoWrapperPassPass() {
|
||||
return new IslAstInfoWrapperPass();
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(IslAstInfoWrapperPass, "polly-ast",
|
||||
"Polly - Generate an AST of the SCoP (isl)", false,
|
||||
false);
|
||||
INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
|
||||
INITIALIZE_PASS_END(IslAstInfoWrapperPass, "polly-ast",
|
||||
"Polly - Generate an AST from the SCoP (isl)", false, false)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
/// Print result from IslAstInfoWrapperPass.
|
||||
class IslAstInfoPrinterLegacyPass final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
IslAstInfoPrinterLegacyPass() : IslAstInfoPrinterLegacyPass(outs()) {}
|
||||
explicit IslAstInfoPrinterLegacyPass(llvm::raw_ostream &OS)
|
||||
: ScopPass(ID), OS(OS) {}
|
||||
|
||||
bool runOnScop(Scop &S) override {
|
||||
IslAstInfoWrapperPass &P = getAnalysis<IslAstInfoWrapperPass>();
|
||||
|
||||
OS << "Printing analysis '" << P.getPassName() << "' for region: '"
|
||||
<< S.getRegion().getNameStr() << "' in function '"
|
||||
<< S.getFunction().getName() << "':\n";
|
||||
P.printScop(OS, S);
|
||||
|
||||
return false;
|
||||
std::unique_ptr<IslAstInfo> Result = runIslAst(S, GetDeps);
|
||||
if (PollyPrintAst) {
|
||||
outs() << "Printing analysis 'Polly - Generate an AST of the SCoP (isl)'"
|
||||
<< S.getName() << "' in function '" << S.getFunction().getName()
|
||||
<< "':\n";
|
||||
if (Result)
|
||||
Result->print(llvm::outs());
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<IslAstInfoWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
char IslAstInfoPrinterLegacyPass::ID = 0;
|
||||
} // namespace
|
||||
|
||||
Pass *polly::createIslAstInfoPrinterLegacyPass(raw_ostream &OS) {
|
||||
return new IslAstInfoPrinterLegacyPass(OS);
|
||||
return Result;
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(IslAstInfoPrinterLegacyPass, "polly-print-ast",
|
||||
"Polly - Print the AST from a SCoP (isl)", false, false);
|
||||
INITIALIZE_PASS_DEPENDENCY(IslAstInfoWrapperPass);
|
||||
INITIALIZE_PASS_END(IslAstInfoPrinterLegacyPass, "polly-print-ast",
|
||||
"Polly - Print the AST from a SCoP (isl)", false, false)
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
#include "polly/JSONExporter.h"
|
||||
#include "polly/DependenceInfo.h"
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/Options.h"
|
||||
#include "polly/ScopInfo.h"
|
||||
#include "polly/ScopPass.h"
|
||||
@@ -36,6 +35,11 @@ using namespace polly;
|
||||
|
||||
#define DEBUG_TYPE "polly-import-jscop"
|
||||
|
||||
static cl::opt<bool>
|
||||
PollyPrintImportJscop("polly-print-import-jscop",
|
||||
cl::desc("Polly - Print Scop import result"),
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
STATISTIC(NewAccessMapFound, "Number of updated access functions");
|
||||
|
||||
namespace {
|
||||
@@ -50,36 +54,6 @@ static cl::opt<std::string>
|
||||
cl::desc("Postfix to append to the import .jsop files."),
|
||||
cl::Hidden, cl::value_desc("File postfix"), cl::ValueRequired,
|
||||
cl::init(""), cl::cat(PollyCategory));
|
||||
|
||||
class JSONExporter : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
explicit JSONExporter() : ScopPass(ID) {}
|
||||
|
||||
/// Export the SCoP @p S to a JSON file.
|
||||
bool runOnScop(Scop &S) override;
|
||||
|
||||
/// Print the SCoP @p S as it is exported.
|
||||
void printScop(raw_ostream &OS, Scop &S) const override;
|
||||
|
||||
/// Register all analyses and transformation required.
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
};
|
||||
|
||||
class JSONImporter : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
std::vector<std::string> NewAccessStrings;
|
||||
explicit JSONImporter() : ScopPass(ID) {}
|
||||
/// Import new access functions for SCoP @p S from a JSON file.
|
||||
bool runOnScop(Scop &S) override;
|
||||
|
||||
/// Print the SCoP @p S and the imported access functions.
|
||||
void printScop(raw_ostream &OS, Scop &S) const override;
|
||||
|
||||
/// Register all analyses and transformation required.
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
static std::string getFileName(Scop &S, StringRef Suffix = "") {
|
||||
@@ -742,21 +716,6 @@ static bool importScop(Scop &S, const Dependences &D, const DataLayout &DL,
|
||||
return true;
|
||||
}
|
||||
|
||||
char JSONExporter::ID = 0;
|
||||
void JSONExporter::printScop(raw_ostream &OS, Scop &S) const { OS << S; }
|
||||
|
||||
bool JSONExporter::runOnScop(Scop &S) {
|
||||
exportScop(S);
|
||||
return false;
|
||||
}
|
||||
|
||||
void JSONExporter::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
AU.addRequired<ScopInfoRegionPass>();
|
||||
}
|
||||
|
||||
Pass *polly::createJSONExporterPass() { return new JSONExporter(); }
|
||||
|
||||
PreservedAnalyses JSONExportPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &SAR,
|
||||
SPMUpdater &) {
|
||||
@@ -764,37 +723,6 @@ PreservedAnalyses JSONExportPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
char JSONImporter::ID = 0;
|
||||
|
||||
void JSONImporter::printScop(raw_ostream &OS, Scop &S) const {
|
||||
OS << S;
|
||||
for (std::vector<std::string>::const_iterator I = NewAccessStrings.begin(),
|
||||
E = NewAccessStrings.end();
|
||||
I != E; I++)
|
||||
OS << "New access function '" << *I << "' detected in JSCOP file\n";
|
||||
}
|
||||
|
||||
bool JSONImporter::runOnScop(Scop &S) {
|
||||
const Dependences &D =
|
||||
getAnalysis<DependenceInfo>().getDependences(Dependences::AL_Statement);
|
||||
const DataLayout &DL = S.getFunction().getParent()->getDataLayout();
|
||||
|
||||
if (!importScop(S, D, DL, &NewAccessStrings))
|
||||
report_fatal_error("Tried to import a malformed jscop file.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void JSONImporter::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<DependenceInfo>();
|
||||
|
||||
// TODO: JSONImporter should throw away DependenceInfo.
|
||||
AU.addPreserved<DependenceInfo>();
|
||||
}
|
||||
|
||||
Pass *polly::createJSONImporterPass() { return new JSONImporter(); }
|
||||
|
||||
PreservedAnalyses JSONImportPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &SAR,
|
||||
SPMUpdater &) {
|
||||
@@ -814,68 +742,24 @@ PreservedAnalyses JSONImportPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
return PA;
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(JSONExporter, "polly-export-jscop",
|
||||
"Polly - Export Scops as JSON"
|
||||
" (Writes a .jscop file for each Scop)",
|
||||
false, false);
|
||||
INITIALIZE_PASS_DEPENDENCY(DependenceInfo)
|
||||
INITIALIZE_PASS_END(JSONExporter, "polly-export-jscop",
|
||||
"Polly - Export Scops as JSON"
|
||||
" (Writes a .jscop file for each Scop)",
|
||||
false, false)
|
||||
void polly::runImportJSON(Scop &S, DependenceAnalysis::Result &DA) {
|
||||
const Dependences &D = DA.getDependences(Dependences::AL_Statement);
|
||||
const DataLayout &DL = S.getFunction().getParent()->getDataLayout();
|
||||
std::vector<std::string> NewAccessStrings;
|
||||
if (!importScop(S, D, DL, &NewAccessStrings))
|
||||
report_fatal_error("Tried to import a malformed jscop file.");
|
||||
|
||||
INITIALIZE_PASS_BEGIN(JSONImporter, "polly-import-jscop",
|
||||
"Polly - Import Scops from JSON"
|
||||
" (Reads a .jscop file for each Scop)",
|
||||
false, false);
|
||||
INITIALIZE_PASS_DEPENDENCY(DependenceInfo)
|
||||
INITIALIZE_PASS_END(JSONImporter, "polly-import-jscop",
|
||||
"Polly - Import Scops from JSON"
|
||||
" (Reads a .jscop file for each Scop)",
|
||||
false, false)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
/// Print result from JSONImporter.
|
||||
class JSONImporterPrinterLegacyPass final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
JSONImporterPrinterLegacyPass() : JSONImporterPrinterLegacyPass(outs()) {}
|
||||
explicit JSONImporterPrinterLegacyPass(llvm::raw_ostream &OS)
|
||||
: ScopPass(ID), OS(OS) {}
|
||||
|
||||
bool runOnScop(Scop &S) override {
|
||||
JSONImporter &P = getAnalysis<JSONImporter>();
|
||||
|
||||
OS << "Printing analysis '" << P.getPassName() << "' for region: '"
|
||||
<< S.getRegion().getNameStr() << "' in function '"
|
||||
<< S.getFunction().getName() << "':\n";
|
||||
P.printScop(OS, S);
|
||||
|
||||
return false;
|
||||
if (PollyPrintImportJscop) {
|
||||
outs()
|
||||
<< "Printing analysis 'Polly - Print Scop import result' for region: '"
|
||||
<< S.getRegion().getNameStr() << "' in function '"
|
||||
<< S.getFunction().getName() << "':\n";
|
||||
outs() << S;
|
||||
for (std::vector<std::string>::const_iterator I = NewAccessStrings.begin(),
|
||||
E = NewAccessStrings.end();
|
||||
I != E; I++)
|
||||
outs() << "New access function '" << *I << "' detected in JSCOP file\n";
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<JSONImporter>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
char JSONImporterPrinterLegacyPass::ID = 0;
|
||||
} // namespace
|
||||
|
||||
Pass *polly::createJSONImporterPrinterLegacyPass(llvm::raw_ostream &OS) {
|
||||
return new JSONImporterPrinterLegacyPass(OS);
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(JSONImporterPrinterLegacyPass, "polly-print-import-jscop",
|
||||
"Polly - Print Scop import result", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(JSONImporter)
|
||||
INITIALIZE_PASS_END(JSONImporterPrinterLegacyPass, "polly-print-import-jscop",
|
||||
"Polly - Print Scop import result", false, false)
|
||||
void polly::runExportJSON(Scop &S) { exportScop(S); }
|
||||
|
||||
432
polly/lib/Pass/PhaseManager.cpp
Normal file
432
polly/lib/Pass/PhaseManager.cpp
Normal file
@@ -0,0 +1,432 @@
|
||||
//===------ PhaseManager.cpp ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "polly/Pass/PhaseManager.h"
|
||||
#include "polly/CodeGen/CodeGeneration.h"
|
||||
#include "polly/CodeGen/IslAst.h"
|
||||
#include "polly/CodePreparation.h"
|
||||
#include "polly/DeLICM.h"
|
||||
#include "polly/DeadCodeElimination.h"
|
||||
#include "polly/DependenceInfo.h"
|
||||
#include "polly/FlattenSchedule.h"
|
||||
#include "polly/ForwardOpTree.h"
|
||||
#include "polly/JSONExporter.h"
|
||||
#include "polly/MaximalStaticExpansion.h"
|
||||
#include "polly/PruneUnprofitable.h"
|
||||
#include "polly/ScheduleOptimizer.h"
|
||||
#include "polly/ScopDetection.h"
|
||||
#include "polly/ScopDetectionDiagnostic.h"
|
||||
#include "polly/ScopGraphPrinter.h"
|
||||
#include "polly/ScopInfo.h"
|
||||
#include "polly/Simplify.h"
|
||||
#include "polly/Support/PollyDebug.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
|
||||
#define DEBUG_TYPE "polly-pass"
|
||||
|
||||
using namespace polly;
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
/// Recurse through all subregions and all regions and add them to RQ.
|
||||
static void addRegionIntoQueue(Region &R, SmallVector<Region *> &RQ) {
|
||||
RQ.push_back(&R);
|
||||
for (const auto &E : R)
|
||||
addRegionIntoQueue(*E, RQ);
|
||||
}
|
||||
|
||||
/// The phase pipeline of Polly to be embedded into another pass manager than
|
||||
/// runs passes on functions.
|
||||
///
|
||||
/// Polly holds state besides LLVM-IR (RegionInfo and ScopInfo) between phases
|
||||
/// that LLVM pass managers do not consider when scheduling analyses and passes.
|
||||
/// That is, the ScopInfo must persist between phases that a pass manager must
|
||||
/// not invalidate to recompute later.
|
||||
class PhaseManager {
|
||||
private:
|
||||
Function &F;
|
||||
FunctionAnalysisManager &FAM;
|
||||
PollyPassOptions Opts;
|
||||
|
||||
public:
|
||||
PhaseManager(Function &F, FunctionAnalysisManager &FAM, PollyPassOptions Opts)
|
||||
: F(F), FAM(FAM), Opts(std::move(Opts)) {}
|
||||
|
||||
/// Execute Polly's phases as indicated by the options.
|
||||
bool run() {
|
||||
// Get analyses from the function pass manager.
|
||||
// These must be preserved during all phases so that if processing one SCoP
|
||||
// has finished, the next SCoP can still use them. Recomputing is not an
|
||||
// option because ScopDetection stores references to the old results.
|
||||
// TODO: CodePreparation doesn't actually need these analysis, it just keeps
|
||||
// them up-to-date. If they are not computed yet, can also compute after the
|
||||
// prepare phase.
|
||||
LoopInfo &LI = FAM.getResult<LoopAnalysis>(F);
|
||||
DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
|
||||
bool ModifiedIR = false;
|
||||
|
||||
// Phase: prepare
|
||||
// TODO: Setting ModifiedIR will invalidate any analysis, even if DT, LI are
|
||||
// preserved.
|
||||
if (Opts.isPhaseEnabled(PassPhase::Prepare)) {
|
||||
PreservedAnalyses PA = CodePreparationPass().run(F, FAM);
|
||||
FAM.invalidate(F, PA);
|
||||
if (!PA.areAllPreserved())
|
||||
ModifiedIR = true;
|
||||
}
|
||||
|
||||
// Can't do anything without detection
|
||||
if (!Opts.isPhaseEnabled(PassPhase::Detection))
|
||||
return false;
|
||||
|
||||
AAResults &AA = FAM.getResult<AAManager>(F);
|
||||
ScalarEvolution &SE = FAM.getResult<ScalarEvolutionAnalysis>(F);
|
||||
OptimizationRemarkEmitter &ORE =
|
||||
FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
|
||||
|
||||
// ScopDetection is modifying RegionInfo, do not cache it, nor use a cached
|
||||
// version.
|
||||
RegionInfo RI = RegionInfoAnalysis().run(F, FAM);
|
||||
|
||||
// Phase: detection
|
||||
ScopDetection SD(DT, SE, LI, RI, AA, ORE);
|
||||
SD.detect(F);
|
||||
if (Opts.isPhaseEnabled(PassPhase::PrintDetect)) {
|
||||
outs() << "Detected Scops in Function " << F.getName() << "\n";
|
||||
for (const Region *R : SD.ValidRegions)
|
||||
outs() << "Valid Region for Scop: " << R->getNameStr() << '\n';
|
||||
outs() << "\n";
|
||||
}
|
||||
|
||||
if (Opts.isPhaseEnabled(PassPhase::DotScops))
|
||||
printGraphForFunction(F, &SD, "scops", false);
|
||||
if (Opts.isPhaseEnabled(PassPhase::DotScopsOnly))
|
||||
printGraphForFunction(F, &SD, "scopsonly", true);
|
||||
|
||||
auto ViewScops = [&](const char *Name, bool IsSimply) {
|
||||
if (Opts.ViewFilter.empty() && !F.getName().count(Opts.ViewFilter))
|
||||
return;
|
||||
|
||||
if (Opts.ViewAll || std::distance(SD.begin(), SD.end()) > 0)
|
||||
viewGraphForFunction(F, &SD, Name, IsSimply);
|
||||
};
|
||||
if (Opts.isPhaseEnabled(PassPhase::ViewScops))
|
||||
ViewScops("scops", false);
|
||||
if (Opts.isPhaseEnabled(PassPhase::ViewScopsOnly))
|
||||
ViewScops("scopsonly", true);
|
||||
|
||||
// Phase: scops
|
||||
AssumptionCache &AC = FAM.getResult<AssumptionAnalysis>(F);
|
||||
const DataLayout &DL = F.getParent()->getDataLayout();
|
||||
ScopInfo Info(DL, SD, SE, LI, AA, DT, AC, ORE);
|
||||
if (Opts.isPhaseEnabled(PassPhase::PrintScopInfo)) {
|
||||
if (Region *TLR = RI.getTopLevelRegion()) {
|
||||
SmallVector<Region *> Regions;
|
||||
addRegionIntoQueue(*TLR, Regions);
|
||||
|
||||
// reverse iteration because the regression tests expect it.
|
||||
for (Region *R : reverse(Regions)) {
|
||||
Scop *S = Info.getScop(R);
|
||||
outs() << "Printing analysis 'Polly - Create polyhedral "
|
||||
"description of Scops' for region: '"
|
||||
<< R->getNameStr() << "' in function '" << F.getName()
|
||||
<< "':\n";
|
||||
if (S)
|
||||
outs() << *S;
|
||||
else
|
||||
outs() << "Invalid Scop!\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SmallPriorityWorklist<Region *, 4> Worklist;
|
||||
for (auto &[R, S] : Info)
|
||||
if (S)
|
||||
Worklist.insert(R);
|
||||
|
||||
TargetTransformInfo &TTI = FAM.getResult<TargetIRAnalysis>(F);
|
||||
while (!Worklist.empty()) {
|
||||
Region *R = Worklist.pop_back_val();
|
||||
Scop *S = Info.getScop(R);
|
||||
if (!S) {
|
||||
// This can happen if codegenning of a previous SCoP made this region
|
||||
// not-a-SCoP anymore.
|
||||
POLLY_DEBUG(dbgs() << "SCoP in Region '" << *R << "' disappeared");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!SD.isMaxRegionInScop(*R, /*Verify=*/false))
|
||||
continue;
|
||||
|
||||
// Phase: flatten
|
||||
if (Opts.isPhaseEnabled(PassPhase::Flatten))
|
||||
runFlattenSchedulePass(*S);
|
||||
|
||||
// Phase: deps
|
||||
// Actual analysis runs on-demand, so it does not matter whether the phase
|
||||
// is actually enabled, but use this location to print dependencies.
|
||||
DependenceAnalysis::Result DA = runDependenceAnalysis(*S);
|
||||
if (Opts.isPhaseEnabled(PassPhase::PrintDependences)) {
|
||||
assert(Opts.isPhaseEnabled(PassPhase::Dependences));
|
||||
const Dependences &D = DA.getDependences(Opts.PrintDepsAnalysisLevel);
|
||||
D.print(outs());
|
||||
}
|
||||
|
||||
// Phase: import-jscop
|
||||
if (Opts.isPhaseEnabled(PassPhase::ImportJScop))
|
||||
runImportJSON(*S, DA);
|
||||
|
||||
// Phase: simplify-0
|
||||
bool ModifiedSinceSimplify = true;
|
||||
if (Opts.isPhaseEnabled(PassPhase::Simplify0)) {
|
||||
runSimplify(*S, 0);
|
||||
ModifiedSinceSimplify = false;
|
||||
}
|
||||
|
||||
// Phase: optree
|
||||
if (Opts.isPhaseEnabled(PassPhase::Optree)) {
|
||||
bool ModifiedByOptree = runForwardOpTree(*S);
|
||||
ModifiedSinceSimplify |= ModifiedByOptree;
|
||||
}
|
||||
|
||||
// Phase: delicm
|
||||
if (Opts.isPhaseEnabled(PassPhase::DeLICM)) {
|
||||
bool ModifiedByDelicm = runDeLICM(*S);
|
||||
ModifiedSinceSimplify |= ModifiedByDelicm;
|
||||
}
|
||||
|
||||
// Phase: simplify-1
|
||||
// If we have already run simplify-0, do not re-run it if the SCoP has not
|
||||
// changed since then.
|
||||
if (ModifiedSinceSimplify && Opts.isPhaseEnabled(PassPhase::Simplify1)) {
|
||||
runSimplify(*S, 1);
|
||||
ModifiedSinceSimplify = false;
|
||||
}
|
||||
|
||||
// Phase: dce
|
||||
if (Opts.isPhaseEnabled(PassPhase::DeadCodeElimination))
|
||||
runDeadCodeElim(*S, DA);
|
||||
|
||||
// Phase: mse
|
||||
if (Opts.isPhaseEnabled(PassPhase::MaximumStaticExtension))
|
||||
runMaximalStaticExpansion(*S, DA);
|
||||
|
||||
// Phase: prune
|
||||
if (Opts.isPhaseEnabled(PassPhase::PruneUnprofitable))
|
||||
runPruneUnprofitable(*S);
|
||||
|
||||
// Phase: opt-isl
|
||||
if (Opts.isPhaseEnabled(PassPhase::Optimization))
|
||||
runIslScheduleOptimizer(*S, &TTI, DA);
|
||||
|
||||
// Phase: import-jscop
|
||||
if (Opts.isPhaseEnabled(PassPhase::ExportJScop))
|
||||
runExportJSON(*S);
|
||||
|
||||
// Phase: ast
|
||||
// Cannot run codegen unless ast is enabled
|
||||
if (!Opts.isPhaseEnabled(PassPhase::AstGen))
|
||||
continue;
|
||||
std::unique_ptr<IslAstInfo> IslAst = runIslAstGen(*S, DA);
|
||||
|
||||
// Phase: codegen
|
||||
if (!Opts.isPhaseEnabled(PassPhase::CodeGen))
|
||||
continue;
|
||||
bool ModifiedByCodeGen = runCodeGeneration(*S, RI, *IslAst);
|
||||
if (ModifiedByCodeGen) {
|
||||
ModifiedIR = true;
|
||||
|
||||
// For all regions, create new polly::Scop objects because the old ones
|
||||
// refere to invalidated LLVM-IR.
|
||||
// FIXME: Adds all SCoPs again to statistics
|
||||
Info.recompute();
|
||||
}
|
||||
}
|
||||
|
||||
return ModifiedIR;
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
StringRef polly::getPhaseName(PassPhase Phase) {
|
||||
switch (Phase) {
|
||||
case PassPhase::Prepare:
|
||||
return "prepare";
|
||||
case PassPhase::Detection:
|
||||
return "detect";
|
||||
case PassPhase::PrintDetect:
|
||||
return "print-detect";
|
||||
case PassPhase::DotScops:
|
||||
return "dot-scops";
|
||||
case PassPhase::DotScopsOnly:
|
||||
return "dot-scops-only";
|
||||
case PassPhase::ViewScops:
|
||||
return "view-scops";
|
||||
case PassPhase::ViewScopsOnly:
|
||||
return "view-scops-only";
|
||||
case PassPhase::ScopInfo:
|
||||
return "scops";
|
||||
case PassPhase::PrintScopInfo:
|
||||
return "print-scops";
|
||||
case PassPhase::Flatten:
|
||||
return "flatten";
|
||||
case PassPhase::Dependences:
|
||||
return "deps";
|
||||
case PassPhase::PrintDependences:
|
||||
return "print-deps";
|
||||
case PassPhase::ImportJScop:
|
||||
return "import-jscop";
|
||||
case PassPhase::Simplify0:
|
||||
return "simplify-0";
|
||||
case PassPhase::Optree:
|
||||
return "optree";
|
||||
case PassPhase::DeLICM:
|
||||
return "delicm";
|
||||
case PassPhase::Simplify1:
|
||||
return "simplify-1";
|
||||
case PassPhase::DeadCodeElimination:
|
||||
return "dce";
|
||||
case PassPhase::MaximumStaticExtension:
|
||||
return "mse";
|
||||
case PassPhase::PruneUnprofitable:
|
||||
return "prune";
|
||||
case PassPhase::Optimization:
|
||||
return "opt-isl"; // "opt" would conflict with the llvm executable
|
||||
case PassPhase::ExportJScop:
|
||||
return "export-jscop";
|
||||
case PassPhase::AstGen:
|
||||
return "ast";
|
||||
case PassPhase::CodeGen:
|
||||
return "codegen";
|
||||
default:
|
||||
llvm_unreachable("Unexpected phase");
|
||||
}
|
||||
}
|
||||
|
||||
PassPhase polly::parsePhase(StringRef Name) {
|
||||
return StringSwitch<PassPhase>(Name)
|
||||
.Case("prepare", PassPhase::Prepare)
|
||||
.Case("detect", PassPhase::Detection)
|
||||
.Case("print-detect", PassPhase::PrintDetect)
|
||||
.Case("dot-scops", PassPhase::DotScops)
|
||||
.Case("dot-scops-only", PassPhase::DotScopsOnly)
|
||||
.Case("view-scops", PassPhase::ViewScops)
|
||||
.Case("view-scops-only", PassPhase::ViewScopsOnly)
|
||||
.Case("scops", PassPhase::ScopInfo)
|
||||
.Case("print-scops", PassPhase::PrintScopInfo)
|
||||
.Case("flatten", PassPhase::Flatten)
|
||||
.Case("deps", PassPhase::Dependences)
|
||||
.Case("print-deps", PassPhase::PrintDependences)
|
||||
.Case("import-jscop", PassPhase::ImportJScop)
|
||||
.Case("simplify-0", PassPhase::Simplify0)
|
||||
.Case("optree", PassPhase::Optree)
|
||||
.Case("delicm", PassPhase::DeLICM)
|
||||
.Case("simplify-1", PassPhase::Simplify1)
|
||||
.Case("dce", PassPhase::DeadCodeElimination)
|
||||
.Case("mse", PassPhase::MaximumStaticExtension)
|
||||
.Case("prune", PassPhase::PruneUnprofitable)
|
||||
.Case("opt-isl", PassPhase::Optimization)
|
||||
.Case("export-jscop", PassPhase::ExportJScop)
|
||||
.Case("ast", PassPhase::AstGen)
|
||||
.Case("codegen", PassPhase::CodeGen)
|
||||
.Default(PassPhase::None);
|
||||
}
|
||||
|
||||
bool polly::dependsOnDependenceInfo(PassPhase Phase) {
|
||||
// Nothing before dep phase can depend on it
|
||||
if (static_cast<size_t>(Phase) <= static_cast<size_t>(PassPhase::Dependences))
|
||||
return false;
|
||||
|
||||
switch (Phase) {
|
||||
case PassPhase::Simplify0:
|
||||
case PassPhase::Optree:
|
||||
case PassPhase::DeLICM:
|
||||
case PassPhase::Simplify1:
|
||||
case PassPhase::PruneUnprofitable:
|
||||
case PassPhase::ImportJScop:
|
||||
case PassPhase::ExportJScop:
|
||||
case PassPhase::AstGen: // transitively through codegen
|
||||
case PassPhase::CodeGen:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void PollyPassOptions::enableEnd2End() {
|
||||
setPhaseEnabled(PassPhase::Detection);
|
||||
setPhaseEnabled(PassPhase::ScopInfo);
|
||||
setPhaseEnabled(PassPhase::Dependences);
|
||||
setPhaseEnabled(PassPhase::AstGen);
|
||||
setPhaseEnabled(PassPhase::CodeGen);
|
||||
}
|
||||
|
||||
void PollyPassOptions::enableDefaultOpts() {
|
||||
setPhaseEnabled(PassPhase::Prepare);
|
||||
setPhaseEnabled(PassPhase::Simplify0);
|
||||
setPhaseEnabled(PassPhase::Optree);
|
||||
setPhaseEnabled(PassPhase::DeLICM);
|
||||
setPhaseEnabled(PassPhase::Simplify1);
|
||||
setPhaseEnabled(PassPhase::PruneUnprofitable);
|
||||
setPhaseEnabled(PassPhase::Optimization);
|
||||
}
|
||||
|
||||
void PollyPassOptions::disableAfter(PassPhase Phase) {
|
||||
assert(Phase != PassPhase::None);
|
||||
for (PassPhase P : enum_seq_inclusive(Phase, PassPhase::PassPhaseLast)) {
|
||||
if (P == Phase)
|
||||
continue;
|
||||
setPhaseEnabled(P, false);
|
||||
}
|
||||
}
|
||||
|
||||
Error PollyPassOptions::checkConsistency() const {
|
||||
for (PassPhase P : enum_seq_inclusive(PassPhase::PassPhaseFirst,
|
||||
PassPhase::PassPhaseLast)) {
|
||||
if (!isPhaseEnabled(P))
|
||||
continue;
|
||||
|
||||
// Prepare and Detection have no requirements
|
||||
if (P == PassPhase::Prepare || P == PassPhase::Detection)
|
||||
continue;
|
||||
|
||||
if (!isPhaseEnabled(PassPhase::Detection))
|
||||
return make_error<StringError>(
|
||||
formatv("'{0}' requires 'detect' to be enabled", getPhaseName(P))
|
||||
.str(),
|
||||
inconvertibleErrorCode());
|
||||
|
||||
if (static_cast<size_t>(P) < static_cast<size_t>(PassPhase::ScopInfo))
|
||||
continue;
|
||||
|
||||
if (!isPhaseEnabled(PassPhase::ScopInfo))
|
||||
return make_error<StringError>(
|
||||
formatv("'{0}' requires 'scops' to be enabled", getPhaseName(P))
|
||||
.str(),
|
||||
inconvertibleErrorCode());
|
||||
|
||||
if (dependsOnDependenceInfo(P) && !isPhaseEnabled(PassPhase::Dependences))
|
||||
return make_error<StringError>(
|
||||
formatv("'{0}' requires 'deps' to be enabled", getPhaseName(P)).str(),
|
||||
inconvertibleErrorCode());
|
||||
}
|
||||
|
||||
if (isPhaseEnabled(PassPhase::CodeGen) && !isPhaseEnabled(PassPhase::AstGen))
|
||||
return make_error<StringError>("'codegen' requires 'ast' to be enabled",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
bool polly::runPollyPass(Function &F, FunctionAnalysisManager &FAM,
|
||||
PollyPassOptions Opts) {
|
||||
return PhaseManager(F, FAM, std::move(Opts)).run();
|
||||
}
|
||||
22
polly/lib/Pass/PollyFunctionPass.cpp
Normal file
22
polly/lib/Pass/PollyFunctionPass.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
//===------ PollyFunctionPass.cpp - Polly function pass ------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "polly/Pass/PollyFunctionPass.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace polly;
|
||||
|
||||
PreservedAnalyses PollyFunctionPass::run(llvm::Function &F,
|
||||
llvm::FunctionAnalysisManager &FAM) {
|
||||
bool ModifiedIR = runPollyPass(F, FAM, Opts);
|
||||
|
||||
// Be conservative about preserved analyses.
|
||||
// FIXME: May also need to invalidate/update Module/CGSCC passes, but cannot
|
||||
// reach them within a FunctionPassManager.
|
||||
return ModifiedIR ? PreservedAnalyses::none() : PreservedAnalyses::all();
|
||||
}
|
||||
29
polly/lib/Pass/PollyModulePass.cpp
Normal file
29
polly/lib/Pass/PollyModulePass.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
//===------ PollyModulePass.cpp - Polly module pass ----------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "polly/Pass/PollyModulePass.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace polly;
|
||||
|
||||
PreservedAnalyses PollyModulePass::run(llvm::Module &M,
|
||||
llvm::ModuleAnalysisManager &MAM) {
|
||||
FunctionAnalysisManager &FAM =
|
||||
MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
|
||||
|
||||
bool ModifiedAnyIR = false;
|
||||
for (Function &F : M) {
|
||||
bool LocalModifiedIR = runPollyPass(F, FAM, Opts);
|
||||
ModifiedAnyIR |= LocalModifiedIR;
|
||||
}
|
||||
|
||||
// Be conservative about preserved analyses, especially if parallel functions
|
||||
// have been outlined.
|
||||
return ModifiedAnyIR ? PreservedAnalyses::none() : PreservedAnalyses::all();
|
||||
}
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "polly/Support/DumpFunctionPass.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassInstrumentation.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
@@ -82,50 +81,10 @@ static void runDumpFunction(llvm::Function &F, StringRef Suffix) {
|
||||
Out->keep();
|
||||
LLVM_DEBUG(dbgs() << "Dump file " << Dumpfile << " written successfully\n");
|
||||
}
|
||||
|
||||
class DumpFunctionWrapperPass final : public FunctionPass {
|
||||
private:
|
||||
DumpFunctionWrapperPass(const DumpFunctionWrapperPass &) = delete;
|
||||
const DumpFunctionWrapperPass &
|
||||
operator=(const DumpFunctionWrapperPass &) = delete;
|
||||
|
||||
std::string Suffix;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
explicit DumpFunctionWrapperPass() : FunctionPass(ID), Suffix("-dump") {}
|
||||
|
||||
explicit DumpFunctionWrapperPass(std::string Suffix)
|
||||
: FunctionPass(ID), Suffix(std::move(Suffix)) {}
|
||||
|
||||
/// @name FunctionPass interface
|
||||
//@{
|
||||
void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
bool runOnFunction(llvm::Function &F) override {
|
||||
runDumpFunction(F, Suffix);
|
||||
return false;
|
||||
}
|
||||
//@}
|
||||
};
|
||||
|
||||
char DumpFunctionWrapperPass::ID;
|
||||
} // namespace
|
||||
|
||||
FunctionPass *polly::createDumpFunctionWrapperPass(std::string Suffix) {
|
||||
return new DumpFunctionWrapperPass(std::move(Suffix));
|
||||
}
|
||||
|
||||
llvm::PreservedAnalyses DumpFunctionPass::run(Function &F,
|
||||
FunctionAnalysisManager &AM) {
|
||||
runDumpFunction(F, Suffix);
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(DumpFunctionWrapperPass, "polly-dump-function",
|
||||
"Polly - Dump Function", false, false)
|
||||
INITIALIZE_PASS_END(DumpFunctionWrapperPass, "polly-dump-function",
|
||||
"Polly - Dump Function", false, false)
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
#include "polly/Support/DumpModulePass.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
@@ -47,56 +46,10 @@ static void runDumpModule(llvm::Module &M, StringRef Filename, bool IsSuffix) {
|
||||
M.print(Out->os(), nullptr);
|
||||
Out->keep();
|
||||
}
|
||||
|
||||
class DumpModuleWrapperPass final : public ModulePass {
|
||||
private:
|
||||
DumpModuleWrapperPass(const DumpModuleWrapperPass &) = delete;
|
||||
const DumpModuleWrapperPass &
|
||||
operator=(const DumpModuleWrapperPass &) = delete;
|
||||
|
||||
std::string Filename;
|
||||
bool IsSuffix;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
/// This constructor is used e.g. if using opt -polly-dump-module.
|
||||
///
|
||||
/// Provide a default suffix to not overwrite the original file.
|
||||
explicit DumpModuleWrapperPass()
|
||||
: ModulePass(ID), Filename("-dump"), IsSuffix(true) {}
|
||||
|
||||
explicit DumpModuleWrapperPass(std::string Filename, bool IsSuffix)
|
||||
: ModulePass(ID), Filename(std::move(Filename)), IsSuffix(IsSuffix) {}
|
||||
|
||||
/// @name ModulePass interface
|
||||
//@{
|
||||
void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
bool runOnModule(llvm::Module &M) override {
|
||||
runDumpModule(M, Filename, IsSuffix);
|
||||
return false;
|
||||
}
|
||||
//@}
|
||||
};
|
||||
|
||||
char DumpModuleWrapperPass::ID;
|
||||
} // namespace
|
||||
|
||||
ModulePass *polly::createDumpModuleWrapperPass(std::string Filename,
|
||||
bool IsSuffix) {
|
||||
return new DumpModuleWrapperPass(std::move(Filename), IsSuffix);
|
||||
}
|
||||
|
||||
llvm::PreservedAnalyses DumpModulePass::run(llvm::Module &M,
|
||||
llvm::ModuleAnalysisManager &AM) {
|
||||
runDumpModule(M, Filename, IsSuffix);
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(DumpModuleWrapperPass, "polly-dump-module",
|
||||
"Polly - Dump Module", false, false)
|
||||
INITIALIZE_PASS_END(DumpModuleWrapperPass, "polly-dump-module",
|
||||
"Polly - Dump Module", false, false)
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef MODULE_PASS
|
||||
#define MODULE_PASS(NAME, CREATE_PASS, PARSER)
|
||||
#endif
|
||||
MODULE_PASS("polly", createModuleToFunctionPassAdaptor(PollyFunctionPass(Opts)), parsePollyDefaultOptions)
|
||||
MODULE_PASS("polly-custom", createModuleToFunctionPassAdaptor(PollyFunctionPass(Opts)), parsePollyCustomOptions)
|
||||
#undef MODULE_PASS
|
||||
|
||||
#ifndef CGSCC_PASS
|
||||
#define CGSCC_PASS(NAME, CREATE_PASS, PARSER)
|
||||
#endif
|
||||
@@ -12,15 +19,17 @@ FUNCTION_ANALYSIS("polly-function-scops", ScopInfoAnalysis())
|
||||
#undef FUNCTION_ANALYSIS
|
||||
|
||||
#ifndef FUNCTION_PASS
|
||||
#define FUNCTION_PASS(NAME, CREATE_PASS)
|
||||
#define FUNCTION_PASS(NAME, CREATE_PASS, PARSER)
|
||||
#endif
|
||||
FUNCTION_PASS("polly-prepare", CodePreparationPass())
|
||||
FUNCTION_PASS("print<polly-detect>", ScopAnalysisPrinterPass(llvm::errs()))
|
||||
FUNCTION_PASS("print<polly-function-scops>", ScopInfoPrinterPass(llvm::errs()))
|
||||
FUNCTION_PASS("polly-scop-viewer", ScopViewer())
|
||||
FUNCTION_PASS("polly-scop-only-viewer", ScopOnlyViewer())
|
||||
FUNCTION_PASS("polly-scop-printer", ScopPrinter())
|
||||
FUNCTION_PASS("polly-scop-only-printer", ScopOnlyPrinter())
|
||||
FUNCTION_PASS("polly-prepare", CodePreparationPass(), parseNoOptions)
|
||||
FUNCTION_PASS("print<polly-detect>", ScopAnalysisPrinterPass(llvm::errs()), parseNoOptions)
|
||||
FUNCTION_PASS("print<polly-function-scops>", ScopInfoPrinterPass(llvm::errs()), parseNoOptions)
|
||||
FUNCTION_PASS("polly-scop-viewer", ScopViewer(), parseNoOptions)
|
||||
FUNCTION_PASS("polly-scop-only-viewer", ScopOnlyViewer(), parseNoOptions)
|
||||
FUNCTION_PASS("polly-scop-printer", ScopPrinter(), parseNoOptions)
|
||||
FUNCTION_PASS("polly-scop-only-printer", ScopOnlyPrinter(), parseNoOptions)
|
||||
FUNCTION_PASS("polly", PollyFunctionPass(Opts), parsePollyDefaultOptions)
|
||||
FUNCTION_PASS("polly-custom", PollyFunctionPass(Opts), parsePollyCustomOptions)
|
||||
#undef FUNCTION_PASS
|
||||
|
||||
#ifndef SCOP_ANALYSIS
|
||||
|
||||
@@ -28,8 +28,9 @@
|
||||
#include "polly/DependenceInfo.h"
|
||||
#include "polly/ForwardOpTree.h"
|
||||
#include "polly/JSONExporter.h"
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/MaximalStaticExpansion.h"
|
||||
#include "polly/Options.h"
|
||||
#include "polly/Pass/PollyFunctionPass.h"
|
||||
#include "polly/PruneUnprofitable.h"
|
||||
#include "polly/ScheduleOptimizer.h"
|
||||
#include "polly/ScopDetection.h"
|
||||
@@ -52,6 +53,8 @@
|
||||
#include "llvm/Transforms/IPO.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace polly;
|
||||
|
||||
namespace cl = llvm::cl;
|
||||
using namespace polly;
|
||||
|
||||
@@ -201,58 +204,19 @@ static cl::opt<bool> EnablePruneUnprofitable(
|
||||
cl::desc("Bail out on unprofitable SCoPs before rescheduling"), cl::Hidden,
|
||||
cl::init(true), cl::cat(PollyCategory));
|
||||
|
||||
namespace {
|
||||
static cl::opt<bool>
|
||||
PollyPrintDetect("polly-print-detect",
|
||||
cl::desc("Polly - Print static control parts (SCoPs)"),
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
/// Initialize Polly passes when library is loaded.
|
||||
///
|
||||
/// We use the constructor of a statically declared object to initialize the
|
||||
/// different Polly passes right after the Polly library is loaded. This ensures
|
||||
/// that the Polly passes are available e.g. in the 'opt' tool.
|
||||
struct StaticInitializer {
|
||||
StaticInitializer() {
|
||||
llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
|
||||
polly::initializePollyPasses(Registry);
|
||||
}
|
||||
};
|
||||
static StaticInitializer InitializeEverything;
|
||||
} // end of anonymous namespace.
|
||||
static cl::opt<bool>
|
||||
PollyPrintScops("polly-print-scops",
|
||||
cl::desc("Print polyhedral description of all regions"),
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
void initializePollyPasses(llvm::PassRegistry &Registry) {
|
||||
initializeCodeGenerationPass(Registry);
|
||||
|
||||
initializeCodePreparationPass(Registry);
|
||||
initializeDeadCodeElimWrapperPassPass(Registry);
|
||||
initializeDependenceInfoPass(Registry);
|
||||
initializeDependenceInfoPrinterLegacyPassPass(Registry);
|
||||
initializeDependenceInfoWrapperPassPass(Registry);
|
||||
initializeDependenceInfoPrinterLegacyFunctionPassPass(Registry);
|
||||
initializeJSONExporterPass(Registry);
|
||||
initializeJSONImporterPass(Registry);
|
||||
initializeJSONImporterPrinterLegacyPassPass(Registry);
|
||||
initializeMaximalStaticExpanderWrapperPassPass(Registry);
|
||||
initializeIslAstInfoWrapperPassPass(Registry);
|
||||
initializeIslAstInfoPrinterLegacyPassPass(Registry);
|
||||
initializeIslScheduleOptimizerWrapperPassPass(Registry);
|
||||
initializeIslScheduleOptimizerPrinterLegacyPassPass(Registry);
|
||||
initializePollyCanonicalizePass(Registry);
|
||||
initializeScopDetectionWrapperPassPass(Registry);
|
||||
initializeScopDetectionPrinterLegacyPassPass(Registry);
|
||||
initializeScopInlinerWrapperPassPass(Registry);
|
||||
initializeScopInfoRegionPassPass(Registry);
|
||||
initializeScopInfoPrinterLegacyRegionPassPass(Registry);
|
||||
initializeScopInfoWrapperPassPass(Registry);
|
||||
initializeScopInfoPrinterLegacyFunctionPassPass(Registry);
|
||||
initializeFlattenSchedulePass(Registry);
|
||||
initializeFlattenSchedulePrinterLegacyPassPass(Registry);
|
||||
initializeForwardOpTreeWrapperPassPass(Registry);
|
||||
initializeForwardOpTreePrinterLegacyPassPass(Registry);
|
||||
initializeDeLICMWrapperPassPass(Registry);
|
||||
initializeDeLICMPrinterLegacyPassPass(Registry);
|
||||
initializeSimplifyWrapperPassPass(Registry);
|
||||
initializeSimplifyPrinterLegacyPassPass(Registry);
|
||||
initializeDumpModuleWrapperPassPass(Registry);
|
||||
initializePruneUnprofitableWrapperPassPass(Registry);
|
||||
}
|
||||
static cl::opt<bool> PollyPrintDeps("polly-print-deps",
|
||||
cl::desc("Polly - Print dependences"),
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
static bool shouldEnablePollyForOptimization() { return PollyEnabled; }
|
||||
|
||||
@@ -266,6 +230,198 @@ static bool shouldEnablePollyForDiagnostic() {
|
||||
ExportJScop;
|
||||
}
|
||||
|
||||
/// Parser of parameters for LoopVectorize pass.
|
||||
static llvm::Expected<PollyPassOptions> parsePollyOptions(StringRef Params,
|
||||
bool IsCustom) {
|
||||
PassPhase PrevPhase = PassPhase::None;
|
||||
|
||||
bool EnableDefaultOpts = !IsCustom;
|
||||
bool EnableEnd2End = !IsCustom;
|
||||
std::optional<bool>
|
||||
PassEnabled[static_cast<size_t>(PassPhase::PassPhaseLast) + 1];
|
||||
PassPhase StopAfter = PassPhase::None;
|
||||
|
||||
// Passes enabled using command-line flags (can be overridden using
|
||||
// 'polly<no-pass>')
|
||||
if (PollyPrintDetect)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::PrintDetect)] = true;
|
||||
if (PollyPrintScops)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::PrintScopInfo)] = true;
|
||||
if (PollyPrintDeps)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::PrintDependences)] = true;
|
||||
|
||||
if (PollyViewer)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::ViewScops)] = true;
|
||||
if (PollyOnlyViewer)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::ViewScopsOnly)] = true;
|
||||
if (PollyPrinter)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::DotScops)] = true;
|
||||
if (PollyOnlyPrinter)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::DotScopsOnly)] = true;
|
||||
if (!EnableSimplify)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::Simplify0)] = false;
|
||||
if (!EnableForwardOpTree)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::Optree)] = false;
|
||||
if (!EnableDeLICM)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::DeLICM)] = false;
|
||||
if (!EnableSimplify)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::Simplify1)] = false;
|
||||
if (ImportJScop)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::ImportJScop)] = true;
|
||||
if (DeadCodeElim)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::DeadCodeElimination)] = true;
|
||||
if (FullyIndexedStaticExpansion)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::MaximumStaticExtension)] = true;
|
||||
if (!EnablePruneUnprofitable)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::PruneUnprofitable)] = false;
|
||||
switch (Optimizer) {
|
||||
case OPTIMIZER_NONE:
|
||||
// explicitly switched off
|
||||
PassEnabled[static_cast<size_t>(PassPhase::Optimization)] = false;
|
||||
break;
|
||||
case OPTIMIZER_ISL:
|
||||
// default: enabled
|
||||
break;
|
||||
}
|
||||
if (ExportJScop)
|
||||
PassEnabled[static_cast<size_t>(PassPhase::ExportJScop)] = true;
|
||||
switch (CodeGeneration) {
|
||||
case CODEGEN_AST:
|
||||
PassEnabled[static_cast<size_t>(PassPhase::AstGen)] = true;
|
||||
PassEnabled[static_cast<size_t>(PassPhase::CodeGen)] = false;
|
||||
break;
|
||||
case CODEGEN_FULL:
|
||||
// default: ast and codegen enabled
|
||||
break;
|
||||
case CODEGEN_NONE:
|
||||
PassEnabled[static_cast<size_t>(PassPhase::AstGen)] = false;
|
||||
PassEnabled[static_cast<size_t>(PassPhase::CodeGen)] = false;
|
||||
break;
|
||||
}
|
||||
|
||||
while (!Params.empty()) {
|
||||
StringRef Param;
|
||||
std::tie(Param, Params) = Params.split(';');
|
||||
auto [ParamName, ParamVal] = Param.split('=');
|
||||
|
||||
if (ParamName == "stopafter") {
|
||||
StopAfter = parsePhase(ParamVal);
|
||||
if (StopAfter == PassPhase::None)
|
||||
return make_error<StringError>(
|
||||
formatv("invalid stopafter parameter value '{0}'", ParamVal).str(),
|
||||
inconvertibleErrorCode());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ParamVal.empty())
|
||||
return make_error<StringError>(
|
||||
formatv("parameter '{0}' does not take value", ParamName).str(),
|
||||
inconvertibleErrorCode());
|
||||
|
||||
bool Enabled = true;
|
||||
if (ParamName.starts_with("no-")) {
|
||||
Enabled = false;
|
||||
ParamName = ParamName.drop_front(3);
|
||||
}
|
||||
|
||||
if (ParamName == "default-opts") {
|
||||
EnableDefaultOpts = Enabled;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ParamName == "end2end") {
|
||||
EnableEnd2End = Enabled;
|
||||
continue;
|
||||
}
|
||||
|
||||
PassPhase Phase;
|
||||
|
||||
// Shortcut for both simplifys at the same time
|
||||
if (ParamName == "simplify") {
|
||||
PassEnabled[static_cast<size_t>(PassPhase::Simplify0)] = Enabled;
|
||||
PassEnabled[static_cast<size_t>(PassPhase::Simplify1)] = Enabled;
|
||||
Phase = PassPhase::Simplify0;
|
||||
} else {
|
||||
Phase = parsePhase(ParamName);
|
||||
if (Phase == PassPhase::None)
|
||||
return make_error<StringError>(
|
||||
formatv("invalid Polly parameter/phase name '{0}'", ParamName)
|
||||
.str(),
|
||||
inconvertibleErrorCode());
|
||||
|
||||
if (PrevPhase >= Phase)
|
||||
return make_error<StringError>(
|
||||
formatv("phases must not be repeated and enumerated in-order: "
|
||||
"'{0}' listed before '{1}'",
|
||||
getPhaseName(PrevPhase), getPhaseName(Phase))
|
||||
.str(),
|
||||
inconvertibleErrorCode());
|
||||
|
||||
PassEnabled[static_cast<size_t>(Phase)] = Enabled;
|
||||
}
|
||||
PrevPhase = Phase;
|
||||
}
|
||||
|
||||
PollyPassOptions Opts;
|
||||
Opts.ViewAll = ViewAll;
|
||||
Opts.ViewFilter = ViewFilter;
|
||||
Opts.PrintDepsAnalysisLevel = OptAnalysisLevel;
|
||||
|
||||
// Implicitly enable dependent phases first. May be overriden explicitly
|
||||
// on/off later.
|
||||
for (PassPhase P : llvm::enum_seq_inclusive(PassPhase::PassPhaseFirst,
|
||||
PassPhase::PassPhaseLast)) {
|
||||
bool Enabled = PassEnabled[static_cast<size_t>(P)].value_or(false);
|
||||
if (!Enabled)
|
||||
continue;
|
||||
|
||||
if (static_cast<size_t>(PassPhase::Detection) < static_cast<size_t>(P))
|
||||
Opts.setPhaseEnabled(PassPhase::Detection);
|
||||
|
||||
if (static_cast<size_t>(PassPhase::ScopInfo) < static_cast<size_t>(P))
|
||||
Opts.setPhaseEnabled(PassPhase::ScopInfo);
|
||||
|
||||
if (dependsOnDependenceInfo(P))
|
||||
Opts.setPhaseEnabled(PassPhase::Dependences);
|
||||
|
||||
if (static_cast<size_t>(PassPhase::AstGen) < static_cast<size_t>(P))
|
||||
Opts.setPhaseEnabled(PassPhase::AstGen);
|
||||
}
|
||||
|
||||
if (EnableEnd2End)
|
||||
Opts.enableEnd2End();
|
||||
|
||||
if (EnableDefaultOpts)
|
||||
Opts.enableDefaultOpts();
|
||||
|
||||
for (PassPhase P : llvm::enum_seq_inclusive(PassPhase::PassPhaseFirst,
|
||||
PassPhase::PassPhaseLast)) {
|
||||
std::optional<bool> Enabled = PassEnabled[static_cast<size_t>(P)];
|
||||
|
||||
// Apply only if set explicitly.
|
||||
if (Enabled.has_value())
|
||||
Opts.setPhaseEnabled(P, *Enabled);
|
||||
}
|
||||
|
||||
if (StopAfter != PassPhase::None)
|
||||
Opts.disableAfter(StopAfter);
|
||||
|
||||
if (Error CheckResult = Opts.checkConsistency())
|
||||
return CheckResult;
|
||||
|
||||
return Opts;
|
||||
}
|
||||
|
||||
static llvm::Expected<PollyPassOptions>
|
||||
parsePollyDefaultOptions(StringRef Params) {
|
||||
return parsePollyOptions(Params, false);
|
||||
}
|
||||
|
||||
static llvm::Expected<PollyPassOptions>
|
||||
parsePollyCustomOptions(StringRef Params) {
|
||||
return parsePollyOptions(Params, true);
|
||||
}
|
||||
|
||||
/// Register Polly passes such that they form a polyhedral optimizer.
|
||||
///
|
||||
/// The individual Polly passes are registered in the pass manager such that
|
||||
@@ -305,77 +461,12 @@ static void buildCommonPollyPipeline(FunctionPassManager &PM,
|
||||
OptimizationLevel Level,
|
||||
bool EnableForOpt) {
|
||||
PassBuilder PB;
|
||||
ScopPassManager SPM;
|
||||
|
||||
PM.addPass(CodePreparationPass());
|
||||
ExitOnError Err("Inconsistent Polly configuration: ");
|
||||
PollyPassOptions &&Opts =
|
||||
Err(parsePollyOptions(StringRef(), /*IsCustom=*/false));
|
||||
PM.addPass(PollyFunctionPass(Opts));
|
||||
|
||||
// TODO add utility passes for the various command line options, once they're
|
||||
// ported
|
||||
|
||||
if (PollyDetectOnly) {
|
||||
// Don't add more passes other than the ScopPassManager's detection passes.
|
||||
PM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (PollyViewer)
|
||||
PM.addPass(ScopViewer());
|
||||
if (PollyOnlyViewer)
|
||||
PM.addPass(ScopOnlyViewer());
|
||||
if (PollyPrinter)
|
||||
PM.addPass(ScopPrinter());
|
||||
if (PollyOnlyPrinter)
|
||||
PM.addPass(ScopOnlyPrinter());
|
||||
if (EnableSimplify)
|
||||
SPM.addPass(SimplifyPass(0));
|
||||
if (EnableForwardOpTree)
|
||||
SPM.addPass(ForwardOpTreePass());
|
||||
if (EnableDeLICM)
|
||||
SPM.addPass(DeLICMPass());
|
||||
if (EnableSimplify)
|
||||
SPM.addPass(SimplifyPass(1));
|
||||
|
||||
if (ImportJScop)
|
||||
SPM.addPass(JSONImportPass());
|
||||
|
||||
if (DeadCodeElim)
|
||||
SPM.addPass(DeadCodeElimPass());
|
||||
|
||||
if (FullyIndexedStaticExpansion)
|
||||
SPM.addPass(MaximalStaticExpansionPass());
|
||||
|
||||
if (EnablePruneUnprofitable)
|
||||
SPM.addPass(PruneUnprofitablePass());
|
||||
|
||||
switch (Optimizer) {
|
||||
case OPTIMIZER_NONE:
|
||||
break; /* Do nothing */
|
||||
case OPTIMIZER_ISL:
|
||||
SPM.addPass(IslScheduleOptimizerPass());
|
||||
break;
|
||||
}
|
||||
|
||||
if (ExportJScop)
|
||||
SPM.addPass(JSONExportPass());
|
||||
|
||||
if (!EnableForOpt)
|
||||
return;
|
||||
|
||||
switch (CodeGeneration) {
|
||||
case CODEGEN_AST:
|
||||
SPM.addPass(
|
||||
llvm::RequireAnalysisPass<IslAstAnalysis, Scop, ScopAnalysisManager,
|
||||
ScopStandardAnalysisResults &,
|
||||
SPMUpdater &>());
|
||||
break;
|
||||
case CODEGEN_FULL:
|
||||
SPM.addPass(CodeGenerationPass());
|
||||
break;
|
||||
case CODEGEN_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
PM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
|
||||
PM.addPass(PB.buildFunctionSimplificationPipeline(
|
||||
Level, llvm::ThinOrFullLTOPhase::None)); // Cleanup
|
||||
|
||||
@@ -492,8 +583,9 @@ parseCGPipeline(StringRef Name, llvm::CGSCCPassManager &CGPM,
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
static llvm::Expected<bool>
|
||||
parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
|
||||
PassInstrumentationCallbacks *PIC,
|
||||
ArrayRef<PassBuilder::PipelineElement> Pipeline) {
|
||||
if (llvm::parseAnalysisUtilityPasses<OwningScopAnalysisManagerFunctionProxy>(
|
||||
"polly-scop-analyses", Name, FPM))
|
||||
@@ -505,8 +597,13 @@ parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
|
||||
FPM)) \
|
||||
return true;
|
||||
|
||||
#define FUNCTION_PASS(NAME, CREATE_PASS) \
|
||||
if (Name == NAME) { \
|
||||
#define FUNCTION_PASS(NAME, CREATE_PASS, PARSER) \
|
||||
if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
|
||||
auto ExpectedOpts = PassBuilder::parsePassParameters(PARSER, Name, NAME); \
|
||||
if (!ExpectedOpts) \
|
||||
return ExpectedOpts.takeError(); \
|
||||
auto &&Opts = *ExpectedOpts; \
|
||||
(void)Opts; \
|
||||
FPM.addPass(CREATE_PASS); \
|
||||
return true; \
|
||||
}
|
||||
@@ -592,6 +689,26 @@ parseTopLevelPipeline(llvm::ModulePassManager &MPM,
|
||||
return true;
|
||||
}
|
||||
|
||||
static llvm::Expected<bool>
|
||||
parseModulePipeline(StringRef Name, llvm::ModulePassManager &MPM,
|
||||
PassInstrumentationCallbacks *PIC,
|
||||
ArrayRef<PassBuilder::PipelineElement> Pipeline) {
|
||||
#define MODULE_PASS(NAME, CREATE_PASS, PARSER) \
|
||||
if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
|
||||
auto ExpectedOpts = PassBuilder::parsePassParameters(PARSER, Name, NAME); \
|
||||
if (!ExpectedOpts) \
|
||||
return ExpectedOpts.takeError(); \
|
||||
auto &&Opts = *ExpectedOpts; \
|
||||
(void)Opts; \
|
||||
MPM.addPass(CREATE_PASS); \
|
||||
return true; \
|
||||
}
|
||||
|
||||
#include "PollyPasses.def"
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Register Polly to be available as an optimizer
|
||||
///
|
||||
///
|
||||
@@ -620,10 +737,36 @@ parseTopLevelPipeline(llvm::ModulePassManager &MPM,
|
||||
/// handle LICMed code to make it useful.
|
||||
void registerPollyPasses(PassBuilder &PB) {
|
||||
PassInstrumentationCallbacks *PIC = PB.getPassInstrumentationCallbacks();
|
||||
|
||||
#define MODULE_PASS(NAME, CREATE_PASS, PARSER) \
|
||||
{ \
|
||||
std::remove_reference_t<decltype(*PARSER(StringRef()))> Opts; \
|
||||
(void)Opts; \
|
||||
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); \
|
||||
}
|
||||
#define CGSCC_PASS(NAME, CREATE_PASS, PARSER) \
|
||||
{ \
|
||||
std::remove_reference_t<decltype(*PARSER(StringRef()))> Opts; \
|
||||
(void)Opts; \
|
||||
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); \
|
||||
}
|
||||
#define FUNCTION_PASS(NAME, CREATE_PASS, PARSER) \
|
||||
{ \
|
||||
std::remove_reference_t<decltype(*PARSER(StringRef()))> Opts; \
|
||||
(void)Opts; \
|
||||
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); \
|
||||
}
|
||||
#include "PollyPasses.def"
|
||||
|
||||
PB.registerAnalysisRegistrationCallback([PIC](FunctionAnalysisManager &FAM) {
|
||||
registerFunctionAnalyses(FAM, PIC);
|
||||
});
|
||||
PB.registerPipelineParsingCallback(parseFunctionPipeline);
|
||||
PB.registerPipelineParsingCallback(
|
||||
[PIC](StringRef Name, FunctionPassManager &FPM,
|
||||
ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {
|
||||
ExitOnError Err("Unable to parse Polly module pass: ");
|
||||
return Err(parseFunctionPipeline(Name, FPM, PIC, Pipeline));
|
||||
});
|
||||
PB.registerPipelineParsingCallback(
|
||||
[PIC](StringRef Name, FunctionPassManager &FPM,
|
||||
ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {
|
||||
@@ -635,6 +778,12 @@ void registerPollyPasses(PassBuilder &PB) {
|
||||
ExitOnError Err("Unable to parse Polly call graph pass: ");
|
||||
return Err(parseCGPipeline(Name, CGPM, PIC, Pipeline));
|
||||
});
|
||||
PB.registerPipelineParsingCallback(
|
||||
[PIC](StringRef Name, ModulePassManager &MPM,
|
||||
ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {
|
||||
ExitOnError Err("Unable to parse Polly module pass: ");
|
||||
return Err(parseModulePipeline(Name, MPM, PIC, Pipeline));
|
||||
});
|
||||
PB.registerParseTopLevelPipelineCallback(
|
||||
[PIC](llvm::ModulePassManager &MPM,
|
||||
ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {
|
||||
|
||||
@@ -206,18 +206,6 @@ void polly::splitEntryBlockForAlloca(BasicBlock *EntryBlock, DominatorTree *DT,
|
||||
splitBlock(EntryBlock, I, DT, LI, RI);
|
||||
}
|
||||
|
||||
void polly::splitEntryBlockForAlloca(BasicBlock *EntryBlock, Pass *P) {
|
||||
auto *DTWP = P->getAnalysisIfAvailable<DominatorTreeWrapperPass>();
|
||||
auto *DT = DTWP ? &DTWP->getDomTree() : nullptr;
|
||||
auto *LIWP = P->getAnalysisIfAvailable<LoopInfoWrapperPass>();
|
||||
auto *LI = LIWP ? &LIWP->getLoopInfo() : nullptr;
|
||||
RegionInfoPass *RIP = P->getAnalysisIfAvailable<RegionInfoPass>();
|
||||
RegionInfo *RI = RIP ? &RIP->getRegionInfo() : nullptr;
|
||||
|
||||
// splitBlock updates DT, LI and RI.
|
||||
polly::splitEntryBlockForAlloca(EntryBlock, DT, LI, RI);
|
||||
}
|
||||
|
||||
void polly::recordAssumption(polly::RecordedAssumptionsTy *RecordedAssumptions,
|
||||
polly::AssumptionKind Kind, isl::set Set,
|
||||
DebugLoc Loc, polly::AssumptionSign Sign,
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "polly/Canonicalization.h"
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/Options.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
||||
@@ -39,24 +38,6 @@ static cl::opt<bool>
|
||||
cl::desc("Run an early inliner pass before Polly"), cl::Hidden,
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
void polly::registerCanonicalicationPasses(llvm::legacy::PassManagerBase &PM) {
|
||||
bool UseMemSSA = true;
|
||||
PM.add(llvm::createPromoteMemoryToRegisterPass());
|
||||
PM.add(llvm::createEarlyCSEPass(UseMemSSA));
|
||||
PM.add(llvm::createInstructionCombiningPass());
|
||||
PM.add(llvm::createCFGSimplificationPass());
|
||||
PM.add(llvm::createTailCallEliminationPass());
|
||||
PM.add(llvm::createCFGSimplificationPass());
|
||||
PM.add(llvm::createReassociatePass());
|
||||
if (PollyInliner) {
|
||||
PM.add(llvm::createPromoteMemoryToRegisterPass());
|
||||
PM.add(llvm::createCFGSimplificationPass());
|
||||
PM.add(llvm::createInstructionCombiningPass());
|
||||
PM.add(createBarrierNoopPass());
|
||||
}
|
||||
PM.add(llvm::createInstructionCombiningPass());
|
||||
}
|
||||
|
||||
/// Adapted from llvm::PassBuilder::buildInlinerPipeline
|
||||
static ModuleInlinerWrapperPass
|
||||
buildInlinePasses(llvm::OptimizationLevel Level) {
|
||||
@@ -125,49 +106,3 @@ polly::buildCanonicalicationPassesForNPM(llvm::ModulePassManager &MPM,
|
||||
|
||||
return FPM;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class PollyCanonicalize final : public ModulePass {
|
||||
PollyCanonicalize(const PollyCanonicalize &) = delete;
|
||||
const PollyCanonicalize &operator=(const PollyCanonicalize &) = delete;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
explicit PollyCanonicalize() : ModulePass(ID) {}
|
||||
~PollyCanonicalize();
|
||||
|
||||
/// @name FunctionPass interface.
|
||||
//@{
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
void releaseMemory() override;
|
||||
bool runOnModule(Module &M) override;
|
||||
void print(raw_ostream &OS, const Module *) const override;
|
||||
//@}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
PollyCanonicalize::~PollyCanonicalize() {}
|
||||
|
||||
void PollyCanonicalize::getAnalysisUsage(AnalysisUsage &AU) const {}
|
||||
|
||||
void PollyCanonicalize::releaseMemory() {}
|
||||
|
||||
bool PollyCanonicalize::runOnModule(Module &M) {
|
||||
legacy::PassManager PM;
|
||||
registerCanonicalicationPasses(PM);
|
||||
PM.run(M);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PollyCanonicalize::print(raw_ostream &OS, const Module *) const {}
|
||||
|
||||
char PollyCanonicalize::ID = 0;
|
||||
|
||||
Pass *polly::createPollyCanonicalizePass() { return new PollyCanonicalize(); }
|
||||
|
||||
INITIALIZE_PASS_BEGIN(PollyCanonicalize, "polly-canonicalize",
|
||||
"Polly - Run canonicalization passes", false, false)
|
||||
INITIALIZE_PASS_END(PollyCanonicalize, "polly-canonicalize",
|
||||
"Polly - Run canonicalization passes", false, false)
|
||||
|
||||
@@ -16,13 +16,11 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "polly/CodePreparation.h"
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/Support/ScopHelper.h"
|
||||
#include "llvm/Analysis/DominanceFrontier.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/RegionInfo.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/InitializePasses.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace polly;
|
||||
@@ -47,32 +45,6 @@ static bool runCodePreprationImpl(Function &F, DominatorTree *DT, LoopInfo *LI,
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// Prepare the IR for the scop detection.
|
||||
///
|
||||
class CodePreparation final : public FunctionPass {
|
||||
CodePreparation(const CodePreparation &) = delete;
|
||||
const CodePreparation &operator=(const CodePreparation &) = delete;
|
||||
|
||||
void clear();
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
explicit CodePreparation() : FunctionPass(ID) {}
|
||||
~CodePreparation();
|
||||
|
||||
/// @name FunctionPass interface.
|
||||
//@{
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
void releaseMemory() override;
|
||||
bool runOnFunction(Function &F) override;
|
||||
void print(raw_ostream &OS, const Module *) const override;
|
||||
//@}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
PreservedAnalyses CodePreparationPass::run(Function &F,
|
||||
FunctionAnalysisManager &FAM) {
|
||||
auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
|
||||
@@ -86,44 +58,3 @@ PreservedAnalyses CodePreparationPass::run(Function &F,
|
||||
PA.preserve<LoopAnalysis>();
|
||||
return PA;
|
||||
}
|
||||
|
||||
void CodePreparation::clear() {}
|
||||
|
||||
CodePreparation::~CodePreparation() { clear(); }
|
||||
|
||||
void CodePreparation::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<LoopInfoWrapperPass>();
|
||||
|
||||
AU.addPreserved<LoopInfoWrapperPass>();
|
||||
AU.addPreserved<RegionInfoPass>();
|
||||
AU.addPreserved<DominatorTreeWrapperPass>();
|
||||
AU.addPreserved<DominanceFrontierWrapperPass>();
|
||||
}
|
||||
|
||||
bool CodePreparation::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
return false;
|
||||
|
||||
DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
RegionInfo *RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
|
||||
|
||||
runCodePreprationImpl(F, DT, LI, RI);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CodePreparation::releaseMemory() { clear(); }
|
||||
|
||||
void CodePreparation::print(raw_ostream &OS, const Module *) const {}
|
||||
|
||||
char CodePreparation::ID = 0;
|
||||
char &polly::CodePreparationID = CodePreparation::ID;
|
||||
|
||||
Pass *polly::createCodePreparationPass() { return new CodePreparation(); }
|
||||
|
||||
INITIALIZE_PASS_BEGIN(CodePreparation, "polly-prepare",
|
||||
"Polly - Prepare code for polly", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(CodePreparation, "polly-prepare",
|
||||
"Polly - Prepare code for polly", false, false)
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "polly/DeLICM.h"
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/Options.h"
|
||||
#include "polly/ScopInfo.h"
|
||||
#include "polly/ScopPass.h"
|
||||
@@ -25,7 +24,6 @@
|
||||
#include "polly/ZoneAlgo.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/InitializePasses.h"
|
||||
|
||||
#include "polly/Support/PollyDebug.h"
|
||||
#define DEBUG_TYPE "polly-delicm"
|
||||
@@ -35,6 +33,10 @@ using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
static cl::opt<bool> PollyPrintDeLICM("polly-print-delicm",
|
||||
cl::desc("Polly - Print DeLICM/DePRE"),
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
cl::opt<int>
|
||||
DelicmMaxOps("polly-delicm-max-ops",
|
||||
cl::desc("Maximum number of isl operations to invest for "
|
||||
@@ -1356,7 +1358,10 @@ public:
|
||||
}
|
||||
|
||||
/// Return whether at least one transformation been applied.
|
||||
bool isModified() const { return NumberOfTargetsMapped > 0; }
|
||||
bool isModified() const {
|
||||
return NumberOfTargetsMapped > 0 || NumberOfMappedValueScalars > 0 ||
|
||||
NumberOfMappedPHIScalars > 0;
|
||||
}
|
||||
};
|
||||
|
||||
static std::unique_ptr<DeLICMImpl> collapseToUnused(Scop &S, LoopInfo &LI) {
|
||||
@@ -1376,7 +1381,7 @@ static std::unique_ptr<DeLICMImpl> collapseToUnused(Scop &S, LoopInfo &LI) {
|
||||
return Impl;
|
||||
}
|
||||
|
||||
static std::unique_ptr<DeLICMImpl> runDeLICM(Scop &S, LoopInfo &LI) {
|
||||
static std::unique_ptr<DeLICMImpl> runDeLICMImpl(Scop &S, LoopInfo &LI) {
|
||||
std::unique_ptr<DeLICMImpl> Impl = collapseToUnused(S, LI);
|
||||
|
||||
Scop::ScopStatistics ScopStats = S.getStatistics();
|
||||
@@ -1394,7 +1399,7 @@ 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);
|
||||
std::unique_ptr<DeLICMImpl> Impl = runDeLICMImpl(S, LI);
|
||||
|
||||
if (OS) {
|
||||
*OS << "Printing analysis 'Polly - DeLICM/DePRE' for region: '"
|
||||
@@ -1417,88 +1422,8 @@ static PreservedAnalyses runDeLICMUsingNPM(Scop &S, ScopAnalysisManager &SAM,
|
||||
PA.preserveSet<AllAnalysesOn<Loop>>();
|
||||
return PA;
|
||||
}
|
||||
|
||||
class DeLICMWrapperPass final : public ScopPass {
|
||||
private:
|
||||
DeLICMWrapperPass(const DeLICMWrapperPass &) = delete;
|
||||
const DeLICMWrapperPass &operator=(const DeLICMWrapperPass &) = delete;
|
||||
|
||||
/// The pass implementation, also holding per-scop data.
|
||||
std::unique_ptr<DeLICMImpl> Impl;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
explicit DeLICMWrapperPass() : ScopPass(ID) {}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequiredTransitive<ScopInfoRegionPass>();
|
||||
AU.addRequired<LoopInfoWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
bool runOnScop(Scop &S) override {
|
||||
// Free resources for previous scop's computation, if not yet done.
|
||||
releaseMemory();
|
||||
|
||||
auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
Impl = runDeLICM(S, LI);
|
||||
|
||||
return Impl->isModified();
|
||||
}
|
||||
|
||||
void printScop(raw_ostream &OS, Scop &S) const override {
|
||||
if (!Impl)
|
||||
return;
|
||||
assert(Impl->getScop() == &S);
|
||||
|
||||
OS << "DeLICM result:\n";
|
||||
Impl->print(OS);
|
||||
}
|
||||
|
||||
void releaseMemory() override { Impl.reset(); }
|
||||
};
|
||||
|
||||
char DeLICMWrapperPass::ID;
|
||||
|
||||
/// Print result from DeLICMWrapperPass.
|
||||
class DeLICMPrinterLegacyPass final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
DeLICMPrinterLegacyPass() : DeLICMPrinterLegacyPass(outs()) {}
|
||||
explicit DeLICMPrinterLegacyPass(llvm::raw_ostream &OS)
|
||||
: ScopPass(ID), OS(OS) {}
|
||||
|
||||
bool runOnScop(Scop &S) override {
|
||||
DeLICMWrapperPass &P = getAnalysis<DeLICMWrapperPass>();
|
||||
|
||||
OS << "Printing analysis '" << P.getPassName() << "' for region: '"
|
||||
<< S.getRegion().getNameStr() << "' in function '"
|
||||
<< S.getFunction().getName() << "':\n";
|
||||
P.printScop(OS, S);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<DeLICMWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
char DeLICMPrinterLegacyPass::ID = 0;
|
||||
} // anonymous namespace
|
||||
|
||||
Pass *polly::createDeLICMWrapperPass() { return new DeLICMWrapperPass(); }
|
||||
|
||||
llvm::Pass *polly::createDeLICMPrinterLegacyPass(llvm::raw_ostream &OS) {
|
||||
return new DeLICMPrinterLegacyPass(OS);
|
||||
}
|
||||
|
||||
llvm::PreservedAnalyses polly::DeLICMPass::run(Scop &S,
|
||||
ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &SAR,
|
||||
@@ -1527,15 +1452,21 @@ bool polly::isConflicting(
|
||||
return Knowledge::isConflicting(Existing, Proposed, OS, Indent);
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(DeLICMWrapperPass, "polly-delicm", "Polly - DeLICM/DePRE",
|
||||
false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(DeLICMWrapperPass, "polly-delicm", "Polly - DeLICM/DePRE",
|
||||
false, false)
|
||||
bool polly::runDeLICM(Scop &S) {
|
||||
LoopInfo &LI = *S.getLI();
|
||||
std::unique_ptr<DeLICMImpl> Impl = runDeLICMImpl(S, LI);
|
||||
|
||||
INITIALIZE_PASS_BEGIN(DeLICMPrinterLegacyPass, "polly-print-delicm",
|
||||
"Polly - Print DeLICM/DePRE", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(DeLICMPrinterLegacyPass, "polly-print-delicm",
|
||||
"Polly - Print DeLICM/DePRE", false, false)
|
||||
if (PollyPrintDeLICM) {
|
||||
outs() << "Printing analysis 'Polly - DeLICM/DePRE' for region: '"
|
||||
<< S.getName() << "' in function '" << S.getFunction().getName()
|
||||
<< "':\n";
|
||||
if (Impl) {
|
||||
assert(Impl->getScop() == &S);
|
||||
|
||||
outs() << "DeLICM result:\n";
|
||||
Impl->print(outs());
|
||||
}
|
||||
}
|
||||
|
||||
return Impl->isModified();
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
|
||||
#include "polly/DeadCodeElimination.h"
|
||||
#include "polly/DependenceInfo.h"
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/Options.h"
|
||||
#include "polly/ScopInfo.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
@@ -51,20 +50,6 @@ cl::opt<int> DCEPreciseSteps(
|
||||
"before the actual dead code elimination."),
|
||||
cl::init(-1), cl::cat(PollyCategory));
|
||||
|
||||
class DeadCodeElimWrapperPass final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
explicit DeadCodeElimWrapperPass() : ScopPass(ID) {}
|
||||
|
||||
/// Remove dead iterations from the schedule of @p S.
|
||||
bool runOnScop(Scop &S) override;
|
||||
|
||||
/// Register all analyses and transformation required.
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
};
|
||||
|
||||
char DeadCodeElimWrapperPass::ID = 0;
|
||||
|
||||
/// Return the set of live iterations.
|
||||
///
|
||||
/// The set of live iterations are all iterations that write to memory and for
|
||||
@@ -144,29 +129,19 @@ static bool runDeadCodeElimination(Scop &S, int PreciseSteps,
|
||||
return S.restrictDomains(Live);
|
||||
}
|
||||
|
||||
bool DeadCodeElimWrapperPass::runOnScop(Scop &S) {
|
||||
auto &DI = getAnalysis<DependenceInfo>();
|
||||
const Dependences &Deps = DI.getDependences(Dependences::AL_Statement);
|
||||
} // namespace
|
||||
|
||||
bool polly::runDeadCodeElim(Scop &S, DependenceAnalysis::Result &DA) {
|
||||
const Dependences &Deps = DA.getDependences(Dependences::AL_Statement);
|
||||
|
||||
bool Changed = runDeadCodeElimination(S, DCEPreciseSteps, Deps);
|
||||
|
||||
// FIXME: We can probably avoid the recomputation of all dependences by
|
||||
// updating them explicitly.
|
||||
if (Changed)
|
||||
DI.recomputeDependences(Dependences::AL_Statement);
|
||||
DA.recomputeDependences(Dependences::AL_Statement);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeadCodeElimWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<DependenceInfo>();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Pass *polly::createDeadCodeElimWrapperPass() {
|
||||
return new DeadCodeElimWrapperPass();
|
||||
return Changed;
|
||||
}
|
||||
|
||||
llvm::PreservedAnalyses DeadCodeElimPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
@@ -191,10 +166,3 @@ llvm::PreservedAnalyses DeadCodeElimPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
PA.preserveSet<AllAnalysesOn<Loop>>();
|
||||
return PA;
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(DeadCodeElimWrapperPass, "polly-dce",
|
||||
"Polly - Remove dead iterations", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(DependenceInfo)
|
||||
INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass)
|
||||
INITIALIZE_PASS_END(DeadCodeElimWrapperPass, "polly-dce",
|
||||
"Polly - Remove dead iterations", false, false)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "polly/FlattenSchedule.h"
|
||||
#include "polly/FlattenAlgo.h"
|
||||
#include "polly/Options.h"
|
||||
#include "polly/ScopInfo.h"
|
||||
#include "polly/ScopPass.h"
|
||||
#include "polly/Support/ISLOStream.h"
|
||||
@@ -26,6 +27,10 @@ using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
static cl::opt<bool> PollyPrintFlattenSchedule("polly-print-flatten-schedule",
|
||||
cl::desc("A polly pass"),
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
/// Print a schedule to @p OS.
|
||||
///
|
||||
/// Prints the schedule for each statements on a new line.
|
||||
@@ -34,119 +39,45 @@ void printSchedule(raw_ostream &OS, const isl::union_map &Schedule,
|
||||
for (isl::map Map : Schedule.get_map_list())
|
||||
OS.indent(indent) << Map << "\n";
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/// Flatten the schedule stored in an polly::Scop.
|
||||
class FlattenSchedule final : public ScopPass {
|
||||
private:
|
||||
FlattenSchedule(const FlattenSchedule &) = delete;
|
||||
const FlattenSchedule &operator=(const FlattenSchedule &) = delete;
|
||||
void polly::runFlattenSchedulePass(Scop &S) {
|
||||
// Keep a reference to isl_ctx to ensure that it is not freed before we free
|
||||
// OldSchedule.
|
||||
auto IslCtx = S.getSharedIslCtx();
|
||||
|
||||
std::shared_ptr<isl_ctx> IslCtx;
|
||||
isl::union_map OldSchedule;
|
||||
POLLY_DEBUG(dbgs() << "Going to flatten old schedule:\n");
|
||||
auto OldSchedule = S.getSchedule();
|
||||
POLLY_DEBUG(printSchedule(dbgs(), OldSchedule, 2));
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
explicit FlattenSchedule() : ScopPass(ID) {}
|
||||
auto Domains = S.getDomains();
|
||||
auto RestrictedOldSchedule = OldSchedule.intersect_domain(Domains);
|
||||
POLLY_DEBUG(dbgs() << "Old schedule with domains:\n");
|
||||
POLLY_DEBUG(printSchedule(dbgs(), RestrictedOldSchedule, 2));
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequiredTransitive<ScopInfoRegionPass>();
|
||||
AU.setPreservesAll();
|
||||
auto NewSchedule = flattenSchedule(RestrictedOldSchedule);
|
||||
|
||||
POLLY_DEBUG(dbgs() << "Flattened new schedule:\n");
|
||||
POLLY_DEBUG(printSchedule(dbgs(), NewSchedule, 2));
|
||||
|
||||
NewSchedule = NewSchedule.gist_domain(Domains);
|
||||
POLLY_DEBUG(dbgs() << "Gisted, flattened new schedule:\n");
|
||||
POLLY_DEBUG(printSchedule(dbgs(), NewSchedule, 2));
|
||||
|
||||
S.setSchedule(NewSchedule);
|
||||
|
||||
if (PollyPrintFlattenSchedule) {
|
||||
outs()
|
||||
<< "Printing analysis 'Polly - Print flattened schedule' for region: '"
|
||||
<< S.getRegion().getNameStr() << "' in function '"
|
||||
<< S.getFunction().getName() << "':\n";
|
||||
|
||||
outs() << "Schedule before flattening {\n";
|
||||
printSchedule(outs(), OldSchedule, 4);
|
||||
outs() << "}\n\n";
|
||||
|
||||
outs() << "Schedule after flattening {\n";
|
||||
printSchedule(outs(), S.getSchedule(), 4);
|
||||
outs() << "}\n";
|
||||
}
|
||||
|
||||
bool runOnScop(Scop &S) override {
|
||||
// Keep a reference to isl_ctx to ensure that it is not freed before we free
|
||||
// OldSchedule.
|
||||
IslCtx = S.getSharedIslCtx();
|
||||
|
||||
POLLY_DEBUG(dbgs() << "Going to flatten old schedule:\n");
|
||||
OldSchedule = S.getSchedule();
|
||||
POLLY_DEBUG(printSchedule(dbgs(), OldSchedule, 2));
|
||||
|
||||
auto Domains = S.getDomains();
|
||||
auto RestrictedOldSchedule = OldSchedule.intersect_domain(Domains);
|
||||
POLLY_DEBUG(dbgs() << "Old schedule with domains:\n");
|
||||
POLLY_DEBUG(printSchedule(dbgs(), RestrictedOldSchedule, 2));
|
||||
|
||||
auto NewSchedule = flattenSchedule(RestrictedOldSchedule);
|
||||
|
||||
POLLY_DEBUG(dbgs() << "Flattened new schedule:\n");
|
||||
POLLY_DEBUG(printSchedule(dbgs(), NewSchedule, 2));
|
||||
|
||||
NewSchedule = NewSchedule.gist_domain(Domains);
|
||||
POLLY_DEBUG(dbgs() << "Gisted, flattened new schedule:\n");
|
||||
POLLY_DEBUG(printSchedule(dbgs(), NewSchedule, 2));
|
||||
|
||||
S.setSchedule(NewSchedule);
|
||||
return false;
|
||||
}
|
||||
|
||||
void printScop(raw_ostream &OS, Scop &S) const override {
|
||||
OS << "Schedule before flattening {\n";
|
||||
printSchedule(OS, OldSchedule, 4);
|
||||
OS << "}\n\n";
|
||||
|
||||
OS << "Schedule after flattening {\n";
|
||||
printSchedule(OS, S.getSchedule(), 4);
|
||||
OS << "}\n";
|
||||
}
|
||||
|
||||
void releaseMemory() override {
|
||||
OldSchedule = {};
|
||||
IslCtx.reset();
|
||||
}
|
||||
};
|
||||
|
||||
char FlattenSchedule::ID;
|
||||
|
||||
/// Print result from FlattenSchedule.
|
||||
class FlattenSchedulePrinterLegacyPass final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
FlattenSchedulePrinterLegacyPass()
|
||||
: FlattenSchedulePrinterLegacyPass(outs()) {}
|
||||
explicit FlattenSchedulePrinterLegacyPass(llvm::raw_ostream &OS)
|
||||
: ScopPass(ID), OS(OS) {}
|
||||
|
||||
bool runOnScop(Scop &S) override {
|
||||
FlattenSchedule &P = getAnalysis<FlattenSchedule>();
|
||||
|
||||
OS << "Printing analysis '" << P.getPassName() << "' for region: '"
|
||||
<< S.getRegion().getNameStr() << "' in function '"
|
||||
<< S.getFunction().getName() << "':\n";
|
||||
P.printScop(OS, S);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<FlattenSchedule>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
char FlattenSchedulePrinterLegacyPass::ID = 0;
|
||||
} // anonymous namespace
|
||||
|
||||
Pass *polly::createFlattenSchedulePass() { return new FlattenSchedule(); }
|
||||
|
||||
Pass *polly::createFlattenSchedulePrinterLegacyPass(llvm::raw_ostream &OS) {
|
||||
return new FlattenSchedulePrinterLegacyPass(OS);
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(FlattenSchedule, "polly-flatten-schedule",
|
||||
"Polly - Flatten schedule", false, false)
|
||||
INITIALIZE_PASS_END(FlattenSchedule, "polly-flatten-schedule",
|
||||
"Polly - Flatten schedule", false, false)
|
||||
|
||||
INITIALIZE_PASS_BEGIN(FlattenSchedulePrinterLegacyPass,
|
||||
"polly-print-flatten-schedule",
|
||||
"Polly - Print flattened schedule", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(FlattenSchedule)
|
||||
INITIALIZE_PASS_END(FlattenSchedulePrinterLegacyPass,
|
||||
"polly-print-flatten-schedule",
|
||||
"Polly - Print flattened schedule", false, false)
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/InitializePasses.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
@@ -62,6 +61,11 @@ static cl::opt<unsigned>
|
||||
"analysis; 0=no limit"),
|
||||
cl::init(1000000), cl::cat(PollyCategory), cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PollyPrintOptree("polly-print-optree",
|
||||
cl::desc("Polly - Print forward operand tree result"),
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
STATISTIC(KnownAnalyzed, "Number of successfully analyzed SCoPs");
|
||||
STATISTIC(KnownOutOfQuota,
|
||||
"Analyses aborted because max_operations was reached");
|
||||
@@ -1030,8 +1034,8 @@ public:
|
||||
bool isModified() const { return Modified; }
|
||||
};
|
||||
|
||||
static std::unique_ptr<ForwardOpTreeImpl> runForwardOpTree(Scop &S,
|
||||
LoopInfo &LI) {
|
||||
static std::unique_ptr<ForwardOpTreeImpl> runForwardOpTreeImpl(Scop &S,
|
||||
LoopInfo &LI) {
|
||||
std::unique_ptr<ForwardOpTreeImpl> Impl;
|
||||
{
|
||||
IslMaxOperationsGuard MaxOpGuard(S.getIslCtx().get(), MaxOps, false);
|
||||
@@ -1073,7 +1077,7 @@ runForwardOpTreeUsingNPM(Scop &S, ScopAnalysisManager &SAM,
|
||||
raw_ostream *OS) {
|
||||
LoopInfo &LI = SAR.LI;
|
||||
|
||||
std::unique_ptr<ForwardOpTreeImpl> Impl = runForwardOpTree(S, LI);
|
||||
std::unique_ptr<ForwardOpTreeImpl> Impl = runForwardOpTreeImpl(S, LI);
|
||||
if (OS) {
|
||||
*OS << "Printing analysis 'Polly - Forward operand tree' for region: '"
|
||||
<< S.getName() << "' in function '" << S.getFunction().getName()
|
||||
@@ -1094,99 +1098,8 @@ runForwardOpTreeUsingNPM(Scop &S, ScopAnalysisManager &SAM,
|
||||
PA.preserveSet<AllAnalysesOn<Loop>>();
|
||||
return PA;
|
||||
}
|
||||
|
||||
/// 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.
|
||||
class ForwardOpTreeWrapperPass final : public ScopPass {
|
||||
private:
|
||||
/// The pass implementation, also holding per-scop data.
|
||||
std::unique_ptr<ForwardOpTreeImpl> Impl;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
explicit ForwardOpTreeWrapperPass() : ScopPass(ID) {}
|
||||
ForwardOpTreeWrapperPass(const ForwardOpTreeWrapperPass &) = delete;
|
||||
ForwardOpTreeWrapperPass &
|
||||
operator=(const ForwardOpTreeWrapperPass &) = delete;
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequiredTransitive<ScopInfoRegionPass>();
|
||||
AU.addRequired<LoopInfoWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
bool runOnScop(Scop &S) override {
|
||||
// Free resources for previous SCoP's computation, if not yet done.
|
||||
releaseMemory();
|
||||
|
||||
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
|
||||
Impl = runForwardOpTree(S, LI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void printScop(raw_ostream &OS, Scop &S) const override {
|
||||
if (!Impl)
|
||||
return;
|
||||
|
||||
assert(Impl->getScop() == &S);
|
||||
Impl->print(OS);
|
||||
}
|
||||
|
||||
void releaseMemory() override { Impl.reset(); }
|
||||
}; // class ForwardOpTree
|
||||
|
||||
char ForwardOpTreeWrapperPass::ID;
|
||||
|
||||
/// Print result from ForwardOpTreeWrapperPass.
|
||||
class ForwardOpTreePrinterLegacyPass final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
ForwardOpTreePrinterLegacyPass() : ForwardOpTreePrinterLegacyPass(outs()) {}
|
||||
explicit ForwardOpTreePrinterLegacyPass(llvm::raw_ostream &OS)
|
||||
: ScopPass(ID), OS(OS) {}
|
||||
|
||||
bool runOnScop(Scop &S) override {
|
||||
ForwardOpTreeWrapperPass &P = getAnalysis<ForwardOpTreeWrapperPass>();
|
||||
|
||||
OS << "Printing analysis '" << P.getPassName() << "' for region: '"
|
||||
<< S.getRegion().getNameStr() << "' in function '"
|
||||
<< S.getFunction().getName() << "':\n";
|
||||
P.printScop(OS, S);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<ForwardOpTreeWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
char ForwardOpTreePrinterLegacyPass::ID = 0;
|
||||
} // namespace
|
||||
|
||||
Pass *polly::createForwardOpTreeWrapperPass() {
|
||||
return new ForwardOpTreeWrapperPass();
|
||||
}
|
||||
|
||||
Pass *polly::createForwardOpTreePrinterLegacyPass(llvm::raw_ostream &OS) {
|
||||
return new ForwardOpTreePrinterLegacyPass(OS);
|
||||
}
|
||||
|
||||
llvm::PreservedAnalyses ForwardOpTreePass::run(Scop &S,
|
||||
ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &SAR,
|
||||
@@ -1200,14 +1113,20 @@ ForwardOpTreePrinterPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
return runForwardOpTreeUsingNPM(S, SAM, SAR, U, &OS);
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(ForwardOpTreeWrapperPass, "polly-optree",
|
||||
"Polly - Forward operand tree", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(ForwardOpTreeWrapperPass, "polly-optree",
|
||||
"Polly - Forward operand tree", false, false)
|
||||
bool polly::runForwardOpTree(Scop &S) {
|
||||
LoopInfo &LI = *S.getLI();
|
||||
|
||||
INITIALIZE_PASS_BEGIN(ForwardOpTreePrinterLegacyPass, "polly-print-optree",
|
||||
"Polly - Print forward operand tree result", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(ForwardOpTreeWrapperPass)
|
||||
INITIALIZE_PASS_END(ForwardOpTreePrinterLegacyPass, "polly-print-optree",
|
||||
"Polly - Print forward operand tree result", false, false)
|
||||
std::unique_ptr<ForwardOpTreeImpl> Impl = runForwardOpTreeImpl(S, LI);
|
||||
if (PollyPrintOptree) {
|
||||
outs() << "Printing analysis 'Polly - Forward operand tree' for region: '"
|
||||
<< S.getName() << "' in function '" << S.getFunction().getName()
|
||||
<< "':\n";
|
||||
if (Impl) {
|
||||
assert(Impl->getScop() == &S);
|
||||
|
||||
Impl->print(outs());
|
||||
}
|
||||
}
|
||||
|
||||
return Impl->isModified();
|
||||
}
|
||||
|
||||
@@ -13,14 +13,13 @@
|
||||
|
||||
#include "polly/MaximalStaticExpansion.h"
|
||||
#include "polly/DependenceInfo.h"
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/Options.h"
|
||||
#include "polly/ScopInfo.h"
|
||||
#include "polly/ScopPass.h"
|
||||
#include "polly/Support/ISLTools.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
||||
#include "llvm/InitializePasses.h"
|
||||
#include "isl/isl-noexceptions.h"
|
||||
#include "isl/union_map.h"
|
||||
#include <cassert>
|
||||
@@ -35,28 +34,10 @@ using namespace polly;
|
||||
|
||||
namespace {
|
||||
|
||||
class MaximalStaticExpanderWrapperPass final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
explicit MaximalStaticExpanderWrapperPass() : ScopPass(ID) {}
|
||||
|
||||
~MaximalStaticExpanderWrapperPass() override = default;
|
||||
|
||||
/// Expand the accesses of the SCoP.
|
||||
///
|
||||
/// @param S The SCoP that must be expanded.
|
||||
bool runOnScop(Scop &S) override;
|
||||
|
||||
/// Print the SCoP.
|
||||
///
|
||||
/// @param OS The stream where to print.
|
||||
/// @param S The SCop that must be printed.
|
||||
void printScop(raw_ostream &OS, Scop &S) const override;
|
||||
|
||||
/// Register all analyses and transformations required.
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
};
|
||||
static cl::opt<bool>
|
||||
PollyPrintMSE("polly-print-mse",
|
||||
cl::desc("Polly - Print Maximal static expansion of SCoP"),
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
#ifndef NDEBUG
|
||||
/// Whether a dimension of a set is bounded (lower and upper) by a constant,
|
||||
@@ -458,8 +439,8 @@ public:
|
||||
};
|
||||
|
||||
static std::unique_ptr<MaximalStaticExpansionImpl>
|
||||
runMaximalStaticExpansion(Scop &S, OptimizationRemarkEmitter &ORE,
|
||||
const Dependences &D) {
|
||||
runMaximalStaticExpansionImpl(Scop &S, OptimizationRemarkEmitter &ORE,
|
||||
const Dependences &D) {
|
||||
auto Dependences = D.getDependences(Dependences::TYPE_RAW);
|
||||
|
||||
std::unique_ptr<MaximalStaticExpansionImpl> Impl =
|
||||
@@ -478,7 +459,7 @@ static PreservedAnalyses runMSEUsingNPM(Scop &S, ScopAnalysisManager &SAM,
|
||||
auto &D = DI.getDependences(Dependences::AL_Reference);
|
||||
|
||||
std::unique_ptr<MaximalStaticExpansionImpl> Impl =
|
||||
runMaximalStaticExpansion(S, ORE, D);
|
||||
runMaximalStaticExpansionImpl(S, ORE, D);
|
||||
|
||||
if (OS) {
|
||||
*OS << "Printing analysis 'Polly - Maximal static expansion of SCoP' for "
|
||||
@@ -511,42 +492,24 @@ MaximalStaticExpansionPrinterPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
return runMSEUsingNPM(S, SAM, SAR, &OS);
|
||||
}
|
||||
|
||||
char MaximalStaticExpanderWrapperPass::ID = 0;
|
||||
void polly::runMaximalStaticExpansion(Scop &S, DependenceAnalysis::Result &DI) {
|
||||
OptimizationRemarkEmitter ORE(&S.getFunction());
|
||||
|
||||
bool MaximalStaticExpanderWrapperPass::runOnScop(Scop &S) {
|
||||
// Get the ORE from OptimizationRemarkEmitterWrapperPass.
|
||||
OptimizationRemarkEmitter *ORE =
|
||||
&getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
|
||||
|
||||
// Get the RAW Dependences.
|
||||
auto &DI = getAnalysis<DependenceInfo>();
|
||||
auto &D = DI.getDependences(Dependences::AL_Reference);
|
||||
|
||||
std::unique_ptr<MaximalStaticExpansionImpl> Impl =
|
||||
runMaximalStaticExpansion(S, *ORE, D);
|
||||
runMaximalStaticExpansionImpl(S, ORE, D);
|
||||
|
||||
return false;
|
||||
if (PollyPrintMSE) {
|
||||
outs()
|
||||
<< "Printing analysis 'Polly - Maximal static expansion of SCoP' for "
|
||||
"region: '"
|
||||
<< S.getName() << "' in function '" << S.getFunction().getName()
|
||||
<< "':\n";
|
||||
|
||||
if (Impl) {
|
||||
outs() << "MSE result:\n";
|
||||
Impl->print(llvm::outs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MaximalStaticExpanderWrapperPass::printScop(raw_ostream &OS,
|
||||
Scop &S) const {
|
||||
S.print(OS, false);
|
||||
}
|
||||
|
||||
void MaximalStaticExpanderWrapperPass::getAnalysisUsage(
|
||||
AnalysisUsage &AU) const {
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<DependenceInfo>();
|
||||
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
|
||||
}
|
||||
|
||||
Pass *polly::createMaximalStaticExpansionPass() {
|
||||
return new MaximalStaticExpanderWrapperPass();
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(MaximalStaticExpanderWrapperPass, "polly-mse",
|
||||
"Polly - Maximal static expansion of SCoP", false, false);
|
||||
INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
|
||||
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass);
|
||||
INITIALIZE_PASS_END(MaximalStaticExpanderWrapperPass, "polly-mse",
|
||||
"Polly - Maximal static expansion of SCoP", false, false)
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
#include "llvm/ADT/Sequence.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
||||
#include "llvm/InitializePasses.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "isl/options.h"
|
||||
|
||||
@@ -198,6 +197,10 @@ static cl::opt<bool> OptimizedScops(
|
||||
"transformations is applied on the schedule tree"),
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
static cl::opt<bool> PollyPrintOptIsl("polly-print-opt-isl",
|
||||
cl::desc("A polly pass"),
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
STATISTIC(ScopsProcessed, "Number of scops processed");
|
||||
STATISTIC(ScopsRescheduled, "Number of scops rescheduled");
|
||||
STATISTIC(ScopsOptimized, "Number of scops optimized");
|
||||
@@ -638,34 +641,6 @@ bool ScheduleTreeOptimizer::isProfitableSchedule(Scop &S,
|
||||
return changed;
|
||||
}
|
||||
|
||||
class IslScheduleOptimizerWrapperPass final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
explicit IslScheduleOptimizerWrapperPass() : ScopPass(ID) {}
|
||||
|
||||
/// Optimize the schedule of the SCoP @p S.
|
||||
bool runOnScop(Scop &S) override;
|
||||
|
||||
/// Print the new schedule for the SCoP @p S.
|
||||
void printScop(raw_ostream &OS, Scop &S) const override;
|
||||
|
||||
/// Register all analyses and transformation required.
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
|
||||
/// Release the internal memory.
|
||||
void releaseMemory() override {
|
||||
LastSchedule = {};
|
||||
IslCtx.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<isl_ctx> IslCtx;
|
||||
isl::schedule LastSchedule;
|
||||
};
|
||||
|
||||
char IslScheduleOptimizerWrapperPass::ID = 0;
|
||||
|
||||
#ifndef NDEBUG
|
||||
static void printSchedule(llvm::raw_ostream &OS, const isl::schedule &Schedule,
|
||||
StringRef Desc) {
|
||||
@@ -733,7 +708,7 @@ static void walkScheduleTreeForStatistics(isl::schedule Schedule, int Version) {
|
||||
&Version);
|
||||
}
|
||||
|
||||
static void runIslScheduleOptimizer(
|
||||
static void runIslScheduleOptimizerImpl(
|
||||
Scop &S,
|
||||
function_ref<const Dependences &(Dependences::AnalysisLevel)> GetDeps,
|
||||
TargetTransformInfo *TTI, OptimizationRemarkEmitter *ORE,
|
||||
@@ -966,30 +941,6 @@ static void runIslScheduleOptimizer(
|
||||
errs() << S;
|
||||
}
|
||||
|
||||
bool IslScheduleOptimizerWrapperPass::runOnScop(Scop &S) {
|
||||
releaseMemory();
|
||||
|
||||
Function &F = S.getFunction();
|
||||
IslCtx = S.getSharedIslCtx();
|
||||
|
||||
auto getDependences =
|
||||
[this](Dependences::AnalysisLevel) -> const Dependences & {
|
||||
return getAnalysis<DependenceInfo>().getDependences(
|
||||
Dependences::AL_Statement);
|
||||
};
|
||||
OptimizationRemarkEmitter &ORE =
|
||||
getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
|
||||
TargetTransformInfo *TTI =
|
||||
&getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||
|
||||
bool DepsChanged = false;
|
||||
runIslScheduleOptimizer(S, getDependences, TTI, &ORE, LastSchedule,
|
||||
DepsChanged);
|
||||
if (DepsChanged)
|
||||
getAnalysis<DependenceInfo>().abandonDependences();
|
||||
return false;
|
||||
}
|
||||
|
||||
static void runScheduleOptimizerPrinter(raw_ostream &OS,
|
||||
isl::schedule LastSchedule) {
|
||||
isl_printer *p;
|
||||
@@ -1013,36 +964,8 @@ static void runScheduleOptimizerPrinter(raw_ostream &OS,
|
||||
free(ScheduleStr);
|
||||
}
|
||||
|
||||
void IslScheduleOptimizerWrapperPass::printScop(raw_ostream &OS, Scop &) const {
|
||||
runScheduleOptimizerPrinter(OS, LastSchedule);
|
||||
}
|
||||
|
||||
void IslScheduleOptimizerWrapperPass::getAnalysisUsage(
|
||||
AnalysisUsage &AU) const {
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<DependenceInfo>();
|
||||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
|
||||
|
||||
AU.addPreserved<DependenceInfo>();
|
||||
AU.addPreserved<OptimizationRemarkEmitterWrapperPass>();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Pass *polly::createIslScheduleOptimizerWrapperPass() {
|
||||
return new IslScheduleOptimizerWrapperPass();
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(IslScheduleOptimizerWrapperPass, "polly-opt-isl",
|
||||
"Polly - Optimize schedule of SCoP", false, false);
|
||||
INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
|
||||
INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass);
|
||||
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass);
|
||||
INITIALIZE_PASS_END(IslScheduleOptimizerWrapperPass, "polly-opt-isl",
|
||||
"Polly - Optimize schedule of SCoP", false, false)
|
||||
|
||||
static llvm::PreservedAnalyses
|
||||
runIslScheduleOptimizerUsingNPM(Scop &S, ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &SAR, SPMUpdater &U,
|
||||
@@ -1055,7 +978,7 @@ runIslScheduleOptimizerUsingNPM(Scop &S, ScopAnalysisManager &SAM,
|
||||
TargetTransformInfo *TTI = &SAR.TTI;
|
||||
isl::schedule LastSchedule;
|
||||
bool DepsChanged = false;
|
||||
runIslScheduleOptimizer(S, GetDeps, TTI, &ORE, LastSchedule, DepsChanged);
|
||||
runIslScheduleOptimizerImpl(S, GetDeps, TTI, &ORE, LastSchedule, DepsChanged);
|
||||
if (DepsChanged)
|
||||
Deps.abandonDependences();
|
||||
|
||||
@@ -1081,52 +1004,23 @@ IslScheduleOptimizerPrinterPass::run(Scop &S, ScopAnalysisManager &SAM,
|
||||
return runIslScheduleOptimizerUsingNPM(S, SAM, SAR, U, &OS);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
void polly::runIslScheduleOptimizer(Scop &S, TargetTransformInfo *TTI,
|
||||
DependenceAnalysis::Result &Deps) {
|
||||
auto GetDeps = [&Deps](Dependences::AnalysisLevel) -> const Dependences & {
|
||||
return Deps.getDependences(Dependences::AL_Statement);
|
||||
};
|
||||
OptimizationRemarkEmitter ORE(&S.getFunction());
|
||||
isl::schedule LastSchedule;
|
||||
bool DepsChanged = false;
|
||||
runIslScheduleOptimizerImpl(S, GetDeps, TTI, &ORE, LastSchedule, DepsChanged);
|
||||
if (DepsChanged)
|
||||
Deps.abandonDependences();
|
||||
|
||||
namespace {
|
||||
/// Print result from IslScheduleOptimizerWrapperPass.
|
||||
class IslScheduleOptimizerPrinterLegacyPass final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
IslScheduleOptimizerPrinterLegacyPass()
|
||||
: IslScheduleOptimizerPrinterLegacyPass(outs()) {}
|
||||
explicit IslScheduleOptimizerPrinterLegacyPass(llvm::raw_ostream &OS)
|
||||
: ScopPass(ID), OS(OS) {}
|
||||
|
||||
bool runOnScop(Scop &S) override {
|
||||
IslScheduleOptimizerWrapperPass &P =
|
||||
getAnalysis<IslScheduleOptimizerWrapperPass>();
|
||||
|
||||
OS << "Printing analysis '" << P.getPassName() << "' for region: '"
|
||||
<< S.getRegion().getNameStr() << "' in function '"
|
||||
<< S.getFunction().getName() << "':\n";
|
||||
P.printScop(OS, S);
|
||||
|
||||
return false;
|
||||
if (PollyPrintOptIsl) {
|
||||
outs()
|
||||
<< "Printing analysis 'Polly - Optimize schedule of SCoP' for region: '"
|
||||
<< S.getName() << "' in function '" << S.getFunction().getName()
|
||||
<< "':\n";
|
||||
runScheduleOptimizerPrinter(outs(), LastSchedule);
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<IslScheduleOptimizerWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
char IslScheduleOptimizerPrinterLegacyPass::ID = 0;
|
||||
} // namespace
|
||||
|
||||
Pass *polly::createIslScheduleOptimizerPrinterLegacyPass(raw_ostream &OS) {
|
||||
return new IslScheduleOptimizerPrinterLegacyPass(OS);
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(IslScheduleOptimizerPrinterLegacyPass,
|
||||
"polly-print-opt-isl",
|
||||
"Polly - Print optimizer schedule of SCoP", false, false);
|
||||
INITIALIZE_PASS_DEPENDENCY(IslScheduleOptimizerWrapperPass)
|
||||
INITIALIZE_PASS_END(IslScheduleOptimizerPrinterLegacyPass,
|
||||
"polly-print-opt-isl",
|
||||
"Polly - Print optimizer schedule of SCoP", false, false)
|
||||
|
||||
@@ -95,53 +95,7 @@ template <typename SCC_t> bool runScopInlinerImpl(Function *F, SCC_t &SCC) {
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
class ScopInlinerWrapperPass final : public CallGraphSCCPass {
|
||||
using llvm::Pass::doInitialization;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
ScopInlinerWrapperPass() : CallGraphSCCPass(ID) {}
|
||||
|
||||
bool doInitialization(CallGraph &CG) override {
|
||||
if (!polly::PollyAllowFullFunction) {
|
||||
report_fatal_error(
|
||||
"Aborting from ScopInliner because it only makes sense to run with "
|
||||
"-polly-allow-full-function. "
|
||||
"The heurtistic for ScopInliner checks that the full function is a "
|
||||
"Scop, which happens if and only if polly-allow-full-function is "
|
||||
" enabled. "
|
||||
" If not, the entry block is not included in the Scop");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool runOnSCC(CallGraphSCC &SCC) override {
|
||||
Function *F = (*SCC.begin())->getFunction();
|
||||
return runScopInlinerImpl(F, SCC);
|
||||
};
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
CallGraphSCCPass::getAnalysisUsage(AU);
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
char ScopInlinerWrapperPass::ID;
|
||||
|
||||
Pass *polly::createScopInlinerWrapperPass() {
|
||||
ScopInlinerWrapperPass *pass = new ScopInlinerWrapperPass();
|
||||
return pass;
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(
|
||||
ScopInlinerWrapperPass, "polly-scop-inliner",
|
||||
"inline functions based on how much of the function is a scop.", false,
|
||||
false)
|
||||
INITIALIZE_PASS_END(
|
||||
ScopInlinerWrapperPass, "polly-scop-inliner",
|
||||
"inline functions based on how much of the function is a scop.", false,
|
||||
false)
|
||||
|
||||
polly::ScopInlinerPass::ScopInlinerPass() {
|
||||
if (!polly::PollyAllowFullFunction) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "polly/Simplify.h"
|
||||
#include "polly/Options.h"
|
||||
#include "polly/ScopInfo.h"
|
||||
#include "polly/ScopPass.h"
|
||||
#include "polly/Support/GICHelper.h"
|
||||
@@ -18,7 +19,6 @@
|
||||
#include "polly/Support/ISLTools.h"
|
||||
#include "polly/Support/VirtualInstruction.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/InitializePasses.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include <optional>
|
||||
|
||||
@@ -30,6 +30,11 @@ using namespace polly;
|
||||
|
||||
namespace {
|
||||
|
||||
static cl::opt<bool>
|
||||
PollyPrintSimplify("polly-print-simplify",
|
||||
cl::desc("Polly - Print Simplify actions"),
|
||||
cl::cat(PollyCategory));
|
||||
|
||||
#define TWO_STATISTICS(VARNAME, DESC) \
|
||||
static llvm::Statistic VARNAME[2] = { \
|
||||
{DEBUG_TYPE, #VARNAME "0", DESC " (first)"}, \
|
||||
@@ -756,39 +761,6 @@ void SimplifyImpl::printScop(raw_ostream &OS, Scop &S) const {
|
||||
printAccesses(OS);
|
||||
}
|
||||
|
||||
class SimplifyWrapperPass final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
int CallNo;
|
||||
std::optional<SimplifyImpl> Impl;
|
||||
|
||||
explicit SimplifyWrapperPass(int CallNo = 0) : ScopPass(ID), CallNo(CallNo) {}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequiredTransitive<ScopInfoRegionPass>();
|
||||
AU.addRequired<LoopInfoWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
bool runOnScop(Scop &S) override {
|
||||
LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
|
||||
Impl.emplace(CallNo);
|
||||
Impl->run(S, LI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void printScop(raw_ostream &OS, Scop &S) const override {
|
||||
if (Impl)
|
||||
Impl->printScop(OS, S);
|
||||
}
|
||||
|
||||
void releaseMemory() override { Impl.reset(); }
|
||||
};
|
||||
|
||||
char SimplifyWrapperPass::ID;
|
||||
|
||||
static llvm::PreservedAnalyses
|
||||
runSimplifyUsingNPM(Scop &S, ScopAnalysisManager &SAM,
|
||||
ScopStandardAnalysisResults &SAR, SPMUpdater &U, int CallNo,
|
||||
@@ -843,58 +815,15 @@ SmallVector<MemoryAccess *, 32> polly::getAccessesInOrder(ScopStmt &Stmt) {
|
||||
return Accesses;
|
||||
}
|
||||
|
||||
Pass *polly::createSimplifyWrapperPass(int CallNo) {
|
||||
return new SimplifyWrapperPass(CallNo);
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(SimplifyWrapperPass, "polly-simplify", "Polly - Simplify",
|
||||
false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(SimplifyWrapperPass, "polly-simplify", "Polly - Simplify",
|
||||
false, false)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
/// Print result from SimplifyWrapperPass.
|
||||
class SimplifyPrinterLegacyPass final : public ScopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
SimplifyPrinterLegacyPass() : SimplifyPrinterLegacyPass(outs()) {}
|
||||
explicit SimplifyPrinterLegacyPass(llvm::raw_ostream &OS)
|
||||
: ScopPass(ID), OS(OS) {}
|
||||
|
||||
bool runOnScop(Scop &S) override {
|
||||
SimplifyWrapperPass &P = getAnalysis<SimplifyWrapperPass>();
|
||||
|
||||
OS << "Printing analysis '" << P.getPassName() << "' for region: '"
|
||||
<< S.getRegion().getNameStr() << "' in function '"
|
||||
<< S.getFunction().getName() << "':\n";
|
||||
P.printScop(OS, S);
|
||||
|
||||
return false;
|
||||
bool polly::runSimplify(Scop &S, int CallNo) {
|
||||
SimplifyImpl Impl(CallNo);
|
||||
Impl.run(S, S.getLI());
|
||||
if (PollyPrintSimplify) {
|
||||
outs() << "Printing analysis 'Polly - Simplify' for region: '"
|
||||
<< S.getName() << "' in function '" << S.getFunction().getName()
|
||||
<< "':\n";
|
||||
Impl.printScop(outs(), S);
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
ScopPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<SimplifyWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::raw_ostream &OS;
|
||||
};
|
||||
|
||||
char SimplifyPrinterLegacyPass::ID = 0;
|
||||
} // namespace
|
||||
|
||||
Pass *polly::createSimplifyPrinterLegacyPass(raw_ostream &OS) {
|
||||
return new SimplifyPrinterLegacyPass(OS);
|
||||
return Impl.isModified();
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(SimplifyPrinterLegacyPass, "polly-print-simplify",
|
||||
"Polly - Print Simplify actions", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(SimplifyWrapperPass)
|
||||
INITIALIZE_PASS_END(SimplifyPrinterLegacyPass, "polly-print-simplify",
|
||||
"Polly - Print Simplify actions", false, false)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' < %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"
|
||||
|
||||
define void @init_array() nounwind {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen -disable-output < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=print<polly-detect>' -disable-output < %s | not FileCheck %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' -disable-output < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<detect>' -polly-print-detect -disable-output < %s | not FileCheck %s
|
||||
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' < %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"
|
||||
|
||||
define void @clause_SetSplitField(i32 %Length) nounwind inlinehint {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' < %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"
|
||||
|
||||
@win193 = external global [4 x [36 x double]], align 32 ; <ptr> [#uses=3]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly '-passes=print<polly-detect>' < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<detect>' -polly-print-detect < %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"
|
||||
|
||||
define fastcc void @execute() nounwind {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' < %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"
|
||||
|
||||
define void @init_array() nounwind {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' < %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"
|
||||
|
||||
define void @fft_float(i32 %NumSamples) nounwind {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' < %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"
|
||||
|
||||
define hidden void @luaD_callhook() nounwind {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen -disable-output < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' -disable-output < %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"
|
||||
|
||||
define void @matrixTranspose(ptr %A) nounwind {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen -verify-dom-info -disable-output < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' -verify-dom-info -disable-output < %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"
|
||||
|
||||
define void @getNonAffNeighbour() nounwind {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen -verify-dom-info -disable-output < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' -verify-dom-info -disable-output < %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"
|
||||
|
||||
define void @intrapred_luma_16x16(i32 %predmode) nounwind {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly '-passes=print<polly-ast>' -disable-output < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<ast>' -polly-print-ast -disable-output < %s
|
||||
|
||||
;int bar1();
|
||||
;int bar2();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen -disable-output < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' -disable-output < %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"
|
||||
define void @cfft2(ptr %x) nounwind {
|
||||
entry:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen -disable-output < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' -disable-output < %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"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' < %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"
|
||||
|
||||
define void @compdecomp() nounwind {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' < %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"
|
||||
define void @Reflection_coefficients(ptr %r) nounwind {
|
||||
bb20:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' < %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"
|
||||
|
||||
define void @CleanNet() nounwind {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' < %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"
|
||||
|
||||
define void @main() nounwind {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' < %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"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -S -passes=polly-codegen < %s | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly -S '-passes=polly<no-default-opts>' < %s | FileCheck %s
|
||||
|
||||
; CHECK: polly.start
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' < %s
|
||||
|
||||
; We just check that this compilation does not crash.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen -S < %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' -S < %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"
|
||||
|
||||
define void @list_sequence(ptr %A) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen -S < %s | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' -S < %s | FileCheck %s
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -S -passes=polly-codegen < %s | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly -S '-passes=polly<no-default-opts>' < %s | FileCheck %s
|
||||
;
|
||||
; Check that we generate code without crashing.
|
||||
;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
; This test checks that we do not accidentally mutate the debug info when
|
||||
; inserting loop parallel metadata.
|
||||
; RUN: opt %loadNPMPolly < %s -S -polly -passes=polly-codegen -polly-ast-detect-parallel | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly -S -polly '-passes=polly<no-default-opts>' -polly-ast-detect-parallel < %s | FileCheck %s
|
||||
; CHECK-NOT: !7 = !{!7}
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen -polly-ast-detect-parallel -S < %s | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' -polly-ast-detect-parallel -S < %s | FileCheck %s
|
||||
;
|
||||
; Check that we mark multiple parallel loops correctly including the memory instructions.
|
||||
;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen -S < %s | FileCheck %s -check-prefix=SEQUENTIAL
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen -polly-ast-detect-parallel -S < %s | FileCheck %s -check-prefix=PARALLEL
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' -S < %s | FileCheck %s -check-prefix=SEQUENTIAL
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' -polly-ast-detect-parallel -S < %s | FileCheck %s -check-prefix=PARALLEL
|
||||
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"
|
||||
|
||||
; This is a trivially parallel loop. We just use it to ensure that we actually
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: not --crash opt %loadNPMPolly -passes=polly-import-jscop -disable-output 2>&1 < %s | FileCheck %s
|
||||
; RUN: not --crash opt %loadNPMPolly '-passes=polly-custom<import-jscop>' -disable-output 2>&1 < %s | FileCheck %s
|
||||
;
|
||||
; Check that we do not allow to access elements not accessed before because the
|
||||
; alignment information would become invalid.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;RUN: opt %loadNPMPolly '-passes=polly-import-jscop,polly-codegen' -polly-import-jscop-postfix=transformed < %s -S | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<import-jscop;codegen>' -polly-import-jscop-postfix=transformed -S < %s | FileCheck %s
|
||||
|
||||
;int A[100];
|
||||
;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;RUN: opt %loadNPMPolly '-passes=polly-import-jscop,polly-codegen' -polly-import-jscop-postfix=transformed < %s -S | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<import-jscop;codegen>' -polly-import-jscop-postfix=transformed -S < %s | FileCheck %s
|
||||
|
||||
;int A[100];
|
||||
;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;RUN: opt %loadNPMPolly '-passes=polly-import-jscop,polly-codegen' -polly-import-jscop-postfix=transformed < %s -S | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<import-jscop;codegen>' -polly-import-jscop-postfix=transformed -S < %s | FileCheck %s
|
||||
|
||||
;int A[100];
|
||||
;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;RUN: opt %loadNPMPolly '-passes=polly-import-jscop,polly-codegen' -polly-import-jscop-postfix=transformed < %s -S | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<import-jscop;codegen>' -polly-import-jscop-postfix=transformed -S < %s | FileCheck %s
|
||||
;
|
||||
;float A[100];
|
||||
;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
;RUN: opt %loadNPMPolly '-passes=polly-import-jscop,polly-codegen' -polly-import-jscop-postfix=transformed+withconst < %s -S | FileCheck -check-prefix=WITHCONST %s
|
||||
;RUN: opt %loadNPMPolly '-passes=polly-import-jscop,polly-codegen' -polly-import-jscop-postfix=transformed+withoutconst < %s -S | FileCheck -check-prefix=WITHOUTCONST %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<import-jscop;codegen>' -polly-import-jscop-postfix=transformed+withconst -S < %s | FileCheck -check-prefix=WITHCONST %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<import-jscop;codegen>' -polly-import-jscop-postfix=transformed+withoutconst -S < %s | FileCheck -check-prefix=WITHOUTCONST %s
|
||||
|
||||
;int A[1040];
|
||||
;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
;RUN: opt %loadNPMPolly '-passes=polly-import-jscop,polly-codegen' -polly-import-jscop-postfix=transformed+withconst < %s -S | FileCheck -check-prefix=WITHCONST %s
|
||||
;RUN: opt %loadNPMPolly '-passes=polly-import-jscop,polly-codegen' -polly-import-jscop-postfix=transformed+withoutconst < %s -S | FileCheck -check-prefix=WITHOUTCONST %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<import-jscop;codegen>' -polly-import-jscop-postfix=transformed+withconst -S < %s | FileCheck -check-prefix=WITHCONST %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<import-jscop;codegen>' -polly-import-jscop-postfix=transformed+withoutconst -S < %s | FileCheck -check-prefix=WITHOUTCONST %s
|
||||
;
|
||||
;float A[1040];
|
||||
;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
; RUN: opt %loadPolly -polly-print-scops -polly-print-import-jscop -polly-import-jscop-postfix=transformed -disable-output < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-postfix=transformed -polly-codegen -S < %s 2>&1 | FileCheck %s --check-prefix=CODEGEN
|
||||
; RUN: opt %loadNPMPolly -polly-print-scops '-passes=polly-custom<import-jscop>' -polly-print-import-jscop -polly-import-jscop-postfix=transformed -disable-output < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<import-jscop;codegen>' -polly-import-jscop-postfix=transformed -S < %s 2>&1 | FileCheck %s --check-prefix=CODEGEN
|
||||
;
|
||||
; for (i = 0; i < _PB_NI; i++)
|
||||
; for (j = 0; j < _PB_NJ; j++)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-print-scops -polly-print-import-jscop -polly-import-jscop-postfix=transformed -disable-output < %s | FileCheck %s
|
||||
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-import-jscop -polly-import-jscop-postfix=transformed -polly-codegen -S < %s | FileCheck %s --check-prefix=CODEGEN
|
||||
; RUN: opt %loadNPMPolly -polly-stmt-granularity=bb -polly-print-scops '-passes=polly-custom<import-jscop>' -polly-print-import-jscop -polly-import-jscop-postfix=transformed -disable-output < %s | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly -polly-stmt-granularity=bb '-passes=polly-custom<import-jscop;codegen>' -polly-import-jscop-postfix=transformed -S < %s | FileCheck %s --check-prefix=CODEGEN
|
||||
;
|
||||
; #define Ni 1056
|
||||
; #define Nj 1056
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: opt %loadPolly -basic-aa -polly-print-import-jscop -disable-output < %s | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<import-jscop>' -polly-print-import-jscop -disable-output < %s | FileCheck %s
|
||||
;
|
||||
; Check that we allow the new access functions even though they access
|
||||
; different locations than the original ones (but the alignment is the
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-import-jscop,polly-codegen' \
|
||||
; RUN: \
|
||||
; RUN: -S < %s | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<import-jscop;codegen>' -S < %s | FileCheck %s
|
||||
;
|
||||
; void foo(float A[], float B[]) {
|
||||
; for (long i = 0; i < 100; i++)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen -polly-codegen-generate-expressions=false \
|
||||
; RUN: -S < %s | FileCheck %s -check-prefix=SCEV
|
||||
; RUN: opt %loadNPMPolly -passes=polly-codegen -polly-codegen-generate-expressions=true \
|
||||
; RUN: -S < %s | FileCheck %s -check-prefix=ASTEXPR
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' -polly-codegen-generate-expressions=false -S < %s | FileCheck %s -check-prefix=SCEV
|
||||
; RUN: opt %loadNPMPolly '-passes=polly<no-default-opts>' -polly-codegen-generate-expressions=true -S < %s | FileCheck %s -check-prefix=ASTEXPR
|
||||
;
|
||||
; void foo(float A[]) {
|
||||
; for (long i = 0; i < 100; i++)
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-import-jscop,polly-codegen' \
|
||||
; RUN: -polly-invariant-load-hoisting -S \
|
||||
; RUN: 2>&1 < %s | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly '-passes=polly-custom<import-jscop;codegen>' -polly-invariant-load-hoisting -S 2>&1 < %s | FileCheck %s
|
||||
|
||||
; Setting new access functions where the base pointer of the array that is newly
|
||||
; accessed is only loaded within the scop itself caused incorrect code to be
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-import-jscop-postfix=transformed -polly-print-import-jscop -disable-output < %s | FileCheck %s
|
||||
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-import-jscop-postfix=transformed -polly-import-jscop -polly-codegen -S < %s | FileCheck %s --check-prefix=CODEGEN
|
||||
; RUN: opt %loadNPMPolly -polly-stmt-granularity=bb -polly-import-jscop-postfix=transformed '-passes=polly-custom<import-jscop>' -polly-print-import-jscop -disable-output < %s | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly -polly-stmt-granularity=bb -polly-import-jscop-postfix=transformed '-passes=polly-custom<import-jscop;codegen>' -S < %s | FileCheck %s --check-prefix=CODEGEN
|
||||
|
||||
define void @map_scalar_access(ptr noalias nonnull %A) {
|
||||
entry:
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
; RUN: opt %loadNPMPolly -polly-stmt-granularity=bb '-passes=polly-import-jscop,polly-codegen' \
|
||||
; RUN: -polly-allow-differing-element-types \
|
||||
; RUN: -S < %s | FileCheck %s
|
||||
; RUN: opt %loadNPMPolly -polly-stmt-granularity=bb '-passes=polly-custom<import-jscop;codegen>' -polly-allow-differing-element-types -S < %s | FileCheck %s
|
||||
;
|
||||
; // Check that accessing one array with different types works.
|
||||
; void multiple_types(char *Short, char *Float, char *Double) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user