Index: include/polly/LinkAllPasses.h =================================================================== --- include/polly/LinkAllPasses.h +++ include/polly/LinkAllPasses.h @@ -37,6 +37,7 @@ llvm::Pass *createJSONExporterPass(); llvm::Pass *createJSONImporterPass(); llvm::Pass *createPollyCanonicalizePass(); +llvm::Pass *createPolyhedralInfoPass(); llvm::Pass *createScopDetectionPass(); llvm::Pass *createScopInfoRegionPassPass(); llvm::Pass *createScopInfoWrapperPassPass(); @@ -69,6 +70,7 @@ polly::createScopDetectionPass(); polly::createScopInfoRegionPassPass(); polly::createPollyCanonicalizePass(); + polly::createPolyhedralInfoPass(); polly::createIslAstInfoPass(); polly::createCodeGenerationPass(); polly::createIslScheduleOptimizerPass(); Index: include/polly/PolyhedralInfo.h =================================================================== --- /dev/null +++ include/polly/PolyhedralInfo.h @@ -0,0 +1,67 @@ +//===- polly/PolyhedralInfo.h - PolyhedralInfo class definition -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains the declaration of the PolyhedralInfo class, which will +/// provide an interface to expose polyhedral analysis information of Polly. +//===----------------------------------------------------------------------===/// + +#ifndef POLLY_POLYHEDRAL_INFO_H +#define POLLY_POLYHEDRAL_INFO_H + +#include "llvm/Pass.h" +#include "isl/ctx.h" +#include "isl/union_map.h" + +using namespace llvm; + +namespace llvm { +class Loop; +} + +namespace polly { + +class Scop; +class ScopInfoWrapperPass; +class DependenceInfoWrapperPass; + +class PolyhedralInfo : public FunctionPass { +public: + static char ID; // Pass identification, replacement for typeid + + PolyhedralInfo() : FunctionPass(ID) {} + ~PolyhedralInfo() {} + + bool isParallel(Loop *L) const; + + const Scop *getScopContainingLoop(Loop *L) const; + + __isl_give isl_union_map *getScheduleForLoop(const Scop *S, Loop *L) const; + + bool runOnFunction(Function &F) override; + + void releaseMemory() override {} + + void print(raw_ostream &O, const Module *M = nullptr) const override; + + void getAnalysisUsage(AnalysisUsage &AU) const override; + +private: + ScopInfoWrapperPass *SI; + DependenceInfoWrapperPass *DI; +}; + +} // end namespace polly + +namespace llvm { +class PassRegistry; +void initializePolyhedralInfoPass(llvm::PassRegistry &); +} + +#endif Index: lib/Analysis/PolyhedralInfo.cpp =================================================================== --- /dev/null +++ lib/Analysis/PolyhedralInfo.cpp @@ -0,0 +1,149 @@ +//===--------- PolyhedralInfo.cpp - Create Scops from LLVM IR-------------===// +/// +/// The LLVM Compiler Infrastructure +/// +/// This file is distributed under the University of Illinois Open Source +/// License. See LICENSE.TXT for details. +/// +//===----------------------------------------------------------------------===// +/// +/// An interface to the Polyhedral analysis engine(Polly) of LLVM. +/// +/// The pass provides an interface to the polyhedral analysis performed by +/// Polly. +/// +/// This interface provides basic interface like isParallel, isVectorizable +/// that can be used in LLVM transformation passes. +/// +/// Work in progress, this file is subject to change. +//===----------------------------------------------------------------------===// + +#include "polly/PolyhedralInfo.h" +#include "polly/DependenceInfo.h" +#include "polly/LinkAllPasses.h" +#include "polly/Options.h" +#include "polly/ScopInfo.h" +#include "polly/Support/GICHelper.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Support/Debug.h" +#include +#include + +using namespace llvm; +using namespace polly; + +#define DEBUG_TYPE "polyhedral-info" + +void PolyhedralInfo::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequiredTransitive(); + AU.addRequired(); + AU.addRequiredTransitive(); + AU.setPreservesAll(); +} + +bool PolyhedralInfo::runOnFunction(Function &F) { + DI = &getAnalysis(); + SI = &getAnalysis(); + return false; +} + +void PolyhedralInfo::print(raw_ostream &OS, const Module *) const { + auto &LI = getAnalysis().getLoopInfo(); + for (auto *TopLevelLoop : LI) { + for (auto *Loop : depth_first(TopLevelLoop)) { + OS.indent(2) << Loop->getHeader()->getName() << ":\t"; + if (isParallel(Loop)) + OS << "Loop is parallel\n"; + else + OS << "Loop is not parallel\n"; + } + } +} + +bool PolyhedralInfo::isParallel(Loop *L) const { + const Scop *S = getScopContainingLoop(L); + if (!S) + return false; + const Dependences &D = + DI->getDependences(const_cast(S), Dependences::AL_Access); + if (!D.hasValidDependences()) + return false; + + isl_union_map *Deps = D.getDependences( + Dependences::TYPE_RAW | Dependences::TYPE_WAW | Dependences::TYPE_WAR); + dbgs() << "\nDependences for this Loop:\t" << stringFromIslObj(Deps) << "\n"; + isl_union_map *Schedule; // = S->getSchedule(); + // dbgs() << "Initial Schedule :\t" << stringFromIslObj(Schedule) << "\n"; + Schedule = getScheduleForLoop(S, L); + dbgs() << "Schedule for loop:\t" << stringFromIslObj(Schedule) << "\n"; + // S->dump(); + bool IsParallel = D.isParallel(Schedule, Deps); + + isl_union_map_free(Deps); + isl_union_map_free(Schedule); + return IsParallel; +} + +const Scop *PolyhedralInfo::getScopContainingLoop(Loop *L) const { + assert((SI) && "ScopInfoWrapperPass is required by PolyhedralInfo pass!\n"); + for (auto &It : *SI) { + Region *R = It.first; + if (R->contains(L)) + return It.second.get(); + } + return nullptr; +} +__isl_give isl_union_map *PolyhedralInfo::getScheduleForLoop(const Scop *S, + Loop *L) const { + dbgs() << "\nget the schedule for loop\n"; + // const Scop *S = getScopContainingLoop(L); + if (!S) + dbgs() << "\nWhy ScopIsEmpty?\n"; + isl_union_map *Schedule = isl_union_map_empty(S->getParamSpace()); + + dbgs() << "\nLoop Depth:\t" << S->getRelativeLoopDepth(L) << "\n"; + for (auto *BB : L->blocks()) { + auto *SS = S->getStmtFor(BB); + if (SS) { + unsigned int CurrDim, MaxDim = SS->getNumIterators(); + for (CurrDim = 0; CurrDim < MaxDim; CurrDim++) { + auto *LL = SS->getLoopForDimension(CurrDim); + if (L == LL) { + break; + } + } + auto *ScheduleMap = SS->getSchedule(); + + dbgs() << "\nCurr Dim:\t" << CurrDim << "\t.Max Dim :\t " << MaxDim + << "\n "; + // ScheduleMap = isl_map_project_out(ScheduleMap, isl_dim_in, CurrDim + 1, + // MaxDim - CurrDim - 1); + // ScheduleMap = isl_map_set_tuple_id(ScheduleMap, isl_dim_in, + // SS->getDomainId()); + ScheduleMap = isl_map_project_out(ScheduleMap, isl_dim_out, CurrDim + 1, + MaxDim - CurrDim - 1); + ScheduleMap = + isl_map_set_tuple_id(ScheduleMap, isl_dim_out, SS->getDomainId()); + Schedule = + isl_union_map_union(Schedule, isl_union_map_from_map(ScheduleMap)); + } + } + // dbgs() << "\nSchedule for loop is \t" << stringFromIslObj(Schedule) << + // "\n"; + Schedule = isl_union_map_coalesce(Schedule); + return Schedule; +} + +char PolyhedralInfo::ID = 0; + +Pass *polly::createPolyhedralInfoPass() { return new PolyhedralInfo(); } + +INITIALIZE_PASS_BEGIN(PolyhedralInfo, "polyhedral-info", + "Polly - Interface to polyhedral analysis engine", false, + false); +INITIALIZE_PASS_DEPENDENCY(DependenceInfoWrapperPass); +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass); +INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass); +INITIALIZE_PASS_END(PolyhedralInfo, "polyhedral-info", + "Polly - Interface to polyhedral analysis engine", false, + false) Index: lib/CMakeLists.txt =================================================================== --- lib/CMakeLists.txt +++ lib/CMakeLists.txt @@ -26,6 +26,7 @@ add_polly_library(Polly Analysis/DependenceInfo.cpp + Analysis/PolyhedralInfo.cpp Analysis/ScopDetection.cpp Analysis/ScopDetectionDiagnostic.cpp Analysis/ScopInfo.cpp Index: lib/Support/RegisterPasses.cpp =================================================================== --- lib/Support/RegisterPasses.cpp +++ lib/Support/RegisterPasses.cpp @@ -26,6 +26,7 @@ #include "polly/DependenceInfo.h" #include "polly/LinkAllPasses.h" #include "polly/Options.h" +#include "polly/PolyhedralInfo.h" #include "polly/ScopDetection.h" #include "polly/ScopInfo.h" #include "llvm/Analysis/CFGPrinter.h" @@ -154,6 +155,7 @@ initializeIslAstInfoPass(Registry); initializeIslScheduleOptimizerPass(Registry); initializePollyCanonicalizePass(Registry); + initializePolyhedralInfoPass(Registry); initializeScopDetectionPass(Registry); initializeScopInfoRegionPassPass(Registry); initializeScopInfoWrapperPassPass(Registry);