[Polly] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).

llvm-svn: 311489
This commit is contained in:
Eugene Zelenko 2017-08-22 21:25:51 +00:00
parent 79865d98d0
commit 0c4c2ce0b0
4 changed files with 328 additions and 233 deletions

View File

@ -1,4 +1,4 @@
//===- polly/ScopBuilder.h -------------------------------------*- C++ -*-===//
//===- polly/ScopBuilder.h --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -14,22 +14,48 @@
//
//===----------------------------------------------------------------------===//
#ifndef POLLY_SCOP_BUILDER_H
#define POLLY_SCOP_BUILDER_H
#ifndef POLLY_SCOPBUILDER_H
#define POLLY_SCOPBUILDER_H
#include "polly/ScopInfo.h"
#include "polly/Support/ScopHelper.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include <algorithm>
#include <memory>
#include <utility>
namespace llvm {
class AssumptionCache;
class BasicBlock;
class DataLayout;
class DominatorTree;
class Instruction;
class LoopInfo;
class PassRegistry;
class PHINode;
class Region;
class ScalarEvolution;
class SCEV;
class Type;
class Value;
void initializeScopInfoRegionPassPass(PassRegistry &);
void initializeScopInfoWrapperPassPass(PassRegistry &);
} // end namespace llvm
namespace polly {
class ScopDetection;
/// Command line switch whether to model read-only accesses.
extern bool ModelReadOnlyScalars;
/// Build the Polly IR (Scop and ScopStmt) on a Region.
class ScopBuilder {
//===-------------------------------------------------------------------===//
ScopBuilder(const ScopBuilder &) = delete;
const ScopBuilder &operator=(const ScopBuilder &) = delete;
/// The AliasAnalysis to build AliasSetTracker.
AliasAnalysis &AA;
@ -312,7 +338,9 @@ public:
explicit ScopBuilder(Region *R, AssumptionCache &AC, AliasAnalysis &AA,
const DataLayout &DL, DominatorTree &DT, LoopInfo &LI,
ScopDetection &SD, ScalarEvolution &SE);
~ScopBuilder() {}
ScopBuilder(const ScopBuilder &) = delete;
ScopBuilder &operator=(const ScopBuilder &) = delete;
~ScopBuilder() = default;
/// Try to build the Polly IR of static control part on the current
/// SESE-Region.
@ -324,10 +352,4 @@ public:
} // end namespace polly
namespace llvm {
class PassRegistry;
void initializeScopInfoRegionPassPass(llvm::PassRegistry &);
void initializeScopInfoWrapperPassPass(llvm::PassRegistry &);
} // namespace llvm
#endif
#endif // POLLY_SCOPBUILDER_H

View File

@ -1,4 +1,4 @@
//===------ polly/ScopInfo.h -----------------------------------*- C++ -*-===//
//===- polly/ScopInfo.h -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -15,57 +15,83 @@
//
//===----------------------------------------------------------------------===//
#ifndef POLLY_SCOP_INFO_H
#define POLLY_SCOP_INFO_H
#ifndef POLLY_SCOPINFO_H
#define POLLY_SCOPINFO_H
#include "polly/ScopDetection.h"
#include "polly/Support/SCEVAffinator.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/Analysis/RegionPass.h"
#include "llvm/IR/PassManager.h"
#include "polly/Support/ScopHelper.h"
#include "isl/aff.h"
#include "isl/ctx.h"
#include "isl/set.h"
#include "isl-noexceptions.h"
#include <deque>
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/RegionPass.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <forward_list>
#include <functional>
#include <list>
#include <map>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace llvm;
namespace llvm {
class AssumptionCache;
class BasicBlock;
class DataLayout;
class DominatorTree;
class Function;
class Loop;
class LoopInfo;
class PHINode;
class OptimizationRemarkEmitter;
class PassRegistry;
class raw_ostream;
class ScalarEvolution;
class SCEV;
class SCEVAddRecExpr;
class Type;
} // namespace llvm
class Value;
void initializeScopInfoRegionPassPass(PassRegistry &);
void initializeScopInfoWrapperPassPass(PassRegistry &);
} // end namespace llvm
struct isl_ctx;
struct isl_map;
struct isl_basic_map;
struct isl_id;
struct isl_set;
struct isl_union_set;
struct isl_union_map;
struct isl_space;
struct isl_ast_build;
struct isl_constraint;
struct isl_pw_aff;
struct isl_pw_multi_aff;
struct isl_schedule;
struct isl_set;
struct isl_union_map;
namespace polly {
class MemoryAccess;
class Scop;
class ScopStmt;
class ScopBuilder;
//===---------------------------------------------------------------------===//
@ -217,9 +243,9 @@ enum class MemoryKind {
/// A canonical induction variable is:
/// an integer recurrence that starts at 0 and increments by one each time
/// through the loop.
typedef std::map<const Loop *, const SCEV *> LoopBoundMapType;
using LoopBoundMapType = std::map<const Loop *, const SCEV *>;
typedef std::vector<std::unique_ptr<MemoryAccess>> AccFuncVector;
using AccFuncVector = std::vector<std::unique_ptr<MemoryAccess>>;
/// A class to store information about arrays in the SCoP.
///
@ -242,6 +268,9 @@ public:
ArrayRef<const SCEV *> DimensionSizes, MemoryKind Kind,
const DataLayout &DL, Scop *S, const char *BaseName = nullptr);
/// Destructor to free the isl id of the base pointer.
~ScopArrayInfo();
/// Update the element type of the ScopArrayInfo object.
///
/// Memory accesses referencing this ScopArrayInfo object may use
@ -272,9 +301,6 @@ public:
/// since this information is available for Fortran arrays at runtime.
void applyAndSetFAD(Value *FAD);
/// Destructor to free the isl id of the base pointer.
~ScopArrayInfo();
/// Set the base pointer to @p BP.
void setBasePtr(Value *BP) { BasePtr = BP; }
@ -423,7 +449,7 @@ private:
isl::id Id;
/// True if the newly allocated array is on heap.
bool IsOnHeap;
bool IsOnHeap = false;
/// The sizes of each dimension as SCEV*.
SmallVector<const SCEV *, 4> DimensionSizes;
@ -444,7 +470,7 @@ private:
/// If this array models a Fortran array, then this points
/// to the Fortran array descriptor.
Value *FAD;
Value *FAD = nullptr;
};
/// Represent memory accesses in statements.
@ -492,9 +518,6 @@ public:
};
private:
MemoryAccess(const MemoryAccess &) = delete;
const MemoryAccess &operator=(const MemoryAccess &) = delete;
/// A unique identifier for this memory access.
///
/// The identifier is unique between all memory accesses belonging to the same
@ -584,7 +607,7 @@ private:
/// instructions in the statement using the same llvm::Value. The access
/// instruction of a write access is the instruction that defines the
/// llvm::Value.
Instruction *AccessInstruction;
Instruction *AccessInstruction = nullptr;
/// Incoming block and value of a PHINode.
SmallVector<std::pair<BasicBlock *, Value *>, 4> Incoming;
@ -602,7 +625,7 @@ private:
AssertingVH<Value> AccessValue;
/// Are all the subscripts affine expression?
bool IsAffine;
bool IsAffine = true;
/// Subscript expression for each dimension.
SmallVector<const SCEV *, 4> Subscripts;
@ -749,6 +772,8 @@ public:
/// @param AccRel The access relation that describes the memory access.
MemoryAccess(ScopStmt *Stmt, AccessType AccType, isl::map AccRel);
MemoryAccess(const MemoryAccess &) = delete;
MemoryAccess &operator=(const MemoryAccess &) = delete;
~MemoryAccess();
/// Add a new incoming block/value pairs for this PHI/ExitPHI access.
@ -931,7 +956,7 @@ public:
/// Get the FortranArrayDescriptor corresponding to this memory access if
/// it exists, and nullptr otherwise.
Value *getFortranArrayDescriptor() const { return this->FAD; };
Value *getFortranArrayDescriptor() const { return this->FAD; }
/// Is the stride of the access equal to a certain width? Schedule is a map
/// from the statement to a schedule where the innermost dimension is the
@ -1111,8 +1136,7 @@ public:
bool isAffine() const { return IsAffine; }
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
MemoryAccess::ReductionType RT);
raw_ostream &operator<<(raw_ostream &OS, MemoryAccess::ReductionType RT);
/// Ordered list type to hold accesses.
using MemoryAccessList = std::forward_list<MemoryAccess *>;
@ -1131,7 +1155,6 @@ using InvariantAccessesTy = SmallVector<InvariantAccess, 8>;
/// Type for equivalent invariant accesses and their domain context.
struct InvariantEquivClassTy {
/// The pointer that identifies this equivalence class
const SCEV *IdentifyingPointer;
@ -1167,9 +1190,6 @@ using InvariantEquivClassesTy = SmallVector<InvariantEquivClassTy, 8>;
/// At the moment every statement represents a single basic block of LLVM-IR.
class ScopStmt {
public:
ScopStmt(const ScopStmt &) = delete;
const ScopStmt &operator=(const ScopStmt &) = delete;
/// Create the ScopStmt from a BasicBlock.
ScopStmt(Scop &parent, BasicBlock &bb, Loop *SurroundingLoop,
std::vector<Instruction *> Instructions);
@ -1187,6 +1207,10 @@ public:
ScopStmt(Scop &parent, isl::map SourceRel, isl::map TargetRel,
isl::set Domain);
ScopStmt(const ScopStmt &) = delete;
const ScopStmt &operator=(const ScopStmt &) = delete;
~ScopStmt();
/// Initialize members after all MemoryAccesses have been added.
void init(LoopInfo &LI);
@ -1228,7 +1252,7 @@ private:
/// The memory accesses of this statement.
///
/// The only side effects of a statement are its memory accesses.
typedef SmallVector<MemoryAccess *, 8> MemoryAccessVec;
using MemoryAccessVec = SmallVector<MemoryAccess *, 8>;
MemoryAccessVec MemAccs;
/// Mapping from instructions to (scalar) memory accesses.
@ -1265,10 +1289,10 @@ private:
///{
/// The BasicBlock represented by this statement (in the affine case).
BasicBlock *BB;
BasicBlock *BB = nullptr;
/// The region represented by this statement (in the non-affine case).
Region *R;
Region *R = nullptr;
///}
@ -1299,17 +1323,14 @@ private:
void checkForReductions();
/// Collect loads which might form a reduction chain with @p StoreMA
void
collectCandiateReductionLoads(MemoryAccess *StoreMA,
llvm::SmallVectorImpl<MemoryAccess *> &Loads);
void collectCandiateReductionLoads(MemoryAccess *StoreMA,
SmallVectorImpl<MemoryAccess *> &Loads);
//@}
/// Remove @p MA from dictionaries pointing to them.
void removeAccessData(MemoryAccess *MA);
public:
~ScopStmt();
/// Get an isl_ctx pointer.
isl_ctx *getIslCtx() const;
@ -1549,8 +1570,8 @@ public:
/// In contrast to removeMemoryAccess(), no other access will be eliminated.
void removeSingleMemoryAccess(MemoryAccess *MA);
typedef MemoryAccessVec::iterator iterator;
typedef MemoryAccessVec::const_iterator const_iterator;
using iterator = MemoryAccessVec::iterator;
using const_iterator = MemoryAccessVec::const_iterator;
iterator begin() { return MemAccs.begin(); }
iterator end() { return MemAccs.end(); }
@ -1584,8 +1605,7 @@ public:
}
/// The range of instructions in this statement.
llvm::iterator_range<std::vector<Instruction *>::const_iterator>
insts() const {
iterator_range<std::vector<Instruction *>::const_iterator> insts() const {
return {insts_begin(), insts_end()};
}
@ -1646,8 +1666,8 @@ public:
#endif
};
/// Print ScopStmt S to raw_ostream O.
raw_ostream &operator<<(raw_ostream &O, const ScopStmt &S);
/// Print ScopStmt S to raw_ostream OS.
raw_ostream &operator<<(raw_ostream &OS, const ScopStmt &S);
/// Static Control Part
///
@ -1683,8 +1703,7 @@ public:
using MinMaxVectorPairVectorTy = SmallVector<MinMaxVectorPairTy, 4>;
private:
Scop(const Scop &) = delete;
const Scop &operator=(const Scop &) = delete;
friend class ScopBuilder;
ScalarEvolution *SE;
@ -1706,24 +1725,25 @@ private:
AccFuncVector AccessFunctions;
/// Flag to indicate that the scheduler actually optimized the SCoP.
bool IsOptimized;
bool IsOptimized = false;
/// True if the underlying region has a single exiting block.
bool HasSingleExitEdge;
/// Flag to remember if the SCoP contained an error block or not.
bool HasErrorBlock;
bool HasErrorBlock = false;
/// Max loop depth.
unsigned MaxLoopDepth;
unsigned MaxLoopDepth = 0;
/// Number of copy statements.
unsigned CopyStmtsNum;
unsigned CopyStmtsNum = 0;
/// Flag to indicate if the Scop is to be skipped.
bool SkipScop;
bool SkipScop = false;
using StmtSet = std::list<ScopStmt>;
typedef std::list<ScopStmt> StmtSet;
/// The statements in this Scop.
StmtSet Stmts;
@ -1759,18 +1779,18 @@ private:
DenseMap<BasicBlock *, isl::set> DomainMap;
/// Constraints on parameters.
isl_set *Context;
isl_set *Context = nullptr;
/// The affinator used to translate SCEVs to isl expressions.
SCEVAffinator Affinator;
typedef std::map<std::pair<AssertingVH<const Value>, MemoryKind>,
std::unique_ptr<ScopArrayInfo>>
ArrayInfoMapTy;
using ArrayInfoMapTy =
std::map<std::pair<AssertingVH<const Value>, MemoryKind>,
std::unique_ptr<ScopArrayInfo>>;
typedef StringMap<std::unique_ptr<ScopArrayInfo>> ArrayNameMapTy;
using ArrayNameMapTy = StringMap<std::unique_ptr<ScopArrayInfo>>;
typedef SetVector<ScopArrayInfo *> ArrayInfoSetTy;
using ArrayInfoSetTy = SetVector<ScopArrayInfo *>;
/// A map to remember ScopArrayInfo objects for all base pointers.
///
@ -1794,7 +1814,7 @@ private:
/// lot simpler, but which is only valid under certain assumptions. The
/// assumed context records the assumptions taken during the construction of
/// this scop and that need to be code generated as a run-time test.
isl_set *AssumedContext;
isl_set *AssumedContext = nullptr;
/// The restrictions under which this SCoP was built.
///
@ -1802,11 +1822,10 @@ private:
/// constraints over the parameters. However, while we need the constraints
/// in the assumed context to be "true" the constraints in the invalid context
/// need to be "false". Otherwise they behave the same.
isl_set *InvalidContext;
isl_set *InvalidContext = nullptr;
/// Helper struct to remember assumptions.
struct Assumption {
/// The kind of the assumption (e.g., WRAPPING).
AssumptionKind Kind;
@ -1869,7 +1888,7 @@ private:
/// set of statement instances that will be scheduled in a subtree. There
/// are also several other nodes. A full description of the different nodes
/// in a schedule tree is given in the isl manual.
isl_schedule *Schedule;
isl_schedule *Schedule = nullptr;
/// The set of minimal/maximal accesses for each alias group.
///
@ -1917,7 +1936,6 @@ private:
/// Scop constructor; invoked from ScopBuilder::buildScop.
Scop(Region &R, ScalarEvolution &SE, LoopInfo &LI,
ScopDetection::DetectionContext &DC, OptimizationRemarkEmitter &ORE);
//@}
/// Initialize this ScopBuilder.
@ -2083,7 +2101,6 @@ private:
/// for (int i = 1; i < Bound[0]; i++)
/// for (int j = 1; j < Bound[1]; j++)
/// ...
///
void verifyInvariantLoads();
/// Hoist invariant memory loads and check for required ones.
@ -2103,7 +2120,6 @@ private:
///
/// Common inv. loads: V, A[0][0], LB[0], LB[1]
/// Required inv. loads: LB[0], LB[1], (V, if it may alias with A or LB)
///
void hoistInvariantLoads();
/// Canonicalize arrays with base pointers from the same equivalence class.
@ -2278,7 +2294,7 @@ private:
/// A loop stack element to keep track of per-loop information during
/// schedule construction.
typedef struct LoopStackElement {
using LoopStackElementTy = struct LoopStackElement {
// The loop for which we keep information.
Loop *L;
@ -2292,7 +2308,7 @@ private:
LoopStackElement(Loop *L, __isl_give isl_schedule *S,
unsigned NumBlocksProcessed)
: L(L), Schedule(S), NumBlocksProcessed(NumBlocksProcessed) {}
} LoopStackElementTy;
};
/// The loop stack used for schedule construction.
///
@ -2301,7 +2317,7 @@ private:
/// schedule dimension. The loops in a loop stack always have a parent-child
/// relation where the loop at position n is the parent of the loop at
/// position n + 1.
typedef SmallVector<LoopStackElementTy, 4> LoopStackTy;
using LoopStackTy = SmallVector<LoopStackElementTy, 4>;
/// Construct schedule information for a given Region and add the
/// derived information to @p LoopStack.
@ -2350,9 +2366,9 @@ private:
void printAliasAssumptions(raw_ostream &OS) const;
//@}
friend class ScopBuilder;
public:
Scop(const Scop &) = delete;
Scop &operator=(const Scop &) = delete;
~Scop();
/// Get the count of copy statements added to this Scop.
@ -2405,10 +2421,10 @@ public:
const StringRef getName() const { return name; }
typedef ArrayInfoSetTy::iterator array_iterator;
typedef ArrayInfoSetTy::const_iterator const_array_iterator;
typedef iterator_range<ArrayInfoSetTy::iterator> array_range;
typedef iterator_range<ArrayInfoSetTy::const_iterator> const_array_range;
using array_iterator = ArrayInfoSetTy::iterator;
using const_array_iterator = ArrayInfoSetTy::const_iterator;
using array_range = iterator_range<ArrayInfoSetTy::iterator>;
using const_array_range = iterator_range<ArrayInfoSetTy::const_iterator>;
inline array_iterator array_begin() { return ScopArrayInfoSet.begin(); }
@ -2643,10 +2659,10 @@ public:
}
/// A vector of memory accesses that belong to an alias group.
typedef SmallVector<MemoryAccess *, 4> AliasGroupTy;
using AliasGroupTy = SmallVector<MemoryAccess *, 4>;
/// A vector of alias groups.
typedef SmallVector<Scop::AliasGroupTy, 4> AliasGroupVectorTy;
using AliasGroupVectorTy = SmallVector<Scop::AliasGroupTy, 4>;
/// Build the alias checks for this SCoP.
bool buildAliasChecks(AliasAnalysis &AA);
@ -2737,16 +2753,16 @@ public:
///
/// These iterators iterate over all statements of this Scop.
//@{
typedef StmtSet::iterator iterator;
typedef StmtSet::const_iterator const_iterator;
using iterator = StmtSet::iterator;
using const_iterator = StmtSet::const_iterator;
iterator begin() { return Stmts.begin(); }
iterator end() { return Stmts.end(); }
const_iterator begin() const { return Stmts.begin(); }
const_iterator end() const { return Stmts.end(); }
typedef StmtSet::reverse_iterator reverse_iterator;
typedef StmtSet::const_reverse_iterator const_reverse_iterator;
using reverse_iterator = StmtSet::reverse_iterator;
using const_reverse_iterator = StmtSet::const_reverse_iterator;
reverse_iterator rbegin() { return Stmts.rbegin(); }
reverse_iterator rend() { return Stmts.rend(); }
@ -3004,8 +3020,8 @@ public:
bool isEscaping(Instruction *Inst);
};
/// Print Scop scop to raw_ostream O.
raw_ostream &operator<<(raw_ostream &O, const Scop &scop);
/// 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.
@ -3017,7 +3033,7 @@ public:
static char ID; // Pass identification, replacement for typeid
ScopInfoRegionPass() : RegionPass(ID) {}
~ScopInfoRegionPass() {}
~ScopInfoRegionPass() override = default;
/// Build Scop object, the Polly IR of static control
/// part for the current SESE-Region.
@ -3098,13 +3114,17 @@ public:
struct ScopInfoAnalysis : public AnalysisInfoMixin<ScopInfoAnalysis> {
static AnalysisKey Key;
using Result = ScopInfo;
Result run(Function &, FunctionAnalysisManager &);
};
struct ScopInfoPrinterPass : public PassInfoMixin<ScopInfoPrinterPass> {
ScopInfoPrinterPass(raw_ostream &O) : Stream(O) {}
ScopInfoPrinterPass(raw_ostream &OS) : Stream(OS) {}
PreservedAnalyses run(Function &, FunctionAnalysisManager &);
raw_ostream &Stream;
};
@ -3121,7 +3141,7 @@ class ScopInfoWrapperPass : public FunctionPass {
public:
ScopInfoWrapperPass() : FunctionPass(ID) {}
~ScopInfoWrapperPass() = default;
~ScopInfoWrapperPass() override = default;
static char ID; // Pass identification, replacement for typeid
@ -3140,10 +3160,4 @@ public:
} // end namespace polly
namespace llvm {
class PassRegistry;
void initializeScopInfoRegionPassPass(llvm::PassRegistry &);
void initializeScopInfoWrapperPassPass(llvm::PassRegistry &);
} // namespace llvm
#endif
#endif // POLLY_SCOPINFO_H

View File

@ -1,4 +1,4 @@
//===- ScopBuilder.cpp ---------------------------------------------------===//
//===- ScopBuilder.cpp ----------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@ -16,11 +16,50 @@
#include "polly/ScopBuilder.h"
#include "polly/Options.h"
#include "polly/Support/GICHelper.h"
#include "polly/ScopDetection.h"
#include "polly/ScopDetectionDiagnostic.h"
#include "polly/ScopInfo.h"
#include "polly/Support/SCEVValidator.h"
#include "polly/Support/ScopHelper.h"
#include "polly/Support/VirtualInstruction.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/OptimizationDiagnosticInfo.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/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/DiagnosticInfo.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/IntrinsicInst.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <string>
#include <tuple>
#include <vector>
using namespace llvm;
using namespace polly;
@ -33,6 +72,7 @@ STATISTIC(InfeasibleScops,
"Number of SCoPs with statically infeasible context.");
bool polly::ModelReadOnlyScalars;
static cl::opt<bool, true> XModelReadOnlyScalars(
"polly-analyze-read-only-scalars",
cl::desc("Model read-only scalar values in the scop description"),
@ -52,7 +92,6 @@ static cl::opt<bool> DetectFortranArrays(
void ScopBuilder::buildPHIAccesses(ScopStmt *PHIStmt, PHINode *PHI,
Region *NonAffineSubRegion,
bool IsExitBlock) {
// PHI nodes that are in the exit block of the region, hence if IsExitBlock is
// true, are not modeled as ordinary PHI nodes as they are not part of the
// region. However, we model the operands in the predecessor blocks that are
@ -227,7 +266,6 @@ Value *ScopBuilder::findFADAllocationVisible(MemAccInst Inst) {
// We are looking for a "store" into a struct with the type being the Fortran
// descriptor type
for (auto user : MallocMem->users()) {
/// match: 5
auto *MallocStore = dyn_cast<StoreInst>(user);
if (!MallocStore)
@ -513,7 +551,7 @@ bool ScopBuilder::buildAccessCallInst(MemAccInst Inst, ScopStmt *Stmt) {
case FMRB_OnlyReadsArgumentPointees:
ReadOnly = true;
// Fall through
case FMRB_OnlyAccessesArgumentPointees:
case FMRB_OnlyAccessesArgumentPointees: {
auto AccType = ReadOnly ? MemoryAccess::READ : MemoryAccess::MAY_WRITE;
Loop *L = LI.getLoopFor(Inst->getParent());
for (const auto &Arg : CI->arg_operands()) {
@ -530,6 +568,7 @@ bool ScopBuilder::buildAccessCallInst(MemAccInst Inst, ScopStmt *Stmt) {
}
return true;
}
}
return true;
}
@ -579,7 +618,6 @@ void ScopBuilder::buildAccessSingleDim(MemAccInst Inst, ScopStmt *Stmt) {
}
void ScopBuilder::buildMemoryAccess(MemAccInst Inst, ScopStmt *Stmt) {
if (buildAccessMemIntrinsic(Inst, Stmt))
return;
@ -1028,7 +1066,6 @@ ScopBuilder::ScopBuilder(Region *R, AssumptionCache &AC, AliasAnalysis &AA,
const DataLayout &DL, DominatorTree &DT, LoopInfo &LI,
ScopDetection &SD, ScalarEvolution &SE)
: AA(AA), DL(DL), DT(DT), LI(LI), SD(SD), SE(SE) {
DebugLoc Beg, End;
auto P = getBBPairForRegion(R);
getDebugLocations(P, Beg, End);

View File

@ -1,4 +1,4 @@
//===--------- ScopInfo.cpp ----------------------------------------------===//
//===- ScopInfo.cpp -------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@ -21,26 +21,64 @@
#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/SCEVAffinator.h"
#include "polly/Support/SCEVValidator.h"
#include "polly/Support/ScopHelper.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopIterator.h"
#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Analysis/RegionIterator.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/DiagnosticInfo.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/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "isl/aff.h"
#include "isl/constraint.h"
#include "isl/local_space.h"
@ -53,8 +91,16 @@
#include "isl/union_map.h"
#include "isl/union_set.h"
#include "isl/val.h"
#include <sstream>
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iterator>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace llvm;
@ -185,6 +231,7 @@ static cl::opt<bool> PollyPreciseFoldAccesses(
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"),
@ -272,14 +319,13 @@ ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl::ctx Ctx,
ArrayRef<const SCEV *> Sizes, MemoryKind Kind,
const DataLayout &DL, Scop *S,
const char *BaseName)
: BasePtr(BasePtr), ElementType(ElementType), IsOnHeap(false), Kind(Kind),
DL(DL), S(*S), FAD(nullptr) {
: BasePtr(BasePtr), ElementType(ElementType), Kind(Kind), DL(DL), S(*S) {
std::string BasePtrName =
BaseName ? BaseName
: getIslCompatibleName("MemRef", BasePtr, S->getNextArrayIdx(),
Kind == MemoryKind::PHI ? "__phi" : "",
UseInstructionNames);
Id = isl::id::alloc(Ctx, BasePtrName.c_str(), this);
Id = isl::id::alloc(Ctx, BasePtrName, this);
updateSizes(Sizes);
@ -293,6 +339,8 @@ ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl::ctx Ctx,
const_cast<ScopArrayInfo *>(BasePtrOriginSAI)->addDerivedSAI(this);
}
ScopArrayInfo::~ScopArrayInfo() = default;
isl::space ScopArrayInfo::getSpace() const {
auto Space = isl::space(Id.get_ctx(), 0, getNumberOfDimensions());
Space = Space.set_tuple_id(isl::dim::set, Id);
@ -356,7 +404,7 @@ void ScopArrayInfo::applyAndSetFAD(Value *FAD) {
std::string param_name = getName();
param_name += "_fortranarr_size";
isl::id IdPwAff = isl::id::alloc(S.getIslCtx(), param_name.c_str(), this);
isl::id IdPwAff = isl::id::alloc(S.getIslCtx(), param_name, this);
Space = Space.set_dim_id(isl::dim::param, 0, IdPwAff);
isl::pw_aff PwAff =
@ -398,8 +446,6 @@ bool ScopArrayInfo::updateSizes(ArrayRef<const SCEV *> NewSizes,
return true;
}
ScopArrayInfo::~ScopArrayInfo() {}
std::string ScopArrayInfo::getName() const { return Id.get_name(); }
int ScopArrayInfo::getElemSizeInBytes() const {
@ -614,7 +660,6 @@ MemoryAccess::getReductionOperatorStr(MemoryAccess::ReductionType RT) {
return "&";
}
llvm_unreachable("Unknown reduction type");
return "";
}
/// Return the reduction type for a given binary operator.
@ -648,8 +693,6 @@ static MemoryAccess::ReductionType getReductionType(const BinaryOperator *BinOp,
}
}
MemoryAccess::~MemoryAccess() {}
const ScopArrayInfo *MemoryAccess::getOriginalScopArrayInfo() const {
isl::id ArrayId = getArrayId();
void *User = ArrayId.get_user();
@ -1002,8 +1045,8 @@ MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst,
ArrayRef<const SCEV *> Subscripts,
ArrayRef<const SCEV *> Sizes, Value *AccessValue,
MemoryKind Kind)
: Kind(Kind), AccType(AccType), RedType(RT_NONE), Statement(Stmt),
InvalidDomain(nullptr), BaseAddr(BaseAddress), ElementType(ElementType),
: Kind(Kind), AccType(AccType), Statement(Stmt), InvalidDomain(nullptr),
BaseAddr(BaseAddress), ElementType(ElementType),
Sizes(Sizes.begin(), Sizes.end()), AccessInstruction(AccessInst),
AccessValue(AccessValue), IsAffine(Affine),
Subscripts(Subscripts.begin(), Subscripts.end()), AccessRelation(nullptr),
@ -1012,14 +1055,13 @@ MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst,
const std::string Access = TypeStrings[AccType] + utostr(Stmt->size());
std::string IdName = Stmt->getBaseName() + Access;
Id = isl::id::alloc(Stmt->getParent()->getIslCtx(), IdName.c_str(), this);
Id = isl::id::alloc(Stmt->getParent()->getIslCtx(), IdName, this);
}
MemoryAccess::MemoryAccess(ScopStmt *Stmt, AccessType AccType, isl::map AccRel)
: Kind(MemoryKind::Array), AccType(AccType), RedType(RT_NONE),
Statement(Stmt), InvalidDomain(nullptr), AccessInstruction(nullptr),
IsAffine(true), AccessRelation(nullptr), NewAccessRelation(AccRel),
FAD(nullptr) {
: Kind(MemoryKind::Array), AccType(AccType), Statement(Stmt),
InvalidDomain(nullptr), AccessRelation(nullptr),
NewAccessRelation(AccRel), FAD(nullptr) {
isl::id ArrayInfoId = NewAccessRelation.get_tuple_id(isl::dim::out);
auto *SAI = ScopArrayInfo::getFromId(ArrayInfoId);
Sizes.push_back(nullptr);
@ -1031,9 +1073,11 @@ MemoryAccess::MemoryAccess(ScopStmt *Stmt, AccessType AccType, isl::map AccRel)
const std::string Access = TypeStrings[AccType] + utostr(Stmt->size());
std::string IdName = Stmt->getBaseName() + Access;
Id = isl::id::alloc(Stmt->getParent()->getIslCtx(), IdName.c_str(), this);
Id = isl::id::alloc(Stmt->getParent()->getIslCtx(), IdName, this);
}
MemoryAccess::~MemoryAccess() = default;
void MemoryAccess::realignParams() {
isl::set Ctx = Statement->getParent()->getContext();
InvalidDomain = InvalidDomain.gist_params(Ctx);
@ -1345,7 +1389,6 @@ static __isl_give isl_set *collectBoundedParts(__isl_take isl_set *S) {
/// both with regards to the dimension @p Dim.
static std::pair<__isl_give isl_set *, __isl_give isl_set *>
partitionSetParts(__isl_take isl_set *S, unsigned Dim) {
for (unsigned u = 0, e = isl_set_n_dim(S); u < e; u++)
S = isl_set_lower_bound_si(S, isl_dim_set, u, 0);
@ -1464,7 +1507,6 @@ buildConditionSets(Scop &S, BasicBlock *BB, SwitchInst *SI, Loop *L,
__isl_keep isl_set *Domain,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
Value *Condition = getConditionFromTerminator(SI);
assert(Condition && "No condition for switch");
@ -1512,7 +1554,6 @@ buildUnsignedConditionSets(Scop &S, BasicBlock *BB, Value *Condition,
const SCEV *SCEV_UpperBound,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
bool IsStrictUpperBound) {
// Do not take NonNeg assumption on TestVal
// as it might have MSB (Sign bit) set.
isl_pw_aff *TestVal = getPwAff(S, BB, InvalidDomainMap, SCEV_TestVal, false);
@ -1552,7 +1593,6 @@ buildConditionSets(Scop &S, BasicBlock *BB, Value *Condition,
TerminatorInst *TI, Loop *L, __isl_keep isl_set *Domain,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
isl_set *ConsequenceCondSet = nullptr;
if (auto *CCond = dyn_cast<ConstantInt>(Condition)) {
if (CCond->isZero())
@ -1669,7 +1709,6 @@ buildConditionSets(Scop &S, BasicBlock *BB, TerminatorInst *TI, Loop *L,
__isl_keep isl_set *Domain,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
if (SwitchInst *SI = dyn_cast<SwitchInst>(TI))
return buildConditionSets(S, BB, SI, L, Domain, InvalidDomainMap,
ConditionSets);
@ -1703,9 +1742,8 @@ void ScopStmt::collectSurroundingLoops() {
}
ScopStmt::ScopStmt(Scop &parent, Region &R, Loop *SurroundingLoop)
: Parent(parent), InvalidDomain(nullptr), Domain(nullptr), BB(nullptr),
R(&R), Build(nullptr), SurroundingLoop(SurroundingLoop) {
: Parent(parent), InvalidDomain(nullptr), Domain(nullptr), R(&R),
Build(nullptr), SurroundingLoop(SurroundingLoop) {
BaseName = getIslCompatibleName(
"Stmt", R.getNameStr(), parent.getNextStmtIdx(), "", UseInstructionNames);
}
@ -1713,17 +1751,16 @@ ScopStmt::ScopStmt(Scop &parent, Region &R, Loop *SurroundingLoop)
ScopStmt::ScopStmt(Scop &parent, BasicBlock &bb, Loop *SurroundingLoop,
std::vector<Instruction *> Instructions)
: Parent(parent), InvalidDomain(nullptr), Domain(nullptr), BB(&bb),
R(nullptr), Build(nullptr), SurroundingLoop(SurroundingLoop),
Build(nullptr), SurroundingLoop(SurroundingLoop),
Instructions(Instructions) {
BaseName = getIslCompatibleName("Stmt", &bb, parent.getNextStmtIdx(), "",
UseInstructionNames);
}
ScopStmt::ScopStmt(Scop &parent, isl::map SourceRel, isl::map TargetRel,
isl::set NewDomain)
: Parent(parent), InvalidDomain(nullptr), Domain(NewDomain), BB(nullptr),
R(nullptr), Build(nullptr) {
: Parent(parent), InvalidDomain(nullptr), Domain(NewDomain),
Build(nullptr) {
BaseName = getIslCompatibleName("CopyStmt_", "",
std::to_string(parent.getCopyStmtsNum()));
isl::id Id = isl::id::alloc(getIslCtx(), getBaseName(), this);
@ -1739,6 +1776,8 @@ ScopStmt::ScopStmt(Scop &parent, isl::map SourceRel, isl::map TargetRel,
addAccess(Access);
}
ScopStmt::~ScopStmt() = default;
void ScopStmt::init(LoopInfo &LI) {
assert(!Domain && "init must be called only once");
@ -1879,7 +1918,7 @@ std::string ScopStmt::getDomainStr() const { return Domain.to_str(); }
std::string ScopStmt::getScheduleStr() const {
auto *S = getSchedule().release();
if (!S)
return "";
return {};
auto Str = stringFromIslObj(S);
isl_map_free(S);
return Str;
@ -1909,8 +1948,6 @@ isl::space ScopStmt::getDomainSpace() const { return Domain.get_space(); }
isl::id ScopStmt::getDomainId() const { return Domain.get_tuple_id(); }
ScopStmt::~ScopStmt() {}
void ScopStmt::printInstructions(raw_ostream &OS) const {
OS << "Instructions {\n";
@ -2023,9 +2060,9 @@ MemoryAccess *ScopStmt::ensureValueRead(Value *V) {
return Access;
}
raw_ostream &polly::operator<<(raw_ostream &O, const ScopStmt &S) {
S.print(O, PollyPrintInstructions);
return O;
raw_ostream &polly::operator<<(raw_ostream &OS, const ScopStmt &S) {
S.print(OS, PollyPrintInstructions);
return OS;
}
//===----------------------------------------------------------------------===//
@ -2038,6 +2075,7 @@ void Scop::setContext(__isl_take isl_set *NewContext) {
}
namespace {
/// Remap parameter values but keep AddRecs valid wrt. invariant loads.
struct SCEVSensitiveParameterRewriter
: public SCEVRewriteVisitor<SCEVSensitiveParameterRewriter> {
@ -2096,9 +2134,11 @@ public:
}
return !FoundInside;
}
bool isDone() { return FoundInside; }
};
} // namespace
} // end anonymous namespace
const SCEV *Scop::getRepresentingInvariantLoadSCEV(const SCEV *E) const {
// Check whether it makes sense to rewrite the SCEV. (ScalarEvolution
@ -2173,7 +2213,7 @@ void Scop::createParameterId(const SCEV *Parameter) {
ParameterName = getIslCompatibleName("", ParameterName, "");
}
isl::id Id = isl::id::alloc(getIslCtx(), ParameterName.c_str(),
isl::id Id = isl::id::alloc(getIslCtx(), ParameterName,
const_cast<void *>((const void *)Parameter));
ParameterIds[Parameter] = Id;
}
@ -2551,7 +2591,6 @@ static __isl_give isl_set *getAccessDomain(MemoryAccess *MA) {
/// Wrapper function to calculate minimal/maximal accesses to each array.
static bool calculateMinMaxAccess(Scop::AliasGroupTy AliasGroup, Scop &S,
Scop::MinMaxVectorTy &MinMaxAccesses) {
MinMaxAccesses.reserve(AliasGroup.size());
isl::union_set Domains = S.getDomains();
@ -2639,7 +2678,7 @@ static inline Loop *getRegionNodeLoop(RegionNode *RN, LoopInfo &LI) {
/// @see getRegionNodeLoop for additional details.
unsigned getNumBlocksInLoop(Loop *L) {
unsigned NumBlocks = L->getNumBlocks();
SmallVector<llvm::BasicBlock *, 4> ExitBlocks;
SmallVector<BasicBlock *, 4> ExitBlocks;
L->getExitBlocks(ExitBlocks);
for (auto ExitBlock : ExitBlocks) {
@ -2695,7 +2734,6 @@ isl::set Scop::getDomainConditions(BasicBlock *BB) const {
bool Scop::buildDomains(Region *R, DominatorTree &DT, LoopInfo &LI,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
bool IsOnlyNonAffineRegion = isNonAffineSubRegion(R);
auto *EntryBB = R->getEntry();
auto *L = IsOnlyNonAffineRegion ? nullptr : LI.getLoopFor(EntryBB);
@ -2745,7 +2783,6 @@ bool Scop::buildDomains(Region *R, DominatorTree &DT, LoopInfo &LI,
static __isl_give isl_set *adjustDomainDimensions(Scop &S,
__isl_take isl_set *Dom,
Loop *OldL, Loop *NewL) {
// If the loops are the same there is nothing to do.
if (NewL == OldL)
return Dom;
@ -2790,7 +2827,6 @@ static __isl_give isl_set *adjustDomainDimensions(Scop &S,
bool Scop::propagateInvalidStmtDomains(
Region *R, DominatorTree &DT, LoopInfo &LI,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
ReversePostOrderTraversal<Region *> RTraversal(R);
for (auto *RN : RTraversal) {
@ -2875,7 +2911,6 @@ void Scop::propagateDomainConstraintsToRegionExit(
BasicBlock *BB, Loop *BBLoop,
SmallPtrSetImpl<BasicBlock *> &FinishedExitBlocks, LoopInfo &LI,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
// Check if the block @p BB is the entry of a region. If so we propagate it's
// domain to the exit block of the region. Otherwise we are done.
auto *RI = R.getRegionInfo();
@ -2920,7 +2955,6 @@ void Scop::propagateDomainConstraintsToRegionExit(
bool Scop::buildDomainsWithBranchConstraints(
Region *R, DominatorTree &DT, LoopInfo &LI,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
// To create the domain for each block in R we iterate over all blocks and
// subregions in R and propagate the conditions under which the current region
// element is executed. To this end we iterate in reverse post order over R as
@ -2935,7 +2969,6 @@ bool Scop::buildDomainsWithBranchConstraints(
SmallPtrSet<BasicBlock *, 8> FinishedExitBlocks;
ReversePostOrderTraversal<Region *> RTraversal(R);
for (auto *RN : RTraversal) {
// Recurse for affine subregions but go on for basic blocks and non-affine
// subregions.
if (RN->isSubRegion()) {
@ -3117,7 +3150,6 @@ bool Scop::propagateDomainConstraints(
ReversePostOrderTraversal<Region *> RTraversal(R);
for (auto *RN : RTraversal) {
// Recurse for affine subregions but go on for basic blocks and non-affine
// subregions.
if (RN->isSubRegion()) {
@ -3184,11 +3216,10 @@ bool Scop::addLoopBoundsToHeaderDomain(
isl::set UnionBackedgeCondition = HeaderBBDom.empty(HeaderBBDom.get_space());
SmallVector<llvm::BasicBlock *, 4> LatchBlocks;
SmallVector<BasicBlock *, 4> LatchBlocks;
L->getLoopLatches(LatchBlocks);
for (BasicBlock *LatchBB : LatchBlocks) {
// If the latch is only reachable via error statements we skip it.
isl::set LatchBBDom = DomainMap.lookup(LatchBB);
if (!LatchBBDom)
@ -3510,7 +3541,7 @@ static Loop *getLoopSurroundingScop(Scop &S, LoopInfo &LI) {
int Scop::NextScopID = 0;
std::string Scop::CurrentFunc = "";
std::string Scop::CurrentFunc;
int Scop::getNextID(std::string ParentFunc) {
if (ParentFunc != CurrentFunc) {
@ -3522,18 +3553,50 @@ int Scop::getNextID(std::string ParentFunc) {
Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, LoopInfo &LI,
ScopDetection::DetectionContext &DC, OptimizationRemarkEmitter &ORE)
: SE(&ScalarEvolution), R(R), name(R.getNameStr()), IsOptimized(false),
HasSingleExitEdge(R.getExitingBlock()), HasErrorBlock(false),
MaxLoopDepth(0), CopyStmtsNum(0), SkipScop(false), DC(DC), ORE(ORE),
IslCtx(isl_ctx_alloc(), isl_ctx_free), Context(nullptr),
Affinator(this, LI), AssumedContext(nullptr), InvalidContext(nullptr),
Schedule(nullptr),
: SE(&ScalarEvolution), R(R), name(R.getNameStr()),
HasSingleExitEdge(R.getExitingBlock()), DC(DC), ORE(ORE),
IslCtx(isl_ctx_alloc(), isl_ctx_free), Affinator(this, LI),
ID(getNextID((*R.getEntry()->getParent()).getName().str())) {
if (IslOnErrorAbort)
isl_options_set_on_error(getIslCtx(), ISL_ON_ERROR_ABORT);
buildContext();
}
Scop::~Scop() {
isl_set_free(Context);
isl_set_free(AssumedContext);
isl_set_free(InvalidContext);
isl_schedule_free(Schedule);
ParameterIds.clear();
for (auto &AS : RecordedAssumptions)
isl_set_free(AS.Set);
// Free the alias groups
for (MinMaxVectorPairTy &MinMaxAccessPair : MinMaxAliasGroups) {
for (MinMaxAccessTy &MMA : MinMaxAccessPair.first) {
isl_pw_multi_aff_free(MMA.first);
isl_pw_multi_aff_free(MMA.second);
}
for (MinMaxAccessTy &MMA : MinMaxAccessPair.second) {
isl_pw_multi_aff_free(MMA.first);
isl_pw_multi_aff_free(MMA.second);
}
}
for (const auto &IAClass : InvariantEquivClasses)
isl_set_free(IAClass.ExecutionContext);
// Explicitly release all Scop objects and the underlying isl objects before
// we release the isl context.
Stmts.clear();
ScopArrayInfoSet.clear();
ScopArrayInfoMap.clear();
ScopArrayNameMap.clear();
AccessFunctions.clear();
}
void Scop::foldSizeConstantsToRight() {
isl_union_set *Accessed = isl_union_map_range(getAccesses().release());
@ -3657,7 +3720,6 @@ void Scop::foldSizeConstantsToRight() {
isl_set_free(Elements);
}
isl_union_set_free(Accessed);
return;
}
void Scop::markFortranArrays() {
@ -3685,41 +3747,6 @@ void Scop::finalizeAccesses() {
markFortranArrays();
}
Scop::~Scop() {
isl_set_free(Context);
isl_set_free(AssumedContext);
isl_set_free(InvalidContext);
isl_schedule_free(Schedule);
ParameterIds.clear();
for (auto &AS : RecordedAssumptions)
isl_set_free(AS.Set);
// Free the alias groups
for (MinMaxVectorPairTy &MinMaxAccessPair : MinMaxAliasGroups) {
for (MinMaxAccessTy &MMA : MinMaxAccessPair.first) {
isl_pw_multi_aff_free(MMA.first);
isl_pw_multi_aff_free(MMA.second);
}
for (MinMaxAccessTy &MMA : MinMaxAccessPair.second) {
isl_pw_multi_aff_free(MMA.first);
isl_pw_multi_aff_free(MMA.second);
}
}
for (const auto &IAClass : InvariantEquivClasses)
isl_set_free(IAClass.ExecutionContext);
// Explicitly release all Scop objects and the underlying isl objects before
// we release the isl context.
Stmts.clear();
ScopArrayInfoSet.clear();
ScopArrayInfoMap.clear();
ScopArrayNameMap.clear();
AccessFunctions.clear();
}
void Scop::updateAccessDimensionality() {
// Check all array accesses for each base pointer and find a (virtual) element
// size for the base pointer that divides all access functions.
@ -3791,7 +3818,6 @@ void Scop::removeStmtNotInDomainMap() {
}
void Scop::simplifySCoP(bool AfterHoisting) {
auto ShouldDelete = [AfterHoisting](ScopStmt &Stmt) -> bool {
bool RemoveStmt = Stmt.isEmpty();
@ -3881,7 +3907,6 @@ bool Scop::canAlwaysBeHoisted(MemoryAccess *MA, bool StmtInvalidCtxIsEmpty,
}
void Scop::addInvariantLoads(ScopStmt &Stmt, InvariantAccessesTy &InvMAs) {
if (InvMAs.empty())
return;
@ -4931,7 +4956,7 @@ void Scop::buildSchedule(Region *R, LoopStackTy &LoopStack, LoopInfo &LI) {
while (!WorkList.empty() || !DelayList.empty()) {
RegionNode *RN;
if ((LastRNWaiting && !WorkList.empty()) || DelayList.size() == 0) {
if ((LastRNWaiting && !WorkList.empty()) || DelayList.empty()) {
RN = WorkList.front();
WorkList.pop_front();
LastRNWaiting = false;
@ -4955,12 +4980,9 @@ void Scop::buildSchedule(Region *R, LoopStackTy &LoopStack, LoopInfo &LI) {
}
buildSchedule(RN, LoopStack, LI);
}
return;
}
void Scop::buildSchedule(RegionNode *RN, LoopStackTy &LoopStack, LoopInfo &LI) {
if (RN->isSubRegion()) {
auto *LocalRegion = RN->getNodeAs<Region>();
if (!isNonAffineSubRegion(LocalRegion)) {
@ -5019,7 +5041,7 @@ ArrayRef<ScopStmt *> Scop::getStmtListFor(BasicBlock *BB) const {
ScopStmt *Scop::getLastStmtFor(BasicBlock *BB) const {
ArrayRef<ScopStmt *> StmtList = getStmtListFor(BB);
if (StmtList.size() > 0)
if (!StmtList.empty())
return StmtList.back();
return nullptr;
}
@ -5138,9 +5160,9 @@ bool Scop::isEscaping(Instruction *Inst) {
return false;
}
raw_ostream &polly::operator<<(raw_ostream &O, const Scop &scop) {
scop.print(O, PollyPrintInstructions);
return O;
raw_ostream &polly::operator<<(raw_ostream &OS, const Scop &scop) {
scop.print(OS, PollyPrintInstructions);
return OS;
}
//===----------------------------------------------------------------------===//