llvm/polly/lib/Analysis/ScopInfo.cpp

//===- ScopInfo.cpp -------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Create a polyhedral description for a static control flow region.
//
// The pass creates a polyhedral description of the Scops detected by the Scop
// detection derived from their LLVM-IR code.
//
// This representation is shared among several tools in the polyhedral
// community, which are e.g. Cloog, Pluto, Loopo, Graphite.
//
//===----------------------------------------------------------------------===//

#include "polly/ScopInfo.h"
#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "polly/ScopBuilder.h"
#include "polly/ScopDetection.h"
#include "polly/Support/GICHelper.h"
#include "polly/Support/ISLOStream.h"
#include "polly/Support/ISLTools.h"
#include "polly/Support/SCEVAffinator.h"
#include "polly/Support/SCEVValidator.h"
#include "polly/Support/ScopHelper.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Analysis/RegionIterator.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#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"
#include "llvm/Support/raw_ostream.h"
#include "isl/aff.h"
#include "isl/local_space.h"
#include "isl/map.h"
#include "isl/options.h"
#include "isl/set.h"
#include <cassert>
#include <numeric>

usingnamespacellvm;
usingnamespacepolly;

#include "polly/Support/PollyDebug.h"
#define DEBUG_TYPE

STATISTIC(AssumptionsAliasing, "Number of aliasing assumptions taken.");
STATISTIC(AssumptionsInbounds, "Number of inbounds assumptions taken.");
STATISTIC(AssumptionsWrapping, "Number of wrapping assumptions taken.");
STATISTIC(AssumptionsUnsigned, "Number of unsigned assumptions taken.");
STATISTIC(AssumptionsComplexity, "Number of too complex SCoPs.");
STATISTIC(AssumptionsUnprofitable, "Number of unprofitable SCoPs.");
STATISTIC(AssumptionsErrorBlock, "Number of error block assumptions taken.");
STATISTIC(AssumptionsInfiniteLoop, "Number of bounded loop assumptions taken.");
STATISTIC(AssumptionsInvariantLoad,
          "Number of invariant loads assumptions taken.");
STATISTIC(AssumptionsDelinearization,
          "Number of delinearization assumptions taken.");

STATISTIC(NumScops, "Number of feasible SCoPs after ScopInfo");
STATISTIC(NumLoopsInScop, "Number of loops in scops");
STATISTIC(NumBoxedLoops, "Number of boxed loops in SCoPs after ScopInfo");
STATISTIC(NumAffineLoops, "Number of affine loops in SCoPs after ScopInfo");

STATISTIC(NumScopsDepthZero, "Number of scops with maximal loop depth 0");
STATISTIC(NumScopsDepthOne, "Number of scops with maximal loop depth 1");
STATISTIC(NumScopsDepthTwo, "Number of scops with maximal loop depth 2");
STATISTIC(NumScopsDepthThree, "Number of scops with maximal loop depth 3");
STATISTIC(NumScopsDepthFour, "Number of scops with maximal loop depth 4");
STATISTIC(NumScopsDepthFive, "Number of scops with maximal loop depth 5");
STATISTIC(NumScopsDepthLarger,
          "Number of scops with maximal loop depth 6 and larger");
STATISTIC(MaxNumLoopsInScop, "Maximal number of loops in scops");

STATISTIC(NumValueWrites, "Number of scalar value writes after ScopInfo");
STATISTIC(
    NumValueWritesInLoops,
    "Number of scalar value writes nested in affine loops after ScopInfo");
STATISTIC(NumPHIWrites, "Number of scalar phi writes after ScopInfo");
STATISTIC(NumPHIWritesInLoops,
          "Number of scalar phi writes nested in affine loops after ScopInfo");
STATISTIC(NumSingletonWrites, "Number of singleton writes after ScopInfo");
STATISTIC(NumSingletonWritesInLoops,
          "Number of singleton writes nested in affine loops after ScopInfo");

unsigned const polly::MaxDisjunctsInDomain =;

// The number of disjunct in the context after which we stop to add more
// disjuncts. This parameter is there to avoid exponential growth in the
// number of disjunct when adding non-convex sets to the context.
static int const MaxDisjunctsInContext =;

// Be a bit more generous for the defined behavior context which is used less
// often.
static int const MaxDisjunktsInDefinedBehaviourContext =;

static cl::opt<bool> PollyRemarksMinimal(
    "polly-remarks-minimal",
    cl::desc("Do not emit remarks about assumptions that are known"),
    cl::Hidden, cl::cat(PollyCategory));

static cl::opt<bool>
    IslOnErrorAbort("polly-on-isl-error-abort",
                    cl::desc("Abort if an isl error is encountered"),
                    cl::init(true), cl::cat(PollyCategory));

static cl::opt<bool> PollyPreciseInbounds(
    "polly-precise-inbounds",
    cl::desc("Take more precise inbounds assumptions (do not scale well)"),
    cl::Hidden, cl::init(false), cl::cat(PollyCategory));

static cl::opt<bool> PollyIgnoreParamBounds(
    "polly-ignore-parameter-bounds",
    cl::desc(
        "Do not add parameter bounds and do no gist simplify sets accordingly"),
    cl::Hidden, cl::init(false), cl::cat(PollyCategory));

static cl::opt<bool> PollyPreciseFoldAccesses(
    "polly-precise-fold-accesses",
    cl::desc("Fold memory accesses to model more possible delinearizations "
             "(does not scale well)"),
    cl::Hidden, cl::init(false), cl::cat(PollyCategory));

bool polly::UseInstructionNames;

static cl::opt<bool, true> XUseInstructionNames(
    "polly-use-llvm-names",
    cl::desc("Use LLVM-IR names when deriving statement names"),
    cl::location(UseInstructionNames), cl::Hidden, cl::cat(PollyCategory));

static cl::opt<bool> PollyPrintInstructions(
    "polly-print-instructions", cl::desc("Output instructions per ScopStmt"),
    cl::Hidden, cl::Optional, cl::init(false), cl::cat(PollyCategory));

static cl::list<std::string> IslArgs("polly-isl-arg",
                                     cl::value_desc("argument"),
                                     cl::desc("Option passed to ISL"),
                                     cl::cat(PollyCategory));

//===----------------------------------------------------------------------===//

static isl::set addRangeBoundsToSet(isl::set S, const ConstantRange &Range,
                                    int dim, isl::dim type) {}

static const ScopArrayInfo *identifyBasePtrOriginSAI(Scop *S, Value *BasePtr) {}

ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl::ctx Ctx,
                             ArrayRef<const SCEV *> Sizes, MemoryKind Kind,
                             const DataLayout &DL, Scop *S,
                             const char *BaseName)
    :{}

ScopArrayInfo::~ScopArrayInfo() = default;

isl::space ScopArrayInfo::getSpace() const {}

bool ScopArrayInfo::isReadOnly() {}

bool ScopArrayInfo::isCompatibleWith(const ScopArrayInfo *Array) const {}

void ScopArrayInfo::updateElementType(Type *NewElementType) {}

bool ScopArrayInfo::updateSizes(ArrayRef<const SCEV *> NewSizes,
                                bool CheckConsistency) {}

std::string ScopArrayInfo::getName() const {}

int ScopArrayInfo::getElemSizeInBytes() const {}

isl::id ScopArrayInfo::getBasePtrId() const {}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void ScopArrayInfo::dump() const { print(errs()); }
#endif

void ScopArrayInfo::print(raw_ostream &OS, bool SizeAsPwAff) const {}

const ScopArrayInfo *
ScopArrayInfo::getFromAccessFunction(isl::pw_multi_aff PMA) {}

const ScopArrayInfo *ScopArrayInfo::getFromId(isl::id Id) {}

void MemoryAccess::wrapConstantDimensions() {}

void MemoryAccess::updateDimensionality() {}

const std::string
MemoryAccess::getReductionOperatorStr(MemoryAccess::ReductionType RT) {}

const ScopArrayInfo *MemoryAccess::getOriginalScopArrayInfo() const {}

const ScopArrayInfo *MemoryAccess::getLatestScopArrayInfo() const {}

isl::id MemoryAccess::getOriginalArrayId() const {}

isl::id MemoryAccess::getLatestArrayId() const {}

isl::map MemoryAccess::getAddressFunction() const {}

isl::pw_multi_aff
MemoryAccess::applyScheduleToAccessRelation(isl::union_map USchedule) const {}

isl::map MemoryAccess::getOriginalAccessRelation() const {}

std::string MemoryAccess::getOriginalAccessRelationStr() const {}

isl::space MemoryAccess::getOriginalAccessRelationSpace() const {}

isl::map MemoryAccess::getNewAccessRelation() const {}

std::string MemoryAccess::getNewAccessRelationStr() const {}

std::string MemoryAccess::getAccessRelationStr() const {}

isl::basic_map MemoryAccess::createBasicAccessMap(ScopStmt *Statement) {}

// Formalize no out-of-bound access assumption
//
// When delinearizing array accesses we optimistically assume that the
// delinearized accesses do not access out of bound locations (the subscript
// expression of each array evaluates for each statement instance that is
// executed to a value that is larger than zero and strictly smaller than the
// size of the corresponding dimension). The only exception is the outermost
// dimension for which we do not need to assume any upper bound.  At this point
// we formalize this assumption to ensure that at code generation time the
// relevant run-time checks can be generated.
//
// To find the set of constraints necessary to avoid out of bound accesses, we
// first build the set of data locations that are not within array bounds. We
// then apply the reverse access relation to obtain the set of iterations that
// may contain invalid accesses and reduce this set of iterations to the ones
// that are actually executed by intersecting them with the domain of the
// statement. If we now project out all loop dimensions, we obtain a set of
// parameters that may cause statement instances to be executed that may
// possibly yield out of bound memory accesses. The complement of these
// constraints is the set of constraints that needs to be assumed to ensure such
// statement instances are never executed.
isl::set MemoryAccess::assumeNoOutOfBound() {}

void MemoryAccess::buildMemIntrinsicAccessRelation() {}

void MemoryAccess::computeBoundsOnAccessRelation(unsigned ElementSize) {}

void MemoryAccess::foldAccessRelation() {}

void MemoryAccess::buildAccessRelation(const ScopArrayInfo *SAI) {}

MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst,
                           AccessType AccType, Value *BaseAddress,
                           Type *ElementType, bool Affine,
                           ArrayRef<const SCEV *> Subscripts,
                           ArrayRef<const SCEV *> Sizes, Value *AccessValue,
                           MemoryKind Kind)
    :{}

MemoryAccess::MemoryAccess(ScopStmt *Stmt, AccessType AccType, isl::map AccRel)
    :{}

MemoryAccess::~MemoryAccess() = default;

void MemoryAccess::realignParams() {}

const std::string MemoryAccess::getReductionOperatorStr() const {}

isl::id MemoryAccess::getId() const {}

raw_ostream &polly::operator<<(raw_ostream &OS,
                               MemoryAccess::ReductionType RT) {}

void MemoryAccess::print(raw_ostream &OS) const {}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void MemoryAccess::dump() const { print(errs()); }
#endif

isl::pw_aff MemoryAccess::getPwAff(const SCEV *E) {}

// Create a map in the size of the provided set domain, that maps from the
// one element of the provided set domain to another element of the provided
// set domain.
// The mapping is limited to all points that are equal in all but the last
// dimension and for which the last dimension of the input is strict smaller
// than the last dimension of the output.
//
//   getEqualAndLarger(set[i0, i1, ..., iX]):
//
//   set[i0, i1, ..., iX] -> set[o0, o1, ..., oX]
//     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1), iX < oX
//
static isl::map getEqualAndLarger(isl::space SetDomain) {}

isl::set MemoryAccess::getStride(isl::map Schedule) const {}

bool MemoryAccess::isStrideX(isl::map Schedule, int StrideWidth) const {}

bool MemoryAccess::isStrideZero(isl::map Schedule) const {}

bool MemoryAccess::isStrideOne(isl::map Schedule) const {}

void MemoryAccess::setAccessRelation(isl::map NewAccess) {}

void MemoryAccess::setNewAccessRelation(isl::map NewAccess) {}

bool MemoryAccess::isLatestPartialAccess() const {}

//===----------------------------------------------------------------------===//

isl::map ScopStmt::getSchedule() const {}

void ScopStmt::restrictDomain(isl::set NewDomain) {}

void ScopStmt::addAccess(MemoryAccess *Access, bool Prepend) {}

void ScopStmt::realignParams() {}

ScopStmt::ScopStmt(Scop &parent, Region &R, StringRef Name,
                   Loop *SurroundingLoop,
                   std::vector<Instruction *> EntryBlockInstructions)
    :{}

ScopStmt::ScopStmt(Scop &parent, BasicBlock &bb, StringRef Name,
                   Loop *SurroundingLoop,
                   std::vector<Instruction *> Instructions)
    :{}

ScopStmt::ScopStmt(Scop &parent, isl::map SourceRel, isl::map TargetRel,
                   isl::set NewDomain)
    :{}

ScopStmt::~ScopStmt() = default;

std::string ScopStmt::getDomainStr() const {}

std::string ScopStmt::getScheduleStr() const {}

void ScopStmt::setInvalidDomain(isl::set ID) {}

BasicBlock *ScopStmt::getEntryBlock() const {}

unsigned ScopStmt::getNumIterators() const {}

const char *ScopStmt::getBaseName() const {}

Loop *ScopStmt::getLoopForDimension(unsigned Dimension) const {}

isl::ctx ScopStmt::getIslCtx() const {}

isl::set ScopStmt::getDomain() const {}

isl::space ScopStmt::getDomainSpace() const {}

isl::id ScopStmt::getDomainId() const {}

void ScopStmt::printInstructions(raw_ostream &OS) const {}

void ScopStmt::print(raw_ostream &OS, bool PrintInstructions) const {}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void ScopStmt::dump() const { print(dbgs(), true); }
#endif

void ScopStmt::removeAccessData(MemoryAccess *MA) {}

void ScopStmt::removeMemoryAccess(MemoryAccess *MA) {}

void ScopStmt::removeSingleMemoryAccess(MemoryAccess *MA, bool AfterHoisting) {}

MemoryAccess *ScopStmt::ensureValueRead(Value *V) {}

raw_ostream &polly::operator<<(raw_ostream &OS, const ScopStmt &S) {}

//===----------------------------------------------------------------------===//
/// Scop class implement

void Scop::setContext(isl::set NewContext) {}

namespace {

/// Remap parameter values but keep AddRecs valid wrt. invariant loads.
class SCEVSensitiveParameterRewriter final
    : public SCEVRewriteVisitor<SCEVSensitiveParameterRewriter> {};

/// Check whether we should remap a SCEV expression.
class SCEVFindInsideScop : public SCEVTraversal<SCEVFindInsideScop> {};
} // end anonymous namespace

const SCEV *Scop::getRepresentingInvariantLoadSCEV(const SCEV *E) const {}

void Scop::createParameterId(const SCEV *Parameter) {}

void Scop::addParams(const ParameterSetTy &NewParameters) {}

isl::id Scop::getIdForParam(const SCEV *Parameter) const {}

bool Scop::isDominatedBy(const DominatorTree &DT, BasicBlock *BB) const {}

void Scop::buildContext() {}

void Scop::addParameterBounds() {}

void Scop::realignParams() {}

static isl::set simplifyAssumptionContext(isl::set AssumptionContext,
                                          const Scop &S) {}

void Scop::simplifyContexts() {}

isl::set Scop::getDomainConditions(const ScopStmt *Stmt) const {}

isl::set Scop::getDomainConditions(BasicBlock *BB) const {}

Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, LoopInfo &LI,
           DominatorTree &DT, ScopDetection::DetectionContext &DC,
           OptimizationRemarkEmitter &ORE, int ID)
    :{}

Scop::~Scop() = default;

void Scop::removeFromStmtMap(ScopStmt &Stmt) {}

void Scop::removeStmts(function_ref<bool(ScopStmt &)> ShouldDelete,
                       bool AfterHoisting) {}

void Scop::removeStmtNotInDomainMap() {}

void Scop::simplifySCoP(bool AfterHoisting) {}

InvariantEquivClassTy *Scop::lookupInvariantEquivClass(Value *Val) {}

ScopArrayInfo *Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *ElementType,
                                              ArrayRef<const SCEV *> Sizes,
                                              MemoryKind Kind,
                                              const char *BaseName) {}

ScopArrayInfo *Scop::createScopArrayInfo(Type *ElementType,
                                         const std::string &BaseName,
                                         const std::vector<unsigned> &Sizes) {}

ScopArrayInfo *Scop::getScopArrayInfoOrNull(Value *BasePtr, MemoryKind Kind) {}

ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr, MemoryKind Kind) {}

std::string Scop::getContextStr() const {}

std::string Scop::getAssumedContextStr() const {}

std::string Scop::getInvalidContextStr() const {}

std::string Scop::getNameStr() const {}

std::pair<std::string, std::string> Scop::getEntryExitStr() const {}

isl::set Scop::getContext() const {}

isl::space Scop::getParamSpace() const {}

isl::space Scop::getFullParamSpace() const {}

isl::set Scop::getAssumedContext() const {}

bool Scop::isProfitable(bool ScalarsAreUnprofitable) const {}

bool Scop::hasFeasibleRuntimeContext() const {}

MemoryAccess *Scop::lookupBasePtrAccess(MemoryAccess *MA) {}

static std::string toString(AssumptionKind Kind) {}

bool Scop::isEffectiveAssumption(isl::set Set, AssumptionSign Sign) {}

bool Scop::trackAssumption(AssumptionKind Kind, isl::set Set, DebugLoc Loc,
                           AssumptionSign Sign, BasicBlock *BB) {}

void Scop::addAssumption(AssumptionKind Kind, isl::set Set, DebugLoc Loc,
                         AssumptionSign Sign, BasicBlock *BB,
                         bool RequiresRTC) {}

void Scop::intersectDefinedBehavior(isl::set Set, AssumptionSign Sign) {}

void Scop::invalidate(AssumptionKind Kind, DebugLoc Loc, BasicBlock *BB) {}

isl::set Scop::getInvalidContext() const {}

void Scop::printContext(raw_ostream &OS) const {}

void Scop::printAliasAssumptions(raw_ostream &OS) const {}

void Scop::printStatements(raw_ostream &OS, bool PrintInstructions) const {}

void Scop::printArrayInfo(raw_ostream &OS) const {}

void Scop::print(raw_ostream &OS, bool PrintInstructions) const {}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void Scop::dump() const { print(dbgs(), true); }
#endif

isl::ctx Scop::getIslCtx() const {}

__isl_give PWACtx Scop::getPwAff(const SCEV *E, BasicBlock *BB,
                                 bool NonNegative,
                                 RecordedAssumptionsTy *RecordedAssumptions) {}

isl::union_set Scop::getDomains() const {}

isl::pw_aff Scop::getPwAffOnly(const SCEV *E, BasicBlock *BB,
                               RecordedAssumptionsTy *RecordedAssumptions) {}

isl::union_map
Scop::getAccessesOfType(std::function<bool(MemoryAccess &)> Predicate) {}

isl::union_map Scop::getMustWrites() {}

isl::union_map Scop::getMayWrites() {}

isl::union_map Scop::getWrites() {}

isl::union_map Scop::getReads() {}

isl::union_map Scop::getAccesses() {}

isl::union_map Scop::getAccesses(ScopArrayInfo *Array) {}

isl::union_map Scop::getSchedule() const {}

isl::schedule Scop::getScheduleTree() const {}

void Scop::setSchedule(isl::union_map NewSchedule) {}

void Scop::setScheduleTree(isl::schedule NewSchedule) {}

bool Scop::restrictDomains(isl::union_set Domain) {}

ScalarEvolution *Scop::getSE() const {}

void Scop::addScopStmt(BasicBlock *BB, StringRef Name, Loop *SurroundingLoop,
                       std::vector<Instruction *> Instructions) {}

void Scop::addScopStmt(Region *R, StringRef Name, Loop *SurroundingLoop,
                       std::vector<Instruction *> Instructions) {}

ScopStmt *Scop::addScopStmt(isl::map SourceRel, isl::map TargetRel,
                            isl::set Domain) {}

ArrayRef<ScopStmt *> Scop::getStmtListFor(BasicBlock *BB) const {}

ScopStmt *Scop::getIncomingStmtFor(const Use &U) const {}

ScopStmt *Scop::getLastStmtFor(BasicBlock *BB) const {}

ArrayRef<ScopStmt *> Scop::getStmtListFor(RegionNode *RN) const {}

ArrayRef<ScopStmt *> Scop::getStmtListFor(Region *R) const {}

int Scop::getRelativeLoopDepth(const Loop *L) const {}

ScopArrayInfo *Scop::getArrayInfoByName(const std::string BaseName) {}

void Scop::addAccessData(MemoryAccess *Access) {}

void Scop::removeAccessData(MemoryAccess *Access) {}

MemoryAccess *Scop::getValueDef(const ScopArrayInfo *SAI) const {}

ArrayRef<MemoryAccess *> Scop::getValueUses(const ScopArrayInfo *SAI) const {}

MemoryAccess *Scop::getPHIRead(const ScopArrayInfo *SAI) const {}

ArrayRef<MemoryAccess *> Scop::getPHIIncomings(const ScopArrayInfo *SAI) const {}

bool Scop::isEscaping(Instruction *Inst) {}

void Scop::incrementNumberOfAliasingAssumptions(unsigned step) {}

Scop::ScopStatistics Scop::getStatistics() const {}

raw_ostream &polly::operator<<(raw_ostream &OS, const Scop &scop) {}

//===----------------------------------------------------------------------===//
void ScopInfoRegionPass::getAnalysisUsage(AnalysisUsage &AU) const {}

void updateLoopCountStatistic(ScopDetection::LoopStats Stats,
                              Scop::ScopStatistics ScopStats) {}

bool ScopInfoRegionPass::runOnRegion(Region *R, RGPassManager &RGM) {}

void ScopInfoRegionPass::print(raw_ostream &OS, const Module *) const {}

char ScopInfoRegionPass::ID =;

Pass *polly::createScopInfoRegionPassPass() {}

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 {};

char ScopInfoPrinterLegacyRegionPass::ID =;
} // namespace

Pass *polly::createScopInfoPrinterLegacyRegionPass(raw_ostream &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)
    :{}

void ScopInfo::recompute() {}

bool ScopInfo::invalidate(Function &F, const PreservedAnalyses &PA,
                          FunctionAnalysisManager::Invalidator &Inv) {}

AnalysisKey ScopInfoAnalysis::Key;

ScopInfoAnalysis::Result ScopInfoAnalysis::run(Function &F,
                                               FunctionAnalysisManager &FAM) {}

PreservedAnalyses ScopInfoPrinterPass::run(Function &F,
                                           FunctionAnalysisManager &FAM) {}

void ScopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {}

bool ScopInfoWrapperPass::runOnFunction(Function &F) {}

void ScopInfoWrapperPass::print(raw_ostream &OS, const Module *) const {}

char ScopInfoWrapperPass::ID =;

Pass *polly::createScopInfoWrapperPassPass() {}

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 {};

char ScopInfoPrinterLegacyFunctionPass::ID =;
} // namespace

Pass *polly::createScopInfoPrinterLegacyFunctionPass(raw_ostream &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)