27#include "llvm/Analysis/LoopInfo.h"
28#include "llvm/InitializePasses.h"
29#include "llvm/Support/Debug.h"
36#define DEBUG_TYPE "polyhedral-info"
39 cl::desc(
"Check for parallel loops"),
43 cl::desc(
"Check for vectorizable loops"),
48 AU.addRequired<LoopInfoWrapperPass>();
54 DI = &getAnalysis<DependenceInfoWrapperPass>();
55 SI = getAnalysis<ScopInfoWrapperPass>().getSI();
60 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
61 for (
auto *TopLevelLoop : LI) {
62 for (
auto *L : depth_first(TopLevelLoop)) {
63 OS.indent(2) << L->getHeader()->getName() <<
":\t";
65 OS <<
"Loop is parallel.\n";
67 OS <<
"Loop is not parallel.\n";
81 POLLY_DEBUG(dbgs() <<
"Loop :\t" << L->getHeader()->getName() <<
":\n");
88 POLLY_DEBUG(dbgs() <<
"Dependences :\t" << stringFromIslObj(Deps,
"null")
92 POLLY_DEBUG(dbgs() <<
"Schedule: \t" << stringFromIslObj(Schedule,
"null")
95 IsParallel = D.
isParallel(Schedule, Deps, MinDepDistPtr);
103 assert((
SI) &&
"ScopInfoWrapperPass is required by PolyhedralInfo pass!\n");
104 for (
auto &It : *
SI) {
105 Region *R = It.first;
107 return It.second.get();
128 int CurrDim =
S->getRelativeLoopDepth(L);
129 POLLY_DEBUG(dbgs() <<
"Relative loop depth:\t" << CurrDim <<
"\n");
130 assert(CurrDim >= 0 &&
"Loop in region should have at least depth one");
132 for (
auto &SS : *
S) {
133 if (L->contains(SS.getSurroundingLoop())) {
135 unsigned int MaxDim = SS.getNumIterators();
136 POLLY_DEBUG(dbgs() <<
"Maximum depth of Stmt:\t" << MaxDim <<
"\n");
137 isl_map *ScheduleMap = SS.getSchedule().release();
140 "Schedules that contain extension nodes require special handling.");
143 MaxDim - CurrDim - 1);
145 SS.getDomainId().release());
159 "Polly - Interface to polyhedral analysis engine",
false,
165 "Polly - Interface to polyhedral analysis engine",
false,
172class PolyhedralInfoPrinterLegacyPass final :
public FunctionPass {
176 PolyhedralInfoPrinterLegacyPass() : PolyhedralInfoPrinterLegacyPass(outs()) {}
177 explicit PolyhedralInfoPrinterLegacyPass(llvm::raw_ostream &OS)
178 : FunctionPass(ID), OS(OS) {}
180 bool runOnFunction(
Function &F)
override {
183 OS <<
"Printing analysis '" << P.getPassName() <<
"' for function '"
184 << F.getName() <<
"':\n";
190 void getAnalysisUsage(AnalysisUsage &AU)
const override {
191 FunctionPass::getAnalysisUsage(AU);
193 AU.setPreservesAll();
197 llvm::raw_ostream &OS;
200char PolyhedralInfoPrinterLegacyPass::ID = 0;
204 return new PolyhedralInfoPrinterLegacyPass(OS);
208 PolyhedralInfoPrinterLegacyPass,
"print-polyhedral-info",
209 "Polly - Print interface to polyhedral analysis engine analysis",
false,
213 PolyhedralInfoPrinterLegacyPass,
"print-polyhedral-info",
214 "Polly - Print interface to polyhedral analysis engine analysis",
false,
INITIALIZE_PASS_BEGIN(DependenceInfo, "polly-dependences", "Polly - Calculate dependences", false, false)
INITIALIZE_PASS_END(DependenceInfo, "polly-dependences", "Polly - Calculate dependences", false, false) namespace
INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass)
polly dump Polly Dump Function
llvm::cl::OptionCategory PollyCategory
static cl::opt< bool > CheckParallel("polly-check-parallel", cl::desc("Check for parallel loops"), cl::Hidden, cl::cat(PollyCategory))
static cl::opt< bool > CheckVectorizable("polly-check-vectorizable", cl::desc("Check for vectorizable loops"), cl::Hidden, cl::cat(PollyCategory))
__isl_give isl_union_map * release()
Construct a new DependenceInfoWrapper pass.
const Dependences & getDependences(Scop *S, Dependences::AnalysisLevel Level)
Return the dependence information for the given SCoP.
The accumulated dependence information for a SCoP.
bool isParallel(__isl_keep isl_union_map *Schedule, __isl_take isl_union_map *Deps, __isl_give isl_pw_aff **MinDistancePtr=nullptr) const
Check if a partial schedule is parallel wrt to Deps.
bool hasValidDependences() const
Report if valid dependences are available.
isl::union_map getDependences(int Kinds) const
Get the dependences of type Kinds.
bool checkParallel(llvm::Loop *L, __isl_give isl_pw_aff **MinDepDistPtr=nullptr) const
Check if a given loop is parallel or vectorizable.
void getAnalysisUsage(llvm::AnalysisUsage &AU) const override
Register all analyses and transformation required.
bool isParallel(llvm::Loop *L) const
Check if a given loop is parallel.
DependenceInfoWrapperPass * DI
const Scop * getScopContainingLoop(llvm::Loop *L) const
Return the SCoP containing the L loop.
void print(llvm::raw_ostream &OS, const llvm::Module *M=nullptr) const override
Print to OS if each dimension of a loop nest is parallel or not.
__isl_give isl_union_map * getScheduleForLoop(const Scop *S, llvm::Loop *L) const
Computes the partial schedule for the given L loop.
bool runOnFunction(llvm::Function &F) override
Get the SCoP and dependence analysis information for F.
The legacy pass manager's analysis pass to compute scop information for the whole function.
__isl_give isl_map * isl_map_set_tuple_id(__isl_take isl_map *map, enum isl_dim_type type, __isl_take isl_id *id)
__isl_give isl_map * isl_map_project_out(__isl_take isl_map *map, enum isl_dim_type type, unsigned first, unsigned n)
This file contains the declaration of the PolyhedralInfo class, which will provide an interface to ex...
llvm::Pass * createPolyhedralInfoPrinterLegacyPass(llvm::raw_ostream &OS)
llvm::Pass * createPolyhedralInfoPass()
__isl_null isl_union_map * isl_union_map_free(__isl_take isl_union_map *umap)
__isl_export __isl_give isl_union_map * isl_union_map_coalesce(__isl_take isl_union_map *umap)
__isl_give isl_union_map * isl_union_map_empty(__isl_take isl_space *space)
__isl_constructor __isl_give isl_union_map * isl_union_map_from_map(__isl_take isl_map *map)
__isl_export __isl_give isl_union_map * isl_union_map_union(__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)