53#include "llvm/ADT/SmallPtrSet.h"
54#include "llvm/ADT/Statistic.h"
55#include "llvm/Analysis/AliasAnalysis.h"
56#include "llvm/Analysis/Delinearization.h"
57#include "llvm/Analysis/Loads.h"
58#include "llvm/Analysis/LoopInfo.h"
59#include "llvm/Analysis/OptimizationRemarkEmitter.h"
60#include "llvm/Analysis/RegionInfo.h"
61#include "llvm/Analysis/ScalarEvolution.h"
62#include "llvm/Analysis/ScalarEvolutionExpressions.h"
63#include "llvm/IR/BasicBlock.h"
64#include "llvm/IR/DebugLoc.h"
65#include "llvm/IR/DerivedTypes.h"
66#include "llvm/IR/DiagnosticInfo.h"
67#include "llvm/IR/DiagnosticPrinter.h"
68#include "llvm/IR/Dominators.h"
69#include "llvm/IR/Function.h"
70#include "llvm/IR/InstrTypes.h"
71#include "llvm/IR/Instruction.h"
72#include "llvm/IR/Instructions.h"
73#include "llvm/IR/IntrinsicInst.h"
74#include "llvm/IR/Metadata.h"
75#include "llvm/IR/Module.h"
76#include "llvm/IR/PassManager.h"
77#include "llvm/IR/Value.h"
78#include "llvm/InitializePasses.h"
80#include "llvm/Support/Debug.h"
81#include "llvm/Support/Regex.h"
82#include "llvm/Support/raw_ostream.h"
95#define DEBUG_TYPE "polly-detect"
102 "polly-detect-profitability-min-per-loop-insts",
103 cl::desc(
"The minimal number of per-loop instructions before a single loop "
104 "region is considered profitable"),
105 cl::Hidden, cl::ValueRequired, cl::init(100000000), cl::cat(
PollyCategory));
110 "polly-process-unprofitable",
112 "Process scops that are unlikely to benefit from Polly optimizations."),
117 cl::desc(
"Only run on functions that match a regex. "
118 "Multiple regexes can be comma separated. "
119 "Scop detection will run on all functions that match "
120 "ANY of the regexes provided."),
125 cl::desc(
"Ignore functions that match a regex. "
126 "Multiple regexes can be comma separated. "
127 "Scop detection will ignore all functions that match "
128 "ANY of the regexes provided."),
133static cl::opt<bool, true>
135 cl::desc(
"Allow the detection of full functions"),
141 cl::desc(
"Only run on certain regions (The provided identifier must "
142 "appear in the name of the region's entry block"),
143 cl::value_desc(
"identifier"), cl::ValueRequired, cl::init(
""),
148 cl::desc(
"Ignore possible aliasing of the array bases"),
154 "polly-allow-unsigned-operations",
155 cl::desc(
"Allow unsigned operations such as comparisons or zero-extends."),
162 "polly-use-runtime-alias-checks",
163 cl::desc(
"Use runtime alias checks to resolve possible aliasing."),
169 cl::desc(
"Print information about the activities of Polly"),
173 "polly-allow-differing-element-types",
174 cl::desc(
"Allow different element types for array accesses"), cl::Hidden,
179 cl::desc(
"Allow non affine access functions in arrays"),
184 cl::desc(
"Allow functions with known modref behavior"),
188 "polly-allow-nonaffine-branches",
189 cl::desc(
"Allow non affine conditions for branches"), cl::Hidden,
194 cl::desc(
"Allow non affine conditions for loops"),
197static cl::opt<bool, true>
199 cl::desc(
"Track failure strings in detecting scop regions"),
203static cl::opt<bool>
KeepGoing(
"polly-detect-keep-going",
204 cl::desc(
"Do not fail on the first error."),
207static cl::opt<bool, true>
209 cl::desc(
"Delinearize array access functions"),
215 cl::desc(
"Verify the detected SCoPs after each transformation"),
220static cl::opt<bool, true>
222 cl::desc(
"Hoist invariant loads."),
227 "polly-allow-error-blocks",
228 cl::desc(
"Allow to speculate on the execution of 'error blocks'."),
243STATISTIC(NumScopsDepthZero,
"Number of scops with maximal loop depth 0");
244STATISTIC(NumScopsDepthOne,
"Number of scops with maximal loop depth 1");
245STATISTIC(NumScopsDepthTwo,
"Number of scops with maximal loop depth 2");
246STATISTIC(NumScopsDepthThree,
"Number of scops with maximal loop depth 3");
247STATISTIC(NumScopsDepthFour,
"Number of scops with maximal loop depth 4");
248STATISTIC(NumScopsDepthFive,
"Number of scops with maximal loop depth 5");
250 "Number of scops with maximal loop depth 6 and larger");
251STATISTIC(NumProfScopRegions,
"Number of scops (profitable scops only)");
253 "Number of loops in scops (profitable scops only)");
256 "Number of scops with maximal loop depth 0 (profitable scops only)");
258 "Number of scops with maximal loop depth 1 (profitable scops only)");
260 "Number of scops with maximal loop depth 2 (profitable scops only)");
262 "Number of scops with maximal loop depth 3 (profitable scops only)");
264 "Number of scops with maximal loop depth 4 (profitable scops only)");
266 "Number of scops with maximal loop depth 5 (profitable scops only)");
268 "Number of scops with maximal loop depth 6 and larger "
269 "(profitable scops only)");
270STATISTIC(MaxNumLoopsInScop,
"Maximal number of loops in scops");
272 "Maximal number of loops in scops (profitable scops only)");
275 bool OnlyProfitable);
279class DiagnosticScopFound final :
public DiagnosticInfo {
281 static int PluginDiagnosticKind;
284 std::string FileName;
285 unsigned EntryLine, ExitLine;
288 DiagnosticScopFound(Function &F, std::string FileName,
unsigned EntryLine,
290 : DiagnosticInfo(PluginDiagnosticKind, DS_Note), F(F), FileName(FileName),
291 EntryLine(EntryLine), ExitLine(ExitLine) {}
293 void print(DiagnosticPrinter &DP)
const override;
295 static bool classof(
const DiagnosticInfo *DI) {
296 return DI->getKind() == PluginDiagnosticKind;
301int DiagnosticScopFound::PluginDiagnosticKind =
302 getNextAvailablePluginDiagnosticKind();
304void DiagnosticScopFound::print(DiagnosticPrinter &DP)
const {
305 DP <<
"Polly detected an optimizable loop region (scop) in function '" << F
308 if (FileName.empty()) {
309 DP <<
"Scop location is unknown. Compile with debug info "
310 "(-g) to get more precise information. ";
314 DP << FileName <<
":" << EntryLine <<
": Start of scop\n";
315 DP << FileName <<
":" << ExitLine <<
": End of scop";
322 const cl::list<std::string> &RegexList) {
323 for (
auto RegexStr : RegexList) {
328 report_fatal_error(Twine(
"invalid regex given as input to polly: ") + Err,
341 LoopInfo &LI, RegionInfo &RI, AAResults &AA,
342 OptimizationRemarkEmitter &ORE)
343 : DT(DT), SE(SE), LI(LI), RI(RI), AA(AA), ORE(ORE) {}
351 Region *TopRegion =
RI.getTopLevelRegion();
395 "Cached more results than valid regions");
398template <
class RR,
typename... Args>
400 Args &&...Arguments)
const {
403 std::shared_ptr<RR>
RejectReason = std::make_shared<RR>(Arguments...);
413 assert(!Assert &&
"Verification of detected scop failed");
431 Entry = std::make_unique<DetectionContext>(
const_cast<Region &
>(R),
AA,
447 if (!Log || !Log->hasErrors())
451 return RR->getMessage();
463 for (BasicBlock *BB : AR->blocks()) {
464 Loop *L =
LI.getLoopFor(BB);
475 const DataLayout &DL = CurRegion.getEntry()->getModule()->getDataLayout();
480 for (LoadInst *Load : RequiredILS) {
492 if (isSafeToLoadUnconditionally(Load->getPointerOperand(),
493 Load->getType(), Load->getAlign(), DL,
497 if (NonAffineRegion->contains(Load) &&
498 Load->getParent() != NonAffineRegion->getEntry())
503 Context.
RequiredILS.insert(RequiredILS.begin(), RequiredILS.end());
510 SetVector<Value *> Values;
515 SmallPtrSet<Value *, 8> PtrVals;
516 for (
auto *V : Values) {
517 if (
auto *P2I = dyn_cast<PtrToIntInst>(V))
518 V = P2I->getOperand(0);
520 if (!V->getType()->isPointerTy())
523 auto *PtrSCEV =
SE.getSCEVAtScope(V, Scope);
524 if (isa<SCEVConstant>(PtrSCEV))
527 auto *BasePtr = dyn_cast<SCEVUnknown>(
SE.getPointerBase(PtrSCEV));
531 auto *BasePtrVal = BasePtr->getValue();
532 if (PtrVals.insert(BasePtrVal).second) {
533 for (
auto *PtrVal : PtrVals)
534 if (PtrVal != BasePtrVal && !
AA.isNoAlias(PtrVal, BasePtrVal))
555 Value *Condition,
bool IsLoopBranch,
557 Loop *L =
LI.getLoopFor(&BB);
558 const SCEV *ConditionSCEV =
SE.getSCEVAtScope(Condition, L);
560 if (IsLoopBranch && L->isLoopLatch(&BB))
567 if (
isAffine(ConditionSCEV, L, Context))
574 return invalid<ReportNonAffBranch>(Context,
true, &BB,
575 ConditionSCEV, ConditionSCEV, SI);
579 Value *Condition,
bool IsLoopBranch,
582 if (isa<ConstantInt>(Condition))
585 if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Condition)) {
586 auto Opcode = BinOp->getOpcode();
587 if (Opcode == Instruction::And || Opcode == Instruction::Or) {
588 Value *Op0 = BinOp->getOperand(0);
589 Value *Op1 = BinOp->getOperand(1);
595 if (
auto PHI = dyn_cast<PHINode>(Condition)) {
596 auto *Unique = dyn_cast_or_null<ConstantInt>(
598 if (Unique && (Unique->isZero() || Unique->isOne()))
602 if (
auto Load = dyn_cast<LoadInst>(Condition))
603 if (!IsLoopBranch && Context.
CurRegion.contains(Load)) {
609 if (!isa<ICmpInst>(Condition)) {
613 return invalid<ReportInvalidCond>(Context,
true, BI, &BB);
616 ICmpInst *ICmp = cast<ICmpInst>(Condition);
619 if (isa<UndefValue>(ICmp->getOperand(0)) ||
620 isa<UndefValue>(ICmp->getOperand(1)))
621 return invalid<ReportUndefOperand>(Context,
true, &BB, ICmp);
623 Loop *L =
LI.getLoopFor(&BB);
624 const SCEV *LHS =
SE.getSCEVAtScope(ICmp->getOperand(0), L);
625 const SCEV *RHS =
SE.getSCEVAtScope(ICmp->getOperand(1), L);
654 return invalid<ReportNonAffBranch>(Context,
true, &BB, LHS, RHS,
659 bool AllowUnreachable,
663 Instruction *TI = BB.getTerminator();
665 if (AllowUnreachable && isa<UnreachableInst>(TI))
669 if (isa<ReturnInst>(TI) && CurRegion.isTopLevelRegion())
675 return invalid<ReportInvalidTerminator>(Context,
true, &BB);
678 if (isa<UndefValue>(Condition))
679 return invalid<ReportUndefCond>(Context,
true, TI, &BB);
681 if (BranchInst *BI = dyn_cast<BranchInst>(TI))
682 return isValidBranch(BB, BI, Condition, IsLoopBranch, Context);
684 SwitchInst *SI = dyn_cast<SwitchInst>(TI);
685 assert(SI &&
"Terminator was neither branch nor switch");
687 return isValidSwitch(BB, SI, Condition, IsLoopBranch, Context);
692 if (CI.doesNotReturn())
695 if (CI.doesNotAccessMemory())
698 if (
auto *II = dyn_cast<IntrinsicInst>(&CI))
702 Function *CalledFunction = CI.getCalledFunction();
705 if (CalledFunction ==
nullptr)
709 POLLY_DEBUG(dbgs() <<
"Allow call to debug function: "
710 << CalledFunction->getName() <<
'\n');
715 MemoryEffects ME =
AA.getMemoryEffects(CalledFunction);
716 if (ME.onlyAccessesArgPointees()) {
717 for (
const auto &Arg : CI.args()) {
718 if (!Arg->getType()->isPointerTy())
723 auto *ArgSCEV =
SE.getSCEVAtScope(Arg,
LI.getLoopFor(CI.getParent()));
724 if (ArgSCEV->isZero())
727 auto *BP = dyn_cast<SCEVUnknown>(
SE.getPointerBase(ArgSCEV));
738 Context.
AST.addUnknown(&CI);
742 if (ME.onlyReadsMemory()) {
748 Context.
AST.addUnknown(&CI);
763 Loop *L =
LI.getLoopFor(II.getParent());
767 const SCEVUnknown *BP;
769 switch (II.getIntrinsicID()) {
771 case Intrinsic::memmove:
772 case Intrinsic::memcpy:
773 AF =
SE.getSCEVAtScope(cast<MemTransferInst>(II).getSource(), L);
775 BP = dyn_cast<SCEVUnknown>(
SE.getPointerBase(AF));
781 case Intrinsic::memset:
782 AF =
SE.getSCEVAtScope(cast<MemIntrinsic>(II).getDest(), L);
784 BP = dyn_cast<SCEVUnknown>(
SE.getPointerBase(AF));
791 if (!
isAffine(
SE.getSCEVAtScope(cast<MemIntrinsic>(II).getLength(), L), L,
806 if (isa<Argument>(Val) || isa<Constant>(Val))
809 Instruction *I = dyn_cast<Instruction>(&Val);
813 if (!Reg.contains(I))
819 if (
auto LI = dyn_cast<LoadInst>(I)) {
820 Ctx.RequiredILS.insert(
LI);
841class SCEVRemoveMax final :
public SCEVRewriteVisitor<SCEVRemoveMax> {
843 SCEVRemoveMax(ScalarEvolution &SE, std::vector<const SCEV *> *Terms)
844 : SCEVRewriteVisitor(SE), Terms(Terms) {}
846 static const SCEV *rewrite(
const SCEV *Scev, ScalarEvolution &SE,
847 std::vector<const SCEV *> *Terms =
nullptr) {
848 SCEVRemoveMax Rewriter(SE, Terms);
849 return Rewriter.visit(Scev);
852 const SCEV *visitSMaxExpr(
const SCEVSMaxExpr *Expr) {
853 if ((Expr->getNumOperands() == 2) && Expr->getOperand(0)->isZero()) {
854 auto Res = visit(Expr->getOperand(1));
856 (*Terms).push_back(
Res);
864 std::vector<const SCEV *> *Terms;
868SmallVector<const SCEV *, 4>
870 const SCEVUnknown *BasePointer)
const {
871 SmallVector<const SCEV *, 4> Terms;
872 for (
const auto &
Pair : Context.
Accesses[BasePointer]) {
873 std::vector<const SCEV *> MaxTerms;
874 SCEVRemoveMax::rewrite(
Pair.second,
SE, &MaxTerms);
875 if (!MaxTerms.empty()) {
876 Terms.insert(Terms.begin(), MaxTerms.begin(), MaxTerms.end());
887 if (
auto *AF = dyn_cast<SCEVAddExpr>(
Pair.second)) {
888 for (
auto Op : AF->operands()) {
889 if (
auto *AF2 = dyn_cast<SCEVAddRecExpr>(Op))
890 collectParametricTerms(
SE, AF2, Terms);
891 if (
auto *AF2 = dyn_cast<SCEVMulExpr>(Op)) {
892 SmallVector<const SCEV *, 0> Operands;
894 for (
auto *MulOp : AF2->operands()) {
895 if (
auto *Const = dyn_cast<SCEVConstant>(MulOp))
896 Operands.push_back(Const);
897 if (
auto *Unknown = dyn_cast<SCEVUnknown>(MulOp)) {
898 if (
auto *Inst = dyn_cast<Instruction>(Unknown->getValue())) {
900 Operands.push_back(MulOp);
903 Operands.push_back(MulOp);
908 Terms.push_back(
SE.getMulExpr(Operands));
913 collectParametricTerms(
SE,
Pair.second, Terms);
919 SmallVectorImpl<const SCEV *> &Sizes,
920 const SCEVUnknown *BasePointer,
928 if (Sizes.size() == 0)
931 Value *BaseValue = BasePointer->getValue();
933 for (
const SCEV *DelinearizedSize : Sizes) {
936 if (!
isAffine(DelinearizedSize,
nullptr, Context)) {
940 if (
auto *Unknown = dyn_cast<SCEVUnknown>(DelinearizedSize)) {
941 auto *V = dyn_cast<Value>(Unknown->getValue());
942 if (
auto *Load = dyn_cast<LoadInst>(V)) {
951 return invalid<ReportNonAffineAccess>(
952 Context,
true, DelinearizedSize,
953 Context.
Accesses[BasePointer].front().first, BaseValue);
961 for (
const auto &
Pair : Context.
Accesses[BasePointer]) {
962 const Instruction *Insn =
Pair.first;
963 const SCEV *AF =
Pair.second;
965 if (!
isAffine(AF, Scope, Context)) {
966 invalid<ReportNonAffineAccess>(Context,
true, AF, Insn,
985 std::shared_ptr<ArrayShape> Shape)
const {
986 Value *BaseValue = BasePointer->getValue();
987 bool BasePtrHasNonAffine =
false;
989 for (
const auto &
Pair : Context.
Accesses[BasePointer]) {
990 const Instruction *Insn =
Pair.first;
991 auto *AF =
Pair.second;
992 AF = SCEVRemoveMax::rewrite(AF,
SE);
993 bool IsNonAffine =
false;
994 TempMemoryAccesses.insert(std::make_pair(Insn,
MemAcc(Insn, Shape)));
995 MemAcc *Acc = &TempMemoryAccesses.find(Insn)->second;
996 auto *Scope =
LI.getLoopFor(Insn->getParent());
1004 if (Shape->DelinearizedSizes.size() == 0) {
1008 Shape->DelinearizedSizes);
1019 BasePtrHasNonAffine =
true;
1021 invalid<ReportNonAffineAccess>(Context,
true,
Pair.second,
1029 if (!BasePtrHasNonAffine)
1030 Context.
InsnToMemAcc.insert(TempMemoryAccesses.begin(),
1031 TempMemoryAccesses.end());
1037 const SCEVUnknown *BasePointer,
1038 Loop *Scope)
const {
1039 auto Shape = std::shared_ptr<ArrayShape>(
new ArrayShape(BasePointer));
1043 findArrayDimensions(
SE, Terms, Shape->DelinearizedSizes,
1060 auto *BasePointer =
Pair.first;
1061 auto *Scope =
Pair.second;
1072 const SCEVUnknown *BP,
1076 return invalid<ReportNoBasePtr>(Context,
true, Inst);
1078 auto *BV = BP->getValue();
1079 if (isa<UndefValue>(BV))
1080 return invalid<ReportUndefBasePtr>(Context,
true, Inst);
1083 if (IntToPtrInst *Inst = dyn_cast<IntToPtrInst>(BV))
1084 return invalid<ReportIntToPtr>(Context,
true, Inst);
1089 return invalid<ReportVariantBasePtr>(Context,
true, BV, Inst);
1091 AF =
SE.getMinusSCEV(AF, BP);
1094 if (!isa<MemIntrinsic>(Inst)) {
1095 Size =
SE.getElementSize(Inst);
1098 SE.getEffectiveSCEVType(PointerType::getUnqual(
SE.getContext()));
1099 Size =
SE.getConstant(SizeTy, 8);
1104 return invalid<ReportDifferentArrayElementSize>(Context,
true,
1112 bool IsVariantInNonAffineLoop =
false;
1113 SetVector<const Loop *> Loops;
1115 for (
const Loop *L : Loops)
1117 IsVariantInNonAffineLoop =
true;
1119 auto *Scope =
LI.getLoopFor(Inst->getParent());
1120 bool IsAffine = !IsVariantInNonAffineLoop &&
isAffine(AF, Scope, Context);
1122 if (isa<MemIntrinsic>(Inst) && !IsAffine) {
1123 return invalid<ReportNonAffineAccess>(Context,
true, AF, Inst,
1126 Context.
Accesses[BP].push_back({Inst, AF});
1130 std::make_pair(BP,
LI.getLoopFor(Inst->getParent())));
1132 return invalid<ReportNonAffineAccess>(Context,
true, AF, Inst,
1141 AAMDNodes AATags = Inst->getAAMetadata();
1142 AliasSet &AS = Context.
AST.getAliasSetFor(
1143 MemoryLocation::getBeforeOrAfter(BP->getValue(), AATags));
1145 if (!AS.isMustAlias()) {
1147 bool CanBuildRunTimeCheck =
true;
1154 auto ASPointers = AS.getPointers();
1162 const unsigned int VariantSize = VariantLS.size(),
1163 InvariantSize = InvariantLS.size();
1165 for (
const Value *Ptr : ASPointers) {
1166 Instruction *Inst = dyn_cast<Instruction>(
const_cast<Value *
>(Ptr));
1167 if (Inst && Context.
CurRegion.contains(Inst)) {
1168 auto *Load = dyn_cast<LoadInst>(Inst);
1169 if (Load && InvariantLS.count(Load))
1173 if (VariantLS.count(Load))
1174 VariantLS.remove(Load);
1176 InvariantLS.insert(Load);
1178 CanBuildRunTimeCheck =
false;
1179 VariantLS.insert(Load);
1184 if (InvariantSize == InvariantLS.size() &&
1185 VariantSize == VariantLS.size())
1189 if (CanBuildRunTimeCheck)
1192 return invalid<ReportAlias>(Context,
true, Inst, AS);
1201 Loop *L =
LI.getLoopFor(Inst->getParent());
1202 const SCEV *AccessFunction =
SE.getSCEVAtScope(Ptr, L);
1203 const SCEVUnknown *BasePointer;
1205 BasePointer = dyn_cast<SCEVUnknown>(
SE.getPointerBase(AccessFunction));
1207 return isValidAccess(Inst, AccessFunction, BasePointer, Context);
1212 for (
auto &Op : Inst.operands()) {
1213 auto *OpInst = dyn_cast<Instruction>(&Op);
1219 auto *
PHI = dyn_cast<PHINode>(OpInst);
1221 for (User *U :
PHI->users()) {
1222 auto *UI = dyn_cast<Instruction>(U);
1223 if (!UI || !UI->isTerminator())
1232 if (isa<LandingPadInst>(&Inst) || isa<ResumeInst>(&Inst))
1236 if (CallInst *CI = dyn_cast<CallInst>(&Inst)) {
1240 return invalid<ReportFuncCall>(Context,
true, &Inst);
1243 if (!Inst.mayReadOrWriteMemory()) {
1244 if (!isa<AllocaInst>(Inst))
1247 return invalid<ReportAlloca>(Context,
true, &Inst);
1252 Context.
hasStores |= isa<StoreInst>(MemInst);
1253 Context.
hasLoads |= isa<LoadInst>(MemInst);
1254 if (!MemInst.isSimple())
1255 return invalid<ReportNonSimpleMemoryAccess>(Context,
true,
1262 return invalid<ReportUnknownInst>(Context,
true, &Inst);
1271 SmallVector<BasicBlock *, 4> ExitingBlocks;
1272 L->getExitingBlocks(ExitingBlocks);
1273 return !ExitingBlocks.empty();
1288 SmallVector<BasicBlock *, 4> LoopControlBlocks;
1289 L->getExitingBlocks(LoopControlBlocks);
1290 L->getLoopLatches(LoopControlBlocks);
1291 for (BasicBlock *ControlBB : LoopControlBlocks) {
1292 if (!
isValidCFG(*ControlBB,
true,
false, Context)) {
1334 return invalid<ReportLoopHasNoExit>(Context,
true, L);
1340 SmallVector<BasicBlock *, 4> ExitBlocks;
1341 L->getExitBlocks(ExitBlocks);
1342 BasicBlock *TheExitBlock = ExitBlocks[0];
1343 for (BasicBlock *ExitBB : ExitBlocks) {
1344 if (TheExitBlock != ExitBB)
1345 return invalid<ReportLoopHasMultipleExits>(Context,
true, L);
1352 Region *R =
RI.getRegionFor(L->getHeader());
1353 while (R != &Context.
CurRegion && !R->contains(L))
1360 const SCEV *LoopCount =
SE.getBackedgeTakenCount(L);
1361 return invalid<ReportLoopBound>(Context,
true, L, LoopCount);
1368 unsigned MinProfitableTrips) {
1369 auto *TripCount =
SE.getBackedgeTakenCount(L);
1372 int MaxLoopDepth = 1;
1373 if (MinProfitableTrips > 0)
1374 if (
auto *TripCountC = dyn_cast<SCEVConstant>(TripCount))
1375 if (TripCountC->getType()->getScalarSizeInBits() <= 64)
1376 if (TripCountC->getValue()->getZExtValue() <= MinProfitableTrips)
1379 for (
auto &SubLoop : *L) {
1382 MaxLoopDepth = std::max(MaxLoopDepth, Stats.
MaxDepth + 1);
1385 return {NumLoops, MaxLoopDepth};
1390 LoopInfo &LI,
unsigned MinProfitableTrips) {
1392 int MaxLoopDepth = 0;
1394 auto L =
LI.getLoopFor(R->getEntry());
1398 if (L && R->contains(L)) {
1399 L = R->outermostLoopInRegion(L);
1400 L = L->getParentLoop();
1404 L ? L->getSubLoopsVector() : std::vector<Loop *>(
LI.begin(),
LI.end());
1406 for (
auto &SubLoop : SubLoops)
1407 if (R->contains(SubLoop)) {
1411 MaxLoopDepth = std::max(MaxLoopDepth, Stats.
MaxDepth);
1414 return {LoopNum, MaxLoopDepth};
1418 const DominatorTree &DT) {
1419 if (isa<UnreachableInst>(BB.getTerminator()))
1422 if (LI.isLoopHeader(&BB))
1427 if (!R.contains(&BB))
1432 bool DominatesAllPredecessors =
true;
1433 if (R.isTopLevelRegion()) {
1434 for (BasicBlock &I : *R.getEntry()->getParent()) {
1435 if (isa<ReturnInst>(I.getTerminator()) && !DT.dominates(&BB, &I)) {
1436 DominatesAllPredecessors =
false;
1441 for (
auto Pred : predecessors(R.getExit())) {
1442 if (R.contains(Pred) && !DT.dominates(&BB, Pred)) {
1443 DominatesAllPredecessors =
false;
1449 if (DominatesAllPredecessors)
1452 for (Instruction &Inst : BB)
1453 if (CallInst *CI = dyn_cast<CallInst>(&Inst)) {
1461 if (isa<MemSetInst>(CI) || isa<MemTransferInst>(CI))
1464 if (!CI->doesNotAccessMemory())
1466 if (CI->doesNotReturn())
1479 return It.first->getSecond();
1482 It.first->second = Result;
1488 std::unique_ptr<Region> LastValidRegion;
1489 auto ExpandedRegion = std::unique_ptr<Region>(R.getExpandedRegion());
1491 POLLY_DEBUG(dbgs() <<
"\tExpanding " << R.getNameStr() <<
"\n");
1493 while (ExpandedRegion) {
1496 Entry = std::make_unique<DetectionContext>(*ExpandedRegion,
AA,
1500 POLLY_DEBUG(dbgs() <<
"\t\tTrying " << ExpandedRegion->getNameStr()
1516 if (LastValidRegion) {
1520 LastValidRegion = std::move(ExpandedRegion);
1524 std::unique_ptr<Region>(LastValidRegion->getExpandedRegion());
1531 std::unique_ptr<Region>(ExpandedRegion->getExpandedRegion());
1536 if (LastValidRegion)
1537 dbgs() <<
"\tto " << LastValidRegion->getNameStr() <<
"\n";
1539 dbgs() <<
"\tExpanding " << R.getNameStr() <<
" failed\n";
1542 return LastValidRegion.release();
1546 for (
const BasicBlock *BB : R.blocks())
1547 if (R.contains(LI.getLoopFor(BB)))
1554 for (
auto &SubRegion : R) {
1567 std::unique_ptr<DetectionContext> &
Entry =
1569 Entry = std::make_unique<DetectionContext>(R,
AA,
false);
1572 bool DidBailout =
true;
1574 invalid<ReportUnprofitable>(Context,
true, &R);
1581 "With -polly-detect-keep-going, it is sufficient that if "
1582 "isValidRegion short-circuited, that SCoP is invalid");
1585 "isValidRegion must short-circuit iff the ScoP is invalid");
1595 for (
auto &SubRegion : R)
1604 std::vector<Region *> ToExpand;
1606 for (
auto &SubRegion : R)
1607 ToExpand.push_back(SubRegion.get());
1609 for (Region *CurrentRegion : ToExpand) {
1625 R.addSubRegion(ExpandedR,
true);
1635 for (
const BasicBlock *BB : CurRegion.blocks()) {
1636 Loop *L =
LI.getLoopFor(BB);
1637 if (L && L->getHeader() == BB) {
1638 if (CurRegion.contains(L)) {
1645 SmallVector<BasicBlock *, 1> Latches;
1646 L->getLoopLatches(Latches);
1647 for (BasicBlock *Latch : Latches)
1648 if (CurRegion.contains(Latch))
1649 return invalid<ReportLoopOnlySomeLatches>(Context,
true,
1655 for (BasicBlock *BB : CurRegion.blocks()) {
1667 for (BasicBlock::iterator I = BB->begin(), E = --BB->end(); I != E; ++I)
1682 int NumLoops)
const {
1688 for (
auto *BB : Context.
CurRegion.blocks())
1689 if (Context.
CurRegion.contains(
LI.getLoopFor(BB)))
1690 InstCount += BB->size();
1692 InstCount = InstCount / NumLoops;
1699 for (
auto *BB : Context.
CurRegion.blocks()) {
1700 auto *L =
LI.getLoopFor(BB);
1705 unsigned StmtsWithStoresInLoops = 0;
1706 for (
auto *LBB : L->blocks()) {
1707 bool MemStore =
false;
1708 for (
auto &I : *LBB)
1709 MemStore |= isa<StoreInst>(&I);
1710 StmtsWithStoresInLoops += MemStore;
1712 return (StmtsWithStoresInLoops > 1);
1726 return invalid<ReportUnprofitable>(Context,
true, &CurRegion);
1730 int NumAffineLoops = NumLoops - Context.
BoxedLoopsSet.size();
1734 if (NumAffineLoops >= 2)
1750 return invalid<ReportUnprofitable>(Context,
true, &CurRegion);
1756 POLLY_DEBUG(dbgs() <<
"Checking region: " << CurRegion.getNameStr()
1760 POLLY_DEBUG(dbgs() <<
"Top level region is invalid\n");
1766 if (CurRegion.getExit() &&
1767 isa<UnreachableInst>(CurRegion.getExit()->getTerminator())) {
1769 return invalid<ReportUnreachableInExit>(Context,
true,
1770 CurRegion.getExit(), DbgLoc);
1774 !CurRegion.getEntry()->getName().count(
OnlyRegion)) {
1776 dbgs() <<
"Region entry does not match -polly-only-region";
1783 for (BasicBlock *Pred : predecessors(CurRegion.getEntry())) {
1784 Instruction *PredTerm = Pred->getTerminator();
1785 if (isa<IndirectBrInst>(PredTerm) || isa<CallBrInst>(PredTerm))
1786 return invalid<ReportIndirectPredecessor>(
1787 Context,
true, PredTerm, PredTerm->getDebugLoc());
1793 CurRegion.getEntry() ==
1794 &(CurRegion.getEntry()->getParent()->getEntryBlock()))
1795 return invalid<ReportEntry>(Context,
true, CurRegion.getEntry());
1806 return invalid<ReportIrreducibleRegion>(Context,
true,
1807 &CurRegion, DbgLoc);
1822 for (
const Region *R : *
this) {
1823 unsigned LineEntry, LineExit;
1824 std::string FileName;
1827 DiagnosticScopFound Diagnostic(F, FileName, LineEntry, LineExit);
1828 F.getContext().diagnose(Diagnostic);
1846 enum Color { WHITE, GREY, BLACK };
1848 BasicBlock *REntry = R.getEntry();
1849 BasicBlock *RExit = R.getExit();
1851 DenseMap<const BasicBlock *, Color> BBColorMap;
1853 std::stack<std::pair<BasicBlock *, unsigned>> DFSStack;
1855 unsigned AdjacentBlockIndex = 0;
1856 BasicBlock *CurrBB, *SuccBB;
1860 for (
auto *BB : R.blocks())
1861 BBColorMap[BB] = WHITE;
1864 BBColorMap[CurrBB] = GREY;
1865 DFSStack.push(std::make_pair(CurrBB, 0));
1867 while (!DFSStack.empty()) {
1869 CurrBB = DFSStack.top().first;
1870 AdjacentBlockIndex = DFSStack.top().second;
1874 const Instruction *TInst = CurrBB->getTerminator();
1875 unsigned NSucc = TInst->getNumSuccessors();
1876 for (
unsigned I = AdjacentBlockIndex; I < NSucc;
1877 ++I, ++AdjacentBlockIndex) {
1878 SuccBB = TInst->getSuccessor(I);
1881 if (SuccBB == RExit || SuccBB == CurrBB)
1885 if (BBColorMap[SuccBB] == WHITE) {
1887 DFSStack.push(std::make_pair(CurrBB, I + 1));
1889 DFSStack.push(std::make_pair(SuccBB, 0));
1891 BBColorMap[SuccBB] = GREY;
1893 }
else if (BBColorMap[SuccBB] == GREY) {
1897 if (!
DT.dominates(SuccBB, CurrBB)) {
1899 DbgLoc = TInst->getDebugLoc();
1907 if (AdjacentBlockIndex == NSucc)
1908 BBColorMap[CurrBB] = BLACK;
1915 bool OnlyProfitable) {
1916 if (!OnlyProfitable) {
1919 std::max(MaxNumLoopsInScop.getValue(), (uint64_t)Stats.
NumLoops);
1921 NumScopsDepthZero++;
1927 NumScopsDepthThree++;
1929 NumScopsDepthFour++;
1931 NumScopsDepthFive++;
1933 NumScopsDepthLarger++;
1935 NumLoopsInProfScop += Stats.
NumLoops;
1936 MaxNumLoopsInProfScop =
1937 std::max(MaxNumLoopsInProfScop.getValue(), (uint64_t)Stats.
NumLoops);
1939 NumProfScopsDepthZero++;
1941 NumProfScopsDepthOne++;
1943 NumProfScopsDepthTwo++;
1945 NumProfScopsDepthThree++;
1947 NumProfScopsDepthFour++;
1949 NumProfScopsDepthFive++;
1951 NumProfScopsDepthLarger++;
1960 return DCMIt->second.get();
1965 return DC ? &DC->
Log :
nullptr;
1984 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1985 auto &RI = getAnalysis<RegionInfoPass>().getRegionInfo();
1986 auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
1987 auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
1988 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1989 auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
1991 Result = std::make_unique<ScopDetection>(DT, SE, LI, RI, AA, ORE);
1997 AU.addRequired<LoopInfoWrapperPass>();
1998 AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
1999 AU.addRequired<DominatorTreeWrapperPass>();
2000 AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
2002 AU.addRequiredTransitive<AAResultsWrapperPass>();
2003 AU.addRequiredTransitive<RegionInfoPass>();
2004 AU.setPreservesAll();
2008 for (
const Region *R :
Result->ValidRegions)
2009 OS <<
"Valid Region for Scop: " << R->getNameStr() <<
'\n';
2033 auto &LI = FAM.getResult<LoopAnalysis>(F);
2034 auto &RI = FAM.getResult<RegionInfoAnalysis>(F);
2035 auto &AA = FAM.getResult<AAManager>(F);
2036 auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(F);
2037 auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
2038 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
2046 FunctionAnalysisManager &FAM) {
2047 OS <<
"Detected Scops in Function " << F.getName() <<
"\n";
2049 for (
const Region *R : SD.ValidRegions)
2050 OS <<
"Valid Region for Scop: " << R->getNameStr() <<
'\n';
2053 return PreservedAnalyses::all();
2061 "Polly - Detect static control parts (SCoPs)",
false,
2070 "Polly - Detect static control parts (SCoPs)",
false,
false)
2076class ScopDetectionPrinterLegacyPass final :
public FunctionPass {
2080 ScopDetectionPrinterLegacyPass() : ScopDetectionPrinterLegacyPass(outs()) {}
2082 explicit ScopDetectionPrinterLegacyPass(llvm::raw_ostream &OS)
2083 : FunctionPass(ID), OS(OS) {}
2085 bool runOnFunction(
Function &F)
override {
2088 OS <<
"Printing analysis '" << P.getPassName() <<
"' for function '"
2089 << F.getName() <<
"':\n";
2095 void getAnalysisUsage(AnalysisUsage &AU)
const override {
2096 FunctionPass::getAnalysisUsage(AU);
2098 AU.setPreservesAll();
2102 llvm::raw_ostream &OS;
2105char ScopDetectionPrinterLegacyPass::ID = 0;
2109 return new ScopDetectionPrinterLegacyPass(OS);
2113 "Polly - Print static control parts (SCoPs)",
false,
2117 "Polly - Print static control parts (SCoPs)",
false,
false)
static cl::opt< bool > Verify("polly-codegen-verify", cl::desc("Verify the function generated by Polly"), cl::Hidden, cl::cat(PollyCategory))
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 const unsigned MIN_LOOP_TRIP_COUNT
The minimal trip count under which loops are considered unprofitable.
static cl::opt< bool, true > XPollyProcessUnprofitable("polly-process-unprofitable", cl::desc("Process scops that are unlikely to benefit from Polly optimizations."), cl::location(PollyProcessUnprofitable), cl::cat(PollyCategory))
static cl::opt< bool > AllowDifferentTypes("polly-allow-differing-element-types", cl::desc("Allow different element types for array accesses"), cl::Hidden, cl::init(true), cl::cat(PollyCategory))
static cl::opt< bool > AllowNonAffine("polly-allow-nonaffine", cl::desc("Allow non affine access functions in arrays"), cl::Hidden, cl::cat(PollyCategory))
STATISTIC(NumScopRegions, "Number of scops")
static cl::list< std::string > OnlyFunctions("polly-only-func", cl::desc("Only run on functions that match a regex. " "Multiple regexes can be comma separated. " "Scop detection will run on all functions that match " "ANY of the regexes provided."), cl::CommaSeparated, cl::cat(PollyCategory))
static cl::opt< bool > VerifyScops("polly-detect-verify", cl::desc("Verify the detected SCoPs after each transformation"), cl::Hidden, cl::cat(PollyCategory))
static bool hasExitingBlocks(Loop *L)
Check whether L has exiting blocks.
static cl::opt< std::string > OnlyRegion("polly-only-region", cl::desc("Only run on certain regions (The provided identifier must " "appear in the name of the region's entry block"), cl::value_desc("identifier"), cl::ValueRequired, cl::init(""), cl::cat(PollyCategory))
static bool regionWithoutLoops(Region &R, LoopInfo &LI)
static cl::opt< bool > KeepGoing("polly-detect-keep-going", cl::desc("Do not fail on the first error."), cl::Hidden, cl::cat(PollyCategory))
static cl::opt< int > ProfitabilityMinPerLoopInstructions("polly-detect-profitability-min-per-loop-insts", cl::desc("The minimal number of per-loop instructions before a single loop " "region is considered profitable"), cl::Hidden, cl::ValueRequired, cl::init(100000000), cl::cat(PollyCategory))
static cl::opt< bool, true > TrackFailures("polly-detect-track-failures", cl::desc("Track failure strings in detecting scop regions"), cl::location(PollyTrackFailures), cl::Hidden, cl::init(true), cl::cat(PollyCategory))
static bool doesStringMatchAnyRegex(StringRef Str, const cl::list< std::string > &RegexList)
Check if a string matches any regex in a list of regexes.
static cl::opt< bool > PollyAllowErrorBlocks("polly-allow-error-blocks", cl::desc("Allow to speculate on the execution of 'error blocks'."), cl::Hidden, cl::init(true), cl::cat(PollyCategory))
static cl::list< std::string > IgnoredFunctions("polly-ignore-func", cl::desc("Ignore functions that match a regex. " "Multiple regexes can be comma separated. " "Scop detection will ignore all functions that match " "ANY of the regexes provided."), cl::CommaSeparated, cl::cat(PollyCategory))
static cl::opt< bool > ReportLevel("polly-report", cl::desc("Print information about the activities of Polly"), cl::cat(PollyCategory))
static bool isErrorBlockImpl(BasicBlock &BB, const Region &R, LoopInfo &LI, const DominatorTree &DT)
static cl::opt< bool, true > PollyDelinearizeX("polly-delinearize", cl::desc("Delinearize array access functions"), cl::location(PollyDelinearize), cl::Hidden, cl::init(true), cl::cat(PollyCategory))
static cl::opt< bool, true > XPollyAllowUnsignedOperations("polly-allow-unsigned-operations", cl::desc("Allow unsigned operations such as comparisons or zero-extends."), cl::location(PollyAllowUnsignedOperations), cl::Hidden, cl::init(true), cl::cat(PollyCategory))
static void updateLoopCountStatistic(ScopDetection::LoopStats Stats, bool OnlyProfitable)
static cl::opt< bool > AllowNonAffineSubRegions("polly-allow-nonaffine-branches", cl::desc("Allow non affine conditions for branches"), cl::Hidden, cl::init(true), cl::cat(PollyCategory))
static cl::opt< bool, true > XAllowFullFunction("polly-detect-full-functions", cl::desc("Allow the detection of full functions"), cl::location(polly::PollyAllowFullFunction), cl::init(false), cl::cat(PollyCategory))
static cl::opt< bool, true > XPollyInvariantLoadHoisting("polly-invariant-load-hoisting", cl::desc("Hoist invariant loads."), cl::location(PollyInvariantLoadHoisting), cl::Hidden, cl::cat(PollyCategory))
static cl::opt< bool > AllowNonAffineSubLoops("polly-allow-nonaffine-loops", cl::desc("Allow non affine conditions for loops"), cl::Hidden, cl::cat(PollyCategory))
static cl::opt< bool, true > XPollyUseRuntimeAliasChecks("polly-use-runtime-alias-checks", cl::desc("Use runtime alias checks to resolve possible aliasing."), cl::location(PollyUseRuntimeAliasChecks), cl::Hidden, cl::init(true), cl::cat(PollyCategory))
static cl::opt< bool > IgnoreAliasing("polly-ignore-aliasing", cl::desc("Ignore possible aliasing of the array bases"), cl::Hidden, cl::cat(PollyCategory))
static cl::opt< bool > AllowModrefCall("polly-allow-modref-calls", cl::desc("Allow functions with known modref behavior"), cl::Hidden, cl::cat(PollyCategory))
Utility proxy to wrap the common members of LoadInst and StoreInst.
static MemAccInst dyn_cast(llvm::Value &V)
llvm::Value * getPointerOperand() const
Stores all errors that occurred during the detection.
void report(RejectReasonPtr Reject)
bool hasErrors() const
Returns true, if we store at least one error.
Base class of all reject reasons found during Scop detection.
virtual std::string getMessage() const =0
Generate a reasonable diagnostic message describing this error.
std::unique_ptr< ScopDetection > Result
void releaseMemory() override
void getAnalysisUsage(AnalysisUsage &AU) const override
ScopDetectionWrapperPass()
void print(raw_ostream &OS, const Module *M=nullptr) const override
bool runOnFunction(Function &F) override
Pass to detect the maximal static control parts (Scops) of a function.
static void markFunctionAsInvalid(Function *F)
Mark the function as invalid so we will not extract any scop from the function.
bool addOverApproximatedRegion(Region *AR, DetectionContext &Context) const
Add the region AR as over approximated sub-region in Context.
bool isValidAccess(Instruction *Inst, const SCEV *AF, const SCEVUnknown *BP, DetectionContext &Context) const
Check if the memory access caused by Inst is valid.
bool onlyValidRequiredInvariantLoads(InvariantLoadsSetTy &RequiredILS, DetectionContext &Context) const
Check if the given loads could be invariant and can be hoisted.
bool isInvariant(Value &Val, const Region &Reg, DetectionContext &Ctx) const
Check if a value is invariant in the region Reg.
bool isReducibleRegion(Region &R, DebugLoc &DbgLoc) const
Check if a region is reducible or not.
bool computeAccessFunctions(DetectionContext &Context, const SCEVUnknown *BasePointer, std::shared_ptr< ArrayShape > Shape) const
Derive access functions for a given base pointer.
DetectionContext * getDetectionContext(const Region *R) const
Return the detection context for R, nullptr if R was invalid.
void removeCachedResultsRecursively(const Region &R)
Remove cached results for the children of R recursively.
bool hasSufficientCompute(DetectionContext &Context, int NumAffineLoops) const
Check if a region has sufficient compute instructions.
bool isProfitableRegion(DetectionContext &Context) const
Check if a region is profitable to optimize.
void emitMissedRemarks(const Function &F)
Emit rejection remarks for all rejected regions.
bool isValidLoop(Loop *L, DetectionContext &Context)
Is a loop valid with respect to a given region.
static ScopDetection::LoopStats countBeneficialLoops(Region *R, ScalarEvolution &SE, LoopInfo &LI, unsigned MinProfitableTrips)
Count the number of loops and the maximal loop depth in R.
const RejectLog * lookupRejectionLog(const Region *R) const
Return the set of rejection causes for R.
bool involvesMultiplePtrs(const SCEV *S0, const SCEV *S1, Loop *Scope) const
Check if S0 and S1 do contain multiple possibly aliasing pointers.
bool isValidSwitch(BasicBlock &BB, SwitchInst *SI, Value *Condition, bool IsLoopBranch, DetectionContext &Context) const
Check if the switch SI with condition Condition is valid.
bool isValidRegion(DetectionContext &Context)
Check if a region is a Scop.
Region * expandRegion(Region &R)
Try to expand the region R.
const DominatorTree & DT
Analyses used.
bool hasBaseAffineAccesses(DetectionContext &Context, const SCEVUnknown *BasePointer, Loop *Scope) const
Check if all accesses to a given BasePointer are affine.
OptimizationRemarkEmitter & ORE
OptimizationRemarkEmitter object used to emit diagnostic remarks.
bool hasAffineMemoryAccesses(DetectionContext &Context) const
Delinearize all non affine memory accesses and return false when there exists a non affine memory acc...
bool isValidMemoryAccess(MemAccInst Inst, DetectionContext &Context) const
Check if a memory access can be part of a Scop.
bool isValidCFG(BasicBlock &BB, bool IsLoopBranch, bool AllowUnreachable, DetectionContext &Context)
Check if the control flow in a basic block is valid.
void printLocations(Function &F)
Print the locations of all detected scops.
bool hasValidArraySizes(DetectionContext &Context, SmallVectorImpl< const SCEV * > &Sizes, const SCEVUnknown *BasePointer, Loop *Scope) const
Check if the dimension size of a delinearized array is valid.
DenseMap< std::tuple< const BasicBlock *, const Region * >, bool > ErrorBlockCache
Cache for the isErrorBlock function.
void removeCachedResults(const Region &R)
Remove cached results for R.
ScopDetection(const DominatorTree &DT, ScalarEvolution &SE, LoopInfo &LI, RegionInfo &RI, AAResults &AA, OptimizationRemarkEmitter &ORE)
bool isValidBranch(BasicBlock &BB, BranchInst *BI, Value *Condition, bool IsLoopBranch, DetectionContext &Context)
Check if the branch BI with condition Condition is valid.
bool hasPossiblyDistributableLoop(DetectionContext &Context) const
Check if the unique affine loop might be amendable to distribution.
void verifyAnalysis()
Verify if all valid Regions in this Function are still valid after some transformations.
SmallVector< const SCEV *, 4 > getDelinearizationTerms(DetectionContext &Context, const SCEVUnknown *BasePointer) const
Find for a given base pointer terms that hint towards dimension sizes of a multi-dimensional array.
bool isValidInstruction(Instruction &Inst, DetectionContext &Context)
Check if an instruction can be part of a Scop.
bool isAffine(const SCEV *S, Loop *Scope, DetectionContext &Context) const
Check if the SCEV S is affine in the current Context.
DetectionContextMapTy DetectionContextMap
bool allBlocksValid(DetectionContext &Context)
Check if all basic block in the region are valid.
void findScops(Region &R)
Find the Scops in this region tree.
bool isValidIntrinsicInst(IntrinsicInst &II, DetectionContext &Context) const
Check if an intrinsic call can be part of a Scop.
std::string regionIsInvalidBecause(const Region *R) const
Get a message why a region is invalid.
bool isMaxRegionInScop(const Region &R, bool Verify=true)
Is the region is the maximum region of a Scop?
bool isValidCallInst(CallInst &CI, DetectionContext &Context) const
Check if a call instruction can be part of a Scop.
void verifyRegion(const Region &R)
Verify if R is still a valid part of Scop after some transformations.
static bool isValidFunction(Function &F)
Check if the function F is marked as invalid.
bool isErrorBlock(llvm::BasicBlock &BB, const llvm::Region &R)
Check if the block is a error block.
bool invalid(DetectionContext &Context, bool Assert, Args &&...Arguments) const
Track diagnostics for invalid scops.
bool canUseISLTripCount(Loop *L, DetectionContext &Context)
Can ISL compute the trip count of a loop.
static ScopDetection::LoopStats countBeneficialSubLoops(Loop *L, ScalarEvolution &SE, unsigned MinProfitableTrips)
Count the number of loops and the maximal loop depth in L.
This file contains the declaration of the PolyhedralInfo class, which will provide an interface to ex...
std::pair< llvm::BasicBlock *, llvm::BasicBlock * > BBPair
Type to hold region delimiters (entry & exit block).
void findValues(const llvm::SCEV *Expr, llvm::ScalarEvolution &SE, llvm::SetVector< llvm::Value * > &Values)
Find the values referenced by SCEVUnknowns in a given SCEV expression.
void findLoops(const llvm::SCEV *Expr, llvm::SetVector< const llvm::Loop * > &Loops)
Find the loops referenced from a SCEV expression.
llvm::Value * getConditionFromTerminator(llvm::Instruction *TI)
Return the condition for the terminator TI.
StringRef PollySkipFnAttr
A function attribute which will cause Polly to skip the function.
bool PollyAllowFullFunction
std::shared_ptr< RejectReason > RejectReasonPtr
bool isAffineExpr(const llvm::Region *R, llvm::Loop *Scope, const llvm::SCEV *Expression, llvm::ScalarEvolution &SE, InvariantLoadsSetTy *ILS=nullptr)
@ Value
MemoryKind::Value: Models an llvm::Value.
@ PHI
MemoryKind::PHI: Models PHI nodes within the SCoP.
void emitRejectionRemarks(const BBPair &P, const RejectLog &Log, OptimizationRemarkEmitter &ORE)
Emit optimization remarks about the rejected regions to the user.
void getDebugLocation(const llvm::Region *R, unsigned &LineBegin, unsigned &LineEnd, std::string &FileName)
Get the location of a region from the debug info.
const llvm::SCEV * tryForwardThroughPHI(const llvm::SCEV *Expr, llvm::Region &R, llvm::ScalarEvolution &SE, ScopDetection *SD)
Try to look through PHI nodes, where some incoming edges come from error blocks.
bool isDebugCall(llvm::Instruction *Inst)
Is the given instruction a call to a debug function?
BBPair getBBPairForRegion(const Region *R)
Return the region delimiters (entry & exit block) of R.
bool PollyProcessUnprofitable
llvm::Pass * createScopDetectionPrinterLegacyPass(llvm::raw_ostream &OS)
llvm::SetVector< llvm::AssertingVH< llvm::LoadInst > > InvariantLoadsSetTy
Type for a set of invariant loads.
std::map< const Instruction *, MemAcc > MapInsnToMemAcc
bool isHoistableLoad(llvm::LoadInst *LInst, llvm::Region &R, llvm::LoopInfo &LI, llvm::ScalarEvolution &SE, const llvm::DominatorTree &DT, const InvariantLoadsSetTy &KnownInvariantLoads)
Check if LInst can be hoisted in R.
bool PollyUseRuntimeAliasChecks
bool hasScalarDepsInsideRegion(const llvm::SCEV *Expr, const llvm::Region *R, llvm::Loop *Scope, bool AllowLoops, const InvariantLoadsSetTy &ILS)
Returns true when the SCEV contains references to instructions within the region.
bool PollyAllowUnsignedOperations
llvm::Value * getUniqueNonErrorValue(llvm::PHINode *PHI, llvm::Region *R, ScopDetection *SD)
Return a unique non-error block incoming value for PHI if available.
bool PollyInvariantLoadHoisting
bool isIgnoredIntrinsic(const llvm::Value *V)
Return true iff V is an intrinsic that we ignore during code generation.
llvm::Pass * createScopDetectionWrapperPassPass()
SmallVector< const SCEV *, 4 > DelinearizedSubscripts
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
Result run(Function &F, FunctionAnalysisManager &FAM)
Context variables for SCoP detection.
BaseToAFs Accesses
Map a base pointer to all access functions accessing it.
InvariantLoadsSetTy RequiredILS
Loads that need to be invariant during execution.
bool hasLoads
The region has at least one load instruction.
bool IsInvalid
If this flag is set, the SCoP must eventually be rejected, even with KeepGoing.
bool HasUnknownAccess
Flag to indicate the region has at least one unknown access.
BoxedLoopsSetTy BoxedLoopsSet
The set of loops contained in non-affine regions.
MapInsnToMemAcc InsnToMemAcc
Map to memory access description for the corresponding LLVM instructions.
RejectLog Log
Container to remember rejection reasons for this region.
RegionSet NonAffineSubRegionSet
The set of non-affine subregions in the region we analyze.
llvm::SetVector< std::pair< const SCEVUnknown *, Loop * > > NonAffineAccesses
The set of base pointers with non-affine accesses.
bool hasStores
The region has at least one store instruction.
Helper data structure to collect statistics about loop counts.