Polly 24.0.0git
ScopDetection.cpp
Go to the documentation of this file.
1//===- ScopDetection.cpp - Detect Scops -----------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Detect the maximal Scops of a function.
10//
11// A static control part (Scop) is a subgraph of the control flow graph (CFG)
12// that only has statically known control flow and can therefore be described
13// within the polyhedral model.
14//
15// Every Scop fulfills these restrictions:
16//
17// * It is a single entry single exit region
18//
19// * Only affine linear bounds in the loops
20//
21// Every natural loop in a Scop must have a number of loop iterations that can
22// be described as an affine linear function in surrounding loop iterators or
23// parameters. (A parameter is a scalar that does not change its value during
24// execution of the Scop).
25//
26// * Only comparisons of affine linear expressions in conditions
27//
28// * All loops and conditions perfectly nested
29//
30// The control flow needs to be structured such that it could be written using
31// just 'for' and 'if' statements, without the need for any 'goto', 'break' or
32// 'continue'.
33//
34// * Side effect free functions call
35//
36// Function calls and intrinsics that do not have side effects (readnone)
37// or memory intrinsics (memset, memcpy, memmove) are allowed.
38//
39// The Scop detection finds the largest Scops by checking if the largest
40// region is a Scop. If this is not the case, its canonical subregions are
41// checked until a region is a Scop. It is now tried to extend this Scop by
42// creating a larger non canonical region.
43//
44//===----------------------------------------------------------------------===//
45
46#include "polly/ScopDetection.h"
47#include "polly/Options.h"
52#include "llvm/ADT/SmallPtrSet.h"
53#include "llvm/ADT/Statistic.h"
54#include "llvm/Analysis/AliasAnalysis.h"
55#include "llvm/Analysis/Delinearization.h"
56#include "llvm/Analysis/Loads.h"
57#include "llvm/Analysis/LoopInfo.h"
58#include "llvm/Analysis/OptimizationRemarkEmitter.h"
59#include "llvm/Analysis/RegionInfo.h"
60#include "llvm/Analysis/ScalarEvolution.h"
61#include "llvm/Analysis/ScalarEvolutionExpressions.h"
62#include "llvm/IR/BasicBlock.h"
63#include "llvm/IR/DebugLoc.h"
64#include "llvm/IR/DerivedTypes.h"
65#include "llvm/IR/DiagnosticInfo.h"
66#include "llvm/IR/DiagnosticPrinter.h"
67#include "llvm/IR/Dominators.h"
68#include "llvm/IR/Function.h"
69#include "llvm/IR/InstrTypes.h"
70#include "llvm/IR/Instruction.h"
71#include "llvm/IR/Instructions.h"
72#include "llvm/IR/IntrinsicInst.h"
73#include "llvm/IR/Metadata.h"
74#include "llvm/IR/Module.h"
75#include "llvm/IR/Value.h"
76#include "llvm/Support/Debug.h"
77#include "llvm/Support/Regex.h"
78#include "llvm/Support/raw_ostream.h"
79#include <algorithm>
80#include <cassert>
81#include <memory>
82#include <stack>
83#include <string>
84#include <utility>
85#include <vector>
86
87using namespace llvm;
88using namespace polly;
89
91#define DEBUG_TYPE "polly-detect"
92
93// This option is set to a very high value, as analyzing such loops increases
94// compile time on several cases. For experiments that enable this option,
95// a value of around 40 has been working to avoid run-time regressions with
96// Polly while still exposing interesting optimization opportunities.
98 "polly-detect-profitability-min-per-loop-insts",
99 cl::desc("The minimal number of per-loop instructions before a single loop "
100 "region is considered profitable"),
101 cl::Hidden, cl::ValueRequired, cl::init(100000000), cl::cat(PollyCategory));
102
104
105static cl::opt<bool, true> XPollyProcessUnprofitable(
106 "polly-process-unprofitable",
107 cl::desc(
108 "Process scops that are unlikely to benefit from Polly optimizations."),
109 cl::location(PollyProcessUnprofitable), cl::cat(PollyCategory));
110
111static cl::list<std::string> OnlyFunctions(
112 "polly-only-func",
113 cl::desc("Only run on functions that match a regex. "
114 "Multiple regexes can be comma separated. "
115 "Scop detection will run on all functions that match "
116 "ANY of the regexes provided."),
117 cl::CommaSeparated, cl::cat(PollyCategory));
118
119static cl::list<std::string> IgnoredFunctions(
120 "polly-ignore-func",
121 cl::desc("Ignore functions that match a regex. "
122 "Multiple regexes can be comma separated. "
123 "Scop detection will ignore all functions that match "
124 "ANY of the regexes provided."),
125 cl::CommaSeparated, cl::cat(PollyCategory));
126
128
129static cl::opt<bool, true>
130 XAllowFullFunction("polly-detect-full-functions",
131 cl::desc("Allow the detection of full functions"),
132 cl::location(polly::PollyAllowFullFunction),
133 cl::init(false), cl::cat(PollyCategory));
134
135static cl::opt<std::string> OnlyRegion(
136 "polly-only-region",
137 cl::desc("Only run on certain regions (The provided identifier must "
138 "appear in the name of the region's entry block"),
139 cl::value_desc("identifier"), cl::ValueRequired, cl::init(""),
140 cl::cat(PollyCategory));
141
142static cl::opt<bool>
143 IgnoreAliasing("polly-ignore-aliasing",
144 cl::desc("Ignore possible aliasing of the array bases"),
145 cl::Hidden, cl::cat(PollyCategory));
146
148
149static cl::opt<bool, true> XPollyAllowUnsignedOperations(
150 "polly-allow-unsigned-operations",
151 cl::desc("Allow unsigned operations such as comparisons or zero-extends."),
152 cl::location(PollyAllowUnsignedOperations), cl::Hidden, cl::init(true),
153 cl::cat(PollyCategory));
154
156
157static cl::opt<bool, true> XPollyUseRuntimeAliasChecks(
158 "polly-use-runtime-alias-checks",
159 cl::desc("Use runtime alias checks to resolve possible aliasing."),
160 cl::location(PollyUseRuntimeAliasChecks), cl::Hidden, cl::init(true),
161 cl::cat(PollyCategory));
162
163static cl::opt<bool>
164 ReportLevel("polly-report",
165 cl::desc("Print information about the activities of Polly"),
166 cl::cat(PollyCategory));
167
168static cl::opt<bool> AllowDifferentTypes(
169 "polly-allow-differing-element-types",
170 cl::desc("Allow different element types for array accesses"), cl::Hidden,
171 cl::init(true), cl::cat(PollyCategory));
172
173static cl::opt<bool>
174 AllowNonAffine("polly-allow-nonaffine",
175 cl::desc("Allow non affine access functions in arrays"),
176 cl::Hidden, cl::cat(PollyCategory));
177
178static cl::opt<bool>
179 AllowModrefCall("polly-allow-modref-calls",
180 cl::desc("Allow functions with known modref behavior"),
181 cl::Hidden, cl::cat(PollyCategory));
182
183static cl::opt<bool> AllowNonAffineSubRegions(
184 "polly-allow-nonaffine-branches",
185 cl::desc("Allow non affine conditions for branches"), cl::Hidden,
186 cl::init(true), cl::cat(PollyCategory));
187
188static cl::opt<bool>
189 AllowNonAffineSubLoops("polly-allow-nonaffine-loops",
190 cl::desc("Allow non affine conditions for loops"),
191 cl::Hidden, cl::cat(PollyCategory));
192
193static cl::opt<bool, true>
194 TrackFailures("polly-detect-track-failures",
195 cl::desc("Track failure strings in detecting scop regions"),
196 cl::location(PollyTrackFailures), cl::Hidden, cl::init(true),
197 cl::cat(PollyCategory));
198
199static cl::opt<bool> KeepGoing("polly-detect-keep-going",
200 cl::desc("Do not fail on the first error."),
201 cl::Hidden, cl::cat(PollyCategory));
202
203static cl::opt<bool, true>
204 PollyDelinearizeX("polly-delinearize",
205 cl::desc("Delinearize array access functions"),
206 cl::location(PollyDelinearize), cl::Hidden,
207 cl::init(true), cl::cat(PollyCategory));
208
209static cl::opt<bool>
210 VerifyScops("polly-detect-verify",
211 cl::desc("Verify the detected SCoPs after each transformation"),
212 cl::Hidden, cl::cat(PollyCategory));
213
215
216static cl::opt<bool, true>
217 XPollyInvariantLoadHoisting("polly-invariant-load-hoisting",
218 cl::desc("Hoist invariant loads."),
219 cl::location(PollyInvariantLoadHoisting),
220 cl::Hidden, cl::cat(PollyCategory));
221
222static cl::opt<bool> PollyAllowErrorBlocks(
223 "polly-allow-error-blocks",
224 cl::desc("Allow to speculate on the execution of 'error blocks'."),
225 cl::Hidden, cl::init(true), cl::cat(PollyCategory));
226
227/// The minimal trip count under which loops are considered unprofitable.
228static const unsigned MIN_LOOP_TRIP_COUNT = 8;
229
232StringRef polly::PollySkipFnAttr = "polly.skip.fn";
233
234//===----------------------------------------------------------------------===//
235// Statistics.
236
237STATISTIC(NumScopRegions, "Number of scops");
238STATISTIC(NumLoopsInScop, "Number of loops in scops");
239STATISTIC(NumScopsDepthZero, "Number of scops with maximal loop depth 0");
240STATISTIC(NumScopsDepthOne, "Number of scops with maximal loop depth 1");
241STATISTIC(NumScopsDepthTwo, "Number of scops with maximal loop depth 2");
242STATISTIC(NumScopsDepthThree, "Number of scops with maximal loop depth 3");
243STATISTIC(NumScopsDepthFour, "Number of scops with maximal loop depth 4");
244STATISTIC(NumScopsDepthFive, "Number of scops with maximal loop depth 5");
245STATISTIC(NumScopsDepthLarger,
246 "Number of scops with maximal loop depth 6 and larger");
247STATISTIC(NumProfScopRegions, "Number of scops (profitable scops only)");
248STATISTIC(NumLoopsInProfScop,
249 "Number of loops in scops (profitable scops only)");
250STATISTIC(NumLoopsOverall, "Number of total loops");
251STATISTIC(NumProfScopsDepthZero,
252 "Number of scops with maximal loop depth 0 (profitable scops only)");
253STATISTIC(NumProfScopsDepthOne,
254 "Number of scops with maximal loop depth 1 (profitable scops only)");
255STATISTIC(NumProfScopsDepthTwo,
256 "Number of scops with maximal loop depth 2 (profitable scops only)");
257STATISTIC(NumProfScopsDepthThree,
258 "Number of scops with maximal loop depth 3 (profitable scops only)");
259STATISTIC(NumProfScopsDepthFour,
260 "Number of scops with maximal loop depth 4 (profitable scops only)");
261STATISTIC(NumProfScopsDepthFive,
262 "Number of scops with maximal loop depth 5 (profitable scops only)");
263STATISTIC(NumProfScopsDepthLarger,
264 "Number of scops with maximal loop depth 6 and larger "
265 "(profitable scops only)");
266STATISTIC(MaxNumLoopsInScop, "Maximal number of loops in scops");
267STATISTIC(MaxNumLoopsInProfScop,
268 "Maximal number of loops in scops (profitable scops only)");
269
271 bool OnlyProfitable);
272
273namespace {
274
275class DiagnosticScopFound final : public DiagnosticInfo {
276private:
277 static int PluginDiagnosticKind;
278
279 Function &F;
280 std::string FileName;
281 unsigned EntryLine, ExitLine;
282
283public:
284 DiagnosticScopFound(Function &F, std::string FileName, unsigned EntryLine,
285 unsigned ExitLine)
286 : DiagnosticInfo(PluginDiagnosticKind, DS_Note), F(F), FileName(FileName),
287 EntryLine(EntryLine), ExitLine(ExitLine) {}
288
289 void print(DiagnosticPrinter &DP) const override;
290
291 static bool classof(const DiagnosticInfo *DI) {
292 return DI->getKind() == PluginDiagnosticKind;
293 }
294};
295} // namespace
296
297int DiagnosticScopFound::PluginDiagnosticKind =
298 getNextAvailablePluginDiagnosticKind();
299
300void DiagnosticScopFound::print(DiagnosticPrinter &DP) const {
301 DP << "Polly detected an optimizable loop region (scop) in function '" << F
302 << "'\n";
303
304 if (FileName.empty()) {
305 DP << "Scop location is unknown. Compile with debug info "
306 "(-g) to get more precise information. ";
307 return;
308 }
309
310 DP << FileName << ":" << EntryLine << ": Start of scop\n";
311 DP << FileName << ":" << ExitLine << ": End of scop";
312}
313
314/// Check if a string matches any regex in a list of regexes.
315/// @param Str the input string to match against.
316/// @param RegexList a list of strings that are regular expressions.
317static bool doesStringMatchAnyRegex(StringRef Str,
318 const cl::list<std::string> &RegexList) {
319 for (auto RegexStr : RegexList) {
320 Regex R(RegexStr);
321
322 std::string Err;
323 if (!R.isValid(Err))
324 report_fatal_error(Twine("invalid regex given as input to polly: ") + Err,
325 true);
326
327 if (R.match(Str))
328 return true;
329 }
330 return false;
331}
332
333//===----------------------------------------------------------------------===//
334// ScopDetection.
335
336ScopDetection::ScopDetection(const DominatorTree &DT, ScalarEvolution &SE,
337 LoopInfo &LI, RegionInfo &RI, AAResults &AA,
338 OptimizationRemarkEmitter &ORE)
339 : DT(DT), SE(SE), LI(LI), RI(RI), AA(AA), ORE(ORE) {}
340
341void ScopDetection::detect(Function &F) {
342 assert(ValidRegions.empty() && "Detection must run only once");
343
344 if (!PollyProcessUnprofitable && LI.empty())
345 return;
346
347 Region *TopRegion = RI.getTopLevelRegion();
348
349 if (!OnlyFunctions.empty() &&
351 return;
352
354 return;
355
356 if (!isValidFunction(F))
357 return;
358
359 findScops(*TopRegion);
360
361 NumScopRegions += ValidRegions.size();
362
363 // Prune non-profitable regions.
364 for (auto &DIt : DetectionContextMap) {
365 DetectionContext &DC = *DIt.getSecond();
366 if (DC.Log.hasErrors())
367 continue;
368 if (!ValidRegions.count(&DC.CurRegion))
369 continue;
370 LoopStats Stats = countBeneficialLoops(&DC.CurRegion, SE, LI, 0);
371 updateLoopCountStatistic(Stats, false /* OnlyProfitable */);
372 if (isProfitableRegion(DC)) {
373 updateLoopCountStatistic(Stats, true /* OnlyProfitable */);
374 continue;
375 }
376
377 ValidRegions.remove(&DC.CurRegion);
378 }
379
380 NumProfScopRegions += ValidRegions.size();
381 NumLoopsOverall += countBeneficialLoops(TopRegion, SE, LI, 0).NumLoops;
382
383 // Only makes sense when we tracked errors.
386
387 if (ReportLevel)
389
390 assert(ValidRegions.size() <= DetectionContextMap.size() &&
391 "Cached more results than valid regions");
392}
393
394template <class RR, typename... Args>
395inline bool ScopDetection::invalid(DetectionContext &Context, bool Assert,
396 Args &&...Arguments) const {
397 if (!Context.Verifying) {
398 RejectLog &Log = Context.Log;
399 std::shared_ptr<RR> RejectReason = std::make_shared<RR>(Arguments...);
400 Context.IsInvalid = true;
401
402 // Log even if PollyTrackFailures is false, the log entries are also used in
403 // canUseISLTripCount().
404 Log.report(RejectReason);
405
406 POLLY_DEBUG(dbgs() << RejectReason->getMessage());
407 POLLY_DEBUG(dbgs() << "\n");
408 } else {
409 assert(!Assert && "Verification of detected scop failed");
410 }
411
412 return false;
413}
414
415bool ScopDetection::isMaxRegionInScop(const Region &R, bool Verify) {
416 if (!ValidRegions.count(&R))
417 return false;
418
419 if (Verify) {
421 std::unique_ptr<DetectionContext> &Entry = DetectionContextMap[P];
422
423 // Free previous DetectionContext for the region and create and verify a new
424 // one. Be sure that the DetectionContext is not still used by a ScopInfop.
425 // Due to changes but CodeGeneration of another Scop, the Region object and
426 // the BBPair might not match anymore.
427 Entry = std::make_unique<DetectionContext>(const_cast<Region &>(R), AA,
428 /*Verifying=*/false);
429
430 return isValidRegion(*Entry);
431 }
432
433 return true;
434}
435
436std::string ScopDetection::regionIsInvalidBecause(const Region *R) const {
437 // Get the first error we found. Even in keep-going mode, this is the first
438 // reason that caused the candidate to be rejected.
439 auto *Log = lookupRejectionLog(R);
440
441 // This can happen when we marked a region invalid, but didn't track
442 // an error for it.
443 if (!Log || !Log->hasErrors())
444 return "";
445
446 RejectReasonPtr RR = *Log->begin();
447 return RR->getMessage();
448}
449
451 DetectionContext &Context) const {
452 // If we already know about Ar we can exit.
453 if (!Context.NonAffineSubRegionSet.insert(AR))
454 return true;
455
456 // All loops in the region have to be overapproximated too if there
457 // are accesses that depend on the iteration count.
458
459 for (BasicBlock *BB : AR->blocks()) {
460 Loop *L = LI.getLoopFor(BB);
461 if (AR->contains(L))
462 Context.BoxedLoopsSet.insert(L);
463 }
464
465 return (AllowNonAffineSubLoops || Context.BoxedLoopsSet.empty());
466}
467
469 InvariantLoadsSetTy &RequiredILS, DetectionContext &Context) const {
470 Region &CurRegion = Context.CurRegion;
471 const DataLayout &DL = CurRegion.getEntry()->getModule()->getDataLayout();
472
473 if (!PollyInvariantLoadHoisting && !RequiredILS.empty())
474 return false;
475
476 for (LoadInst *Load : RequiredILS) {
477 // If we already know a load has been accepted as required invariant, we
478 // already run the validation below once and consequently don't need to
479 // run it again. Hence, we return early. For certain test cases (e.g.,
480 // COSMO this avoids us spending 50% of scop-detection time in this
481 // very function (and its children).
482 if (Context.RequiredILS.count(Load))
483 continue;
484 if (!isHoistableLoad(Load, CurRegion, LI, SE, DT, Context.RequiredILS))
485 return false;
486
487 for (auto NonAffineRegion : Context.NonAffineSubRegionSet) {
488 if (isSafeToLoadUnconditionally(Load->getPointerOperand(),
489 Load->getType(), Load->getAlign(), DL,
490 nullptr))
491 continue;
492
493 if (NonAffineRegion->contains(Load) &&
494 Load->getParent() != NonAffineRegion->getEntry())
495 return false;
496 }
497 }
498
499 Context.RequiredILS.insert_range(RequiredILS);
500
501 return true;
502}
503
504bool ScopDetection::involvesMultiplePtrs(const SCEV *S0, const SCEV *S1,
505 Loop *Scope) const {
506 SetVector<Value *> Values;
507 findValues(S0, SE, Values);
508 if (S1)
509 findValues(S1, SE, Values);
510
511 SmallPtrSet<Value *, 8> PtrVals;
512 for (auto *V : Values) {
513 if (auto *P2I = dyn_cast<PtrToIntInst>(V))
514 V = P2I->getOperand(0);
515
516 if (!V->getType()->isPointerTy())
517 continue;
518
519 const SCEV *PtrSCEV = SE.getSCEVAtScope(V, Scope);
520 if (isa<SCEVConstant>(PtrSCEV))
521 continue;
522
523 auto *BasePtr = dyn_cast<SCEVUnknown>(SE.getPointerBase(PtrSCEV));
524 if (!BasePtr)
525 return true;
526
527 Value *BasePtrVal = BasePtr->getValue();
528 if (PtrVals.insert(BasePtrVal).second) {
529 for (auto *PtrVal : PtrVals)
530 if (PtrVal != BasePtrVal && !AA.isNoAlias(PtrVal, BasePtrVal))
531 return true;
532 }
533 }
534
535 return false;
536}
537
538bool ScopDetection::isAffine(const SCEV *S, Loop *Scope,
539 DetectionContext &Context) const {
540 InvariantLoadsSetTy AccessILS;
541 if (!isAffineExpr(&Context.CurRegion, Scope, S, SE, &AccessILS))
542 return false;
543
544 if (!onlyValidRequiredInvariantLoads(AccessILS, Context))
545 return false;
546
547 return true;
548}
549
550bool ScopDetection::isValidSwitch(BasicBlock &BB, SwitchInst *SI,
551 Value *Condition, bool IsLoopBranch,
552 DetectionContext &Context) const {
553 Loop *L = LI.getLoopFor(&BB);
554 const SCEV *ConditionSCEV = SE.getSCEVAtScope(Condition, L);
555
556 if (IsLoopBranch && L->isLoopLatch(&BB))
557 return false;
558
559 // Check for invalid usage of different pointers in one expression.
560 if (involvesMultiplePtrs(ConditionSCEV, nullptr, L))
561 return false;
562
563 if (isAffine(ConditionSCEV, L, Context))
564 return true;
565
567 addOverApproximatedRegion(RI.getRegionFor(&BB), Context))
568 return true;
569
570 return invalid<ReportNonAffBranch>(Context, /*Assert=*/true, &BB,
571 ConditionSCEV, ConditionSCEV, SI);
572}
573
574bool ScopDetection::isValidBranch(BasicBlock &BB, CondBrInst *BI,
575 Value *Condition, bool IsLoopBranch,
576 DetectionContext &Context) {
577 // Constant integer conditions are always affine.
578 if (isa<ConstantInt>(Condition))
579 return true;
580
581 if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Condition)) {
582 auto Opcode = BinOp->getOpcode();
583 if (Opcode == Instruction::And || Opcode == Instruction::Or) {
584 Value *Op0 = BinOp->getOperand(0);
585 Value *Op1 = BinOp->getOperand(1);
586 return isValidBranch(BB, BI, Op0, IsLoopBranch, Context) &&
587 isValidBranch(BB, BI, Op1, IsLoopBranch, Context);
588 }
589 }
590
591 if (auto PHI = dyn_cast<PHINode>(Condition)) {
592 auto *Unique = dyn_cast_or_null<ConstantInt>(
593 getUniqueNonErrorValue(PHI, &Context.CurRegion, this));
594 if (Unique && (Unique->isZero() || Unique->isOne()))
595 return true;
596 }
597
598 if (auto Load = dyn_cast<LoadInst>(Condition))
599 if (!IsLoopBranch && Context.CurRegion.contains(Load)) {
600 Context.RequiredILS.insert(Load);
601 return true;
602 }
603
604 // Non constant conditions of branches need to be ICmpInst.
605 if (!isa<ICmpInst>(Condition)) {
606 if (!IsLoopBranch && AllowNonAffineSubRegions &&
607 addOverApproximatedRegion(RI.getRegionFor(&BB), Context))
608 return true;
609 return invalid<ReportInvalidCond>(Context, /*Assert=*/true, BI, &BB);
610 }
611
612 ICmpInst *ICmp = cast<ICmpInst>(Condition);
613
614 // Are both operands of the ICmp affine?
615 if (isa<UndefValue>(ICmp->getOperand(0)) ||
616 isa<UndefValue>(ICmp->getOperand(1)))
617 return invalid<ReportUndefOperand>(Context, /*Assert=*/true, &BB, ICmp);
618
619 Loop *L = LI.getLoopFor(&BB);
620 const SCEV *LHS = SE.getSCEVAtScope(ICmp->getOperand(0), L);
621 const SCEV *RHS = SE.getSCEVAtScope(ICmp->getOperand(1), L);
622
623 LHS = tryForwardThroughPHI(LHS, Context.CurRegion, SE, this);
624 RHS = tryForwardThroughPHI(RHS, Context.CurRegion, SE, this);
625
626 // If unsigned operations are not allowed try to approximate the region.
627 if (ICmp->isUnsigned() && !PollyAllowUnsignedOperations)
628 return !IsLoopBranch && AllowNonAffineSubRegions &&
629 addOverApproximatedRegion(RI.getRegionFor(&BB), Context);
630
631 // Check for invalid usage of different pointers in one expression.
632 if (ICmp->isEquality() && involvesMultiplePtrs(LHS, nullptr, L) &&
633 involvesMultiplePtrs(RHS, nullptr, L))
634 return false;
635
636 // Check for invalid usage of different pointers in a relational comparison.
637 if (ICmp->isRelational() && involvesMultiplePtrs(LHS, RHS, L))
638 return false;
639
640 if (isAffine(LHS, L, Context) && isAffine(RHS, L, Context))
641 return true;
642
643 if (!IsLoopBranch && AllowNonAffineSubRegions &&
644 addOverApproximatedRegion(RI.getRegionFor(&BB), Context))
645 return true;
646
647 if (IsLoopBranch)
648 return false;
649
650 return invalid<ReportNonAffBranch>(Context, /*Assert=*/true, &BB, LHS, RHS,
651 ICmp);
652}
653
654bool ScopDetection::isValidCFG(BasicBlock &BB, bool IsLoopBranch,
655 bool AllowUnreachable,
656 DetectionContext &Context) {
657 Region &CurRegion = Context.CurRegion;
658
659 Instruction *TI = BB.getTerminator();
660
661 if (AllowUnreachable && isa<UnreachableInst>(TI))
662 return true;
663
664 // Return instructions are only valid if the region is the top level region.
665 if (isa<ReturnInst>(TI) && CurRegion.isTopLevelRegion())
666 return true;
667
668 if (isa<UncondBrInst>(TI))
669 return true;
670
671 if (auto *BI = dyn_cast<CondBrInst>(TI)) {
672 Value *Condition = BI->getCondition();
673 if (isa<UndefValue>(Condition))
674 return invalid<ReportUndefCond>(Context, /*Assert=*/true, TI, &BB);
675 return isValidBranch(BB, BI, Condition, IsLoopBranch, Context);
676 }
677
678 if (auto *SI = dyn_cast<SwitchInst>(TI)) {
679 Value *Condition = SI->getCondition();
680 if (isa<UndefValue>(Condition))
681 return invalid<ReportUndefCond>(Context, /*Assert=*/true, TI, &BB);
682 return isValidSwitch(BB, SI, Condition, IsLoopBranch, Context);
683 }
684
685 return invalid<ReportInvalidTerminator>(Context, /*Assert=*/true, &BB);
686}
687
689 DetectionContext &Context) const {
690 if (CI.doesNotReturn())
691 return false;
692
693 if (CI.doesNotAccessMemory())
694 return true;
695
696 if (auto *II = dyn_cast<IntrinsicInst>(&CI))
697 if (isValidIntrinsicInst(*II, Context))
698 return true;
699
700 Function *CalledFunction = CI.getCalledFunction();
701
702 // Indirect calls are not supported.
703 if (CalledFunction == nullptr)
704 return false;
705
706 if (isDebugCall(&CI)) {
707 POLLY_DEBUG(dbgs() << "Allow call to debug function: "
708 << CalledFunction->getName() << '\n');
709 return true;
710 }
711
712 if (AllowModrefCall) {
713 MemoryEffects ME = AA.getMemoryEffects(CalledFunction);
714 if (ME.onlyAccessesArgPointees()) {
715 for (const auto &Arg : CI.args()) {
716 if (!Arg->getType()->isPointerTy())
717 continue;
718
719 // Bail if a pointer argument has a base address not known to
720 // ScalarEvolution. Note that a zero pointer is acceptable.
721 const SCEV *ArgSCEV =
722 SE.getSCEVAtScope(Arg, LI.getLoopFor(CI.getParent()));
723 if (ArgSCEV->isZero())
724 continue;
725
726 auto *BP = dyn_cast<SCEVUnknown>(SE.getPointerBase(ArgSCEV));
727 if (!BP)
728 return false;
729
730 // Implicitly disable delinearization since we have an unknown
731 // accesses with an unknown access function.
732 Context.HasUnknownAccess = true;
733 }
734
735 // Explicitly use addUnknown so we don't put a loop-variant
736 // pointer into the alias set.
737 Context.AST.addUnknown(&CI);
738 return true;
739 }
740
741 if (ME.onlyReadsMemory()) {
742 // Implicitly disable delinearization since we have an unknown
743 // accesses with an unknown access function.
744 Context.HasUnknownAccess = true;
745 // Explicitly use addUnknown so we don't put a loop-variant
746 // pointer into the alias set.
747 Context.AST.addUnknown(&CI);
748 return true;
749 }
750 return false;
751 }
752
753 return false;
754}
755
757 DetectionContext &Context) const {
758 if (isIgnoredIntrinsic(&II))
759 return true;
760
761 // The closest loop surrounding the call instruction.
762 Loop *L = LI.getLoopFor(II.getParent());
763
764 // The access function and base pointer for memory intrinsics.
765 const SCEV *AF;
766 const SCEVUnknown *BP;
767
768 switch (II.getIntrinsicID()) {
769 // Memory intrinsics that can be represented are supported.
770 case Intrinsic::memmove:
771 case Intrinsic::memcpy:
772 AF = SE.getSCEVAtScope(cast<MemTransferInst>(II).getSource(), L);
773 if (!AF->isZero()) {
774 BP = dyn_cast<SCEVUnknown>(SE.getPointerBase(AF));
775 // Bail if the source pointer is not valid.
776 if (!isValidAccess(&II, AF, BP, Context))
777 return false;
778 }
779 [[fallthrough]];
780 case Intrinsic::memset:
781 AF = SE.getSCEVAtScope(cast<MemIntrinsic>(II).getDest(), L);
782 if (!AF->isZero()) {
783 BP = dyn_cast<SCEVUnknown>(SE.getPointerBase(AF));
784 // Bail if the destination pointer is not valid.
785 if (!isValidAccess(&II, AF, BP, Context))
786 return false;
787 }
788
789 // Bail if the length is not affine.
790 if (!isAffine(SE.getSCEVAtScope(cast<MemIntrinsic>(II).getLength(), L), L,
791 Context))
792 return false;
793
794 return true;
795 default:
796 break;
797 }
798
799 return false;
800}
801
802bool ScopDetection::isInvariant(Value &Val, const Region &Reg,
803 DetectionContext &Ctx) const {
804 // A reference to function argument or constant value is invariant.
805 if (isa<Argument>(Val) || isa<Constant>(Val))
806 return true;
807
808 Instruction *I = dyn_cast<Instruction>(&Val);
809 if (!I)
810 return false;
811
812 if (!Reg.contains(I))
813 return true;
814
815 // Loads within the SCoP may read arbitrary values, need to hoist them. If it
816 // is not hoistable, it will be rejected later, but here we assume it is and
817 // that makes the value invariant.
818 if (auto LI = dyn_cast<LoadInst>(I)) {
819 Ctx.RequiredILS.insert(LI);
820 return true;
821 }
822
823 return false;
824}
825
826namespace {
827
828/// Remove smax of smax(0, size) expressions from a SCEV expression and
829/// register the '...' components.
830///
831/// Array access expressions as they are generated by GFortran contain smax(0,
832/// size) expressions that confuse the 'normal' delinearization algorithm.
833/// However, if we extract such expressions before the normal delinearization
834/// takes place they can actually help to identify array size expressions in
835/// Fortran accesses. For the subsequently following delinearization the smax(0,
836/// size) component can be replaced by just 'size'. This is correct as we will
837/// always add and verify the assumption that for all subscript expressions
838/// 'exp' the inequality 0 <= exp < size holds. Hence, we will also verify
839/// that 0 <= size, which means smax(0, size) == size.
840class SCEVRemoveMax final : public SCEVRewriteVisitor<SCEVRemoveMax> {
841public:
842 SCEVRemoveMax(ScalarEvolution &SE, std::vector<const SCEV *> *Terms)
843 : SCEVRewriteVisitor(SE), Terms(Terms) {}
844
845 static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
846 std::vector<const SCEV *> *Terms = nullptr) {
847 SCEVRemoveMax Rewriter(SE, Terms);
848 return Rewriter.visit(Scev);
849 }
850
851 const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
852 if ((Expr->getNumOperands() == 2) && Expr->getOperand(0)->isZero()) {
853 auto Res = visit(Expr->getOperand(1));
854 if (Terms)
855 (*Terms).push_back(Res);
856 return Res;
857 }
858
859 return Expr;
860 }
861
862private:
863 std::vector<const SCEV *> *Terms;
864};
865} // namespace
866
867SmallVector<const SCEV *, 4>
869 const SCEVUnknown *BasePointer) const {
870 SmallVector<const SCEV *, 4> Terms;
871 for (const auto &Pair : Context.Accesses[BasePointer]) {
872 std::vector<const SCEV *> MaxTerms;
873 SCEVRemoveMax::rewrite(Pair.second, SE, &MaxTerms);
874 if (!MaxTerms.empty()) {
875 for (const SCEV *Max : MaxTerms)
876 Terms.push_back(
877 SE.getTruncateOrSignExtend(Max, Pair.second->getType()));
878 continue;
879 }
880 // In case the outermost expression is a plain add, we check if any of its
881 // terms has the form 4 * %inst * %param * %param ..., aka a term that
882 // contains a product between a parameter and an instruction that is
883 // inside the scop. Such instructions, if allowed at all, are instructions
884 // SCEV can not represent, but Polly is still looking through. As a
885 // result, these instructions can depend on induction variables and are
886 // most likely no array sizes. However, terms that are multiplied with
887 // them are likely candidates for array sizes.
888 if (auto *AF = dyn_cast<SCEVAddExpr>(Pair.second)) {
889 for (auto Op : AF->operands()) {
890 if (auto *AF2 = dyn_cast<SCEVAddRecExpr>(Op))
891 collectParametricTerms(SE, AF2, Terms);
892 if (auto *AF2 = dyn_cast<SCEVMulExpr>(Op)) {
893 SmallVector<SCEVUse, 0> Operands;
894
895 for (const SCEV *MulOp : AF2->operands()) {
896 if (auto *Const = dyn_cast<SCEVConstant>(MulOp))
897 Operands.push_back(Const);
898 if (auto *Unknown = dyn_cast<SCEVUnknown>(MulOp)) {
899 if (auto *Inst = dyn_cast<Instruction>(Unknown->getValue())) {
900 if (!Context.CurRegion.contains(Inst))
901 Operands.push_back(MulOp);
902
903 } else {
904 Operands.push_back(MulOp);
905 }
906 }
907 }
908 if (Operands.size())
909 Terms.push_back(SE.getMulExpr(Operands));
910 }
911 }
912 }
913 if (Terms.empty())
914 collectParametricTerms(SE, Pair.second, Terms);
915 }
916 return Terms;
917}
918
920 SmallVectorImpl<const SCEV *> &Sizes,
921 const SCEVUnknown *BasePointer,
922 Loop *Scope) const {
923 // If no sizes were found, all sizes are trivially valid. We allow this case
924 // to make it possible to pass known-affine accesses to the delinearization to
925 // try to recover some interesting multi-dimensional accesses, but to still
926 // allow the already known to be affine access in case the delinearization
927 // fails. In such situations, the delinearization will just return a Sizes
928 // array of size zero.
929 if (Sizes.size() == 0)
930 return true;
931
932 Value *BaseValue = BasePointer->getValue();
933 Region &CurRegion = Context.CurRegion;
934 for (const SCEV *DelinearizedSize : Sizes) {
935 // Don't pass down the scope to isAfffine; array dimensions must be
936 // invariant across the entire scop.
937 if (!isAffine(DelinearizedSize, nullptr, Context)) {
938 Sizes.clear();
939 break;
940 }
941 if (auto *Unknown = dyn_cast<SCEVUnknown>(DelinearizedSize)) {
942 auto *V = dyn_cast<Value>(Unknown->getValue());
943 if (auto *Load = dyn_cast<LoadInst>(V)) {
944 if (Context.CurRegion.contains(Load) &&
945 isHoistableLoad(Load, CurRegion, LI, SE, DT, Context.RequiredILS))
946 Context.RequiredILS.insert(Load);
947 continue;
948 }
949 }
950 if (hasScalarDepsInsideRegion(DelinearizedSize, &CurRegion, Scope, false,
951 Context.RequiredILS))
953 Context, /*Assert=*/true, DelinearizedSize,
954 Context.Accesses[BasePointer].front().first, BaseValue);
955 }
956
957 // No array shape derived.
958 if (Sizes.empty()) {
959 if (AllowNonAffine)
960 return true;
961
962 for (const auto &Pair : Context.Accesses[BasePointer]) {
963 const Instruction *Insn = Pair.first;
964 const SCEV *AF = Pair.second;
965
966 if (!isAffine(AF, Scope, Context)) {
967 invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF, Insn,
968 BaseValue);
969 if (!KeepGoing)
970 return false;
971 }
972 }
973 return false;
974 }
975 return true;
976}
977
978// We first store the resulting memory accesses in TempMemoryAccesses. Only
979// if the access functions for all memory accesses have been successfully
980// delinearized we continue. Otherwise, we either report a failure or, if
981// non-affine accesses are allowed, we drop the information. In case the
982// information is dropped the memory accesses need to be overapproximated
983// when translated to a polyhedral representation.
985 DetectionContext &Context, const SCEVUnknown *BasePointer,
986 std::shared_ptr<ArrayShape> Shape) const {
987 Value *BaseValue = BasePointer->getValue();
988 bool BasePtrHasNonAffine = false;
989 MapInsnToMemAcc TempMemoryAccesses;
990 for (const auto &Pair : Context.Accesses[BasePointer]) {
991 const Instruction *Insn = Pair.first;
992 auto *AF = Pair.second;
993 AF = SCEVRemoveMax::rewrite(AF, SE);
994 bool IsNonAffine = false;
995 TempMemoryAccesses.insert(std::make_pair(Insn, MemAcc(Insn, Shape)));
996 MemAcc *Acc = &TempMemoryAccesses.find(Insn)->second;
997 auto *Scope = LI.getLoopFor(Insn->getParent());
998
999 if (!AF) {
1000 if (isAffine(Pair.second, Scope, Context))
1001 Acc->DelinearizedSubscripts.push_back(Pair.second);
1002 else
1003 IsNonAffine = true;
1004 } else {
1005 if (Shape->DelinearizedSizes.size() == 0) {
1006 Acc->DelinearizedSubscripts.push_back(AF);
1007 } else {
1008 llvm::computeAccessFunctions(SE, AF, Acc->DelinearizedSubscripts,
1009 Shape->DelinearizedSizes);
1010 if (Acc->DelinearizedSubscripts.size() == 0)
1011 IsNonAffine = true;
1012 }
1013 for (const SCEV *S : Acc->DelinearizedSubscripts)
1014 if (!isAffine(S, Scope, Context))
1015 IsNonAffine = true;
1016 }
1017
1018 // (Possibly) report non affine access
1019 if (IsNonAffine) {
1020 BasePtrHasNonAffine = true;
1021 if (!AllowNonAffine) {
1022 invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, Pair.second,
1023 Insn, BaseValue);
1024 if (!KeepGoing)
1025 return false;
1026 }
1027 }
1028 }
1029
1030 if (!BasePtrHasNonAffine)
1031 Context.InsnToMemAcc.insert(TempMemoryAccesses.begin(),
1032 TempMemoryAccesses.end());
1033
1034 return true;
1035}
1036
1038 const SCEVUnknown *BasePointer,
1039 Loop *Scope) const {
1040 auto Shape = std::shared_ptr<ArrayShape>(new ArrayShape(BasePointer));
1041
1042 auto Terms = getDelinearizationTerms(Context, BasePointer);
1043
1044 findArrayDimensions(SE, Terms, Shape->DelinearizedSizes,
1045 Context.ElementSize[BasePointer]);
1046
1047 if (!hasValidArraySizes(Context, Shape->DelinearizedSizes, BasePointer,
1048 Scope))
1049 return false;
1050
1051 return computeAccessFunctions(Context, BasePointer, Shape);
1052}
1053
1055 // TODO: If we have an unknown access and other non-affine accesses we do
1056 // not try to delinearize them for now.
1057 if (Context.HasUnknownAccess && !Context.NonAffineAccesses.empty())
1058 return AllowNonAffine;
1059
1060 for (auto &Pair : Context.NonAffineAccesses) {
1061 auto *BasePointer = Pair.first;
1062 auto *Scope = Pair.second;
1063 if (!hasBaseAffineAccesses(Context, BasePointer, Scope)) {
1064 Context.IsInvalid = true;
1065 if (!KeepGoing)
1066 return false;
1067 }
1068 }
1069 return true;
1070}
1071
1072bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
1073 const SCEVUnknown *BP,
1074 DetectionContext &Context) const {
1075
1076 if (!BP)
1077 return invalid<ReportNoBasePtr>(Context, /*Assert=*/true, Inst);
1078
1079 auto *BV = BP->getValue();
1080 if (isa<UndefValue>(BV))
1081 return invalid<ReportUndefBasePtr>(Context, /*Assert=*/true, Inst);
1082
1083 // FIXME: Think about allowing IntToPtrInst
1084 if (IntToPtrInst *Inst = dyn_cast<IntToPtrInst>(BV))
1085 return invalid<ReportIntToPtr>(Context, /*Assert=*/true, Inst);
1086
1087 // Check that the base address of the access is invariant in the current
1088 // region.
1089 if (!isInvariant(*BV, Context.CurRegion, Context))
1090 return invalid<ReportVariantBasePtr>(Context, /*Assert=*/true, BV, Inst);
1091
1092 AF = SE.getMinusSCEV(AF, BP);
1093
1094 const SCEV *Size;
1095 if (!isa<MemIntrinsic>(Inst)) {
1096 Size = SE.getElementSize(Inst);
1097 } else {
1098 auto *SizeTy =
1099 SE.getEffectiveSCEVType(PointerType::getUnqual(SE.getContext()));
1100 Size = SE.getConstant(SizeTy, 8);
1101 }
1102
1103 if (Context.ElementSize[BP]) {
1104 if (!AllowDifferentTypes && Context.ElementSize[BP] != Size)
1105 return invalid<ReportDifferentArrayElementSize>(Context, /*Assert=*/true,
1106 Inst, BV);
1107
1108 Context.ElementSize[BP] = SE.getSMinExpr(Size, Context.ElementSize[BP]);
1109 } else {
1110 Context.ElementSize[BP] = Size;
1111 }
1112
1113 bool IsVariantInNonAffineLoop = false;
1114 SetVector<const Loop *> Loops;
1115 findLoops(AF, Loops);
1116 for (const Loop *L : Loops)
1117 if (Context.BoxedLoopsSet.count(L))
1118 IsVariantInNonAffineLoop = true;
1119
1120 auto *Scope = LI.getLoopFor(Inst->getParent());
1121 bool IsAffine = !IsVariantInNonAffineLoop && isAffine(AF, Scope, Context);
1122 // Do not try to delinearize memory intrinsics and force them to be affine.
1123 if (isa<MemIntrinsic>(Inst) && !IsAffine) {
1124 return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF, Inst,
1125 BV);
1126 } else if (PollyDelinearize && !IsVariantInNonAffineLoop) {
1127 Context.Accesses[BP].push_back({Inst, AF});
1128
1129 if (!IsAffine)
1130 Context.NonAffineAccesses.insert(
1131 std::make_pair(BP, LI.getLoopFor(Inst->getParent())));
1132 } else if (!AllowNonAffine && !IsAffine) {
1133 return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF, Inst,
1134 BV);
1135 }
1136
1137 if (IgnoreAliasing)
1138 return true;
1139
1140 // Check if the base pointer of the memory access does alias with
1141 // any other pointer. This cannot be handled at the moment.
1142 AAMDNodes AATags = Inst->getAAMetadata();
1143 AliasSet &AS = Context.AST.getAliasSetFor(
1144 MemoryLocation::getBeforeOrAfter(BP->getValue(), AATags));
1145
1146 if (!AS.isMustAlias()) {
1148 bool CanBuildRunTimeCheck = true;
1149 // The run-time alias check places code that involves the base pointer at
1150 // the beginning of the SCoP. This breaks if the base pointer is defined
1151 // inside the scop. Hence, we can only create a run-time check if we are
1152 // sure the base pointer is not an instruction defined inside the scop.
1153 // However, we can ignore loads that will be hoisted.
1154
1155 auto ASPointers = AS.getPointers();
1156
1157 InvariantLoadsSetTy VariantLS, InvariantLS;
1158 // In order to detect loads which are dependent on other invariant loads
1159 // as invariant, we use fixed-point iteration method here i.e we iterate
1160 // over the alias set for arbitrary number of times until it is safe to
1161 // assume that all the invariant loads have been detected
1162 while (true) {
1163 const unsigned int VariantSize = VariantLS.size(),
1164 InvariantSize = InvariantLS.size();
1165
1166 for (const Value *Ptr : ASPointers) {
1167 Instruction *Inst = dyn_cast<Instruction>(const_cast<Value *>(Ptr));
1168 if (Inst && Context.CurRegion.contains(Inst)) {
1169 auto *Load = dyn_cast<LoadInst>(Inst);
1170 if (Load && InvariantLS.count(Load))
1171 continue;
1172 if (Load && isHoistableLoad(Load, Context.CurRegion, LI, SE, DT,
1173 InvariantLS)) {
1174 if (VariantLS.count(Load))
1175 VariantLS.remove(Load);
1176 Context.RequiredILS.insert(Load);
1177 InvariantLS.insert(Load);
1178 } else {
1179 CanBuildRunTimeCheck = false;
1180 VariantLS.insert(Load);
1181 }
1182 }
1183 }
1184
1185 if (InvariantSize == InvariantLS.size() &&
1186 VariantSize == VariantLS.size())
1187 break;
1188 }
1189
1190 if (CanBuildRunTimeCheck)
1191 return true;
1192 }
1193 return invalid<ReportAlias>(Context, /*Assert=*/true, Inst, AS);
1194 }
1195
1196 return true;
1197}
1198
1200 DetectionContext &Context) const {
1201 Value *Ptr = Inst.getPointerOperand();
1202 Loop *L = LI.getLoopFor(Inst->getParent());
1203 const SCEV *AccessFunction = SE.getSCEVAtScope(Ptr, L);
1204 const SCEVUnknown *BasePointer;
1205
1206 BasePointer = dyn_cast<SCEVUnknown>(SE.getPointerBase(AccessFunction));
1207
1208 return isValidAccess(Inst, AccessFunction, BasePointer, Context);
1209}
1210
1211bool ScopDetection::isCompatibleType(Instruction *Inst, Type *Ty,
1212 DetectionContext &Context) {
1213 if (!Ty)
1214 return false;
1215
1216 if (isa<ScalableVectorType>(Ty))
1217 return invalid<ReportIncompatibleType>(Context, /*Assert=*/true, Inst, Ty);
1218
1219 return true;
1220}
1221
1223 DetectionContext &Context) {
1224 for (auto &Op : Inst.operands()) {
1225 auto *OpInst = dyn_cast<Instruction>(&Op);
1226
1227 if (!OpInst)
1228 continue;
1229
1230 if (!isCompatibleType(&Inst, Op->getType(), Context))
1231 return false;
1232
1233 if (isErrorBlock(*OpInst->getParent(), Context.CurRegion)) {
1234 auto *PHI = dyn_cast<PHINode>(OpInst);
1235 if (PHI) {
1236 for (User *U : PHI->users()) {
1237 auto *UI = dyn_cast<Instruction>(U);
1238 if (!UI || !UI->isTerminator())
1239 return false;
1240 }
1241 } else {
1242 return false;
1243 }
1244 }
1245 }
1246
1247 if (isa<LandingPadInst>(&Inst) || isa<ResumeInst>(&Inst))
1248 return false;
1249
1250 if (!isCompatibleType(&Inst, Inst.getType(), Context))
1251 return false;
1252
1253 // We only check the call instruction but not invoke instruction.
1254 if (CallInst *CI = dyn_cast<CallInst>(&Inst)) {
1255 if (isValidCallInst(*CI, Context))
1256 return true;
1257
1258 return invalid<ReportFuncCall>(Context, /*Assert=*/true, &Inst);
1259 }
1260
1261 if (!Inst.mayReadOrWriteMemory()) {
1262 if (!isa<AllocaInst>(Inst))
1263 return true;
1264
1265 return invalid<ReportAlloca>(Context, /*Assert=*/true, &Inst);
1266 }
1267
1268 // Check the access function.
1269 if (auto MemInst = MemAccInst::dyn_cast(Inst)) {
1270 Context.hasStores |= isa<StoreInst>(MemInst);
1271 Context.hasLoads |= isa<LoadInst>(MemInst);
1272 if (!MemInst.isSimple())
1273 return invalid<ReportNonSimpleMemoryAccess>(Context, /*Assert=*/true,
1274 &Inst);
1275
1276 return isValidMemoryAccess(MemInst, Context);
1277 }
1278
1279 // We do not know this instruction, therefore we assume it is invalid.
1280 return invalid<ReportUnknownInst>(Context, /*Assert=*/true, &Inst);
1281}
1282
1283/// Check whether @p L has exiting blocks.
1284///
1285/// @param L The loop of interest
1286///
1287/// @return True if the loop has exiting blocks, false otherwise.
1288static bool hasExitingBlocks(Loop *L) {
1289 SmallVector<BasicBlock *, 4> ExitingBlocks;
1290 L->getExitingBlocks(ExitingBlocks);
1291 return !ExitingBlocks.empty();
1292}
1293
1295 // FIXME: Yes, this is bad. isValidCFG() may call invalid<Reason>() which
1296 // causes the SCoP to be rejected regardless on whether non-ISL trip counts
1297 // could be used. We currently preserve the legacy behaviour of rejecting
1298 // based on Context.Log.size() added by isValidCFG() or before, regardless on
1299 // whether the ISL trip count can be used or can be used as a non-affine
1300 // region. However, we allow rejections by isValidCFG() that do not result in
1301 // an error log entry.
1302 bool OldIsInvalid = Context.IsInvalid;
1303
1304 // Ensure the loop has valid exiting blocks as well as latches, otherwise we
1305 // need to overapproximate it as a boxed loop.
1306 SmallVector<BasicBlock *, 4> LoopControlBlocks;
1307 L->getExitingBlocks(LoopControlBlocks);
1308 L->getLoopLatches(LoopControlBlocks);
1309 for (BasicBlock *ControlBB : LoopControlBlocks) {
1310 if (!isValidCFG(*ControlBB, true, false, Context)) {
1311 Context.IsInvalid = OldIsInvalid || Context.Log.size();
1312 return false;
1313 }
1314 }
1315
1316 // We can use ISL to compute the trip count of L.
1317 Context.IsInvalid = OldIsInvalid || Context.Log.size();
1318 return true;
1319}
1320
1322 // Loops that contain part but not all of the blocks of a region cannot be
1323 // handled by the schedule generation. Such loop constructs can happen
1324 // because a region can contain BBs that have no path to the exit block
1325 // (Infinite loops, UnreachableInst), but such blocks are never part of a
1326 // loop.
1327 //
1328 // _______________
1329 // | Loop Header | <-----------.
1330 // --------------- |
1331 // | |
1332 // _______________ ______________
1333 // | RegionEntry |-----> | RegionExit |----->
1334 // --------------- --------------
1335 // |
1336 // _______________
1337 // | EndlessLoop | <--.
1338 // --------------- |
1339 // | |
1340 // \------------/
1341 //
1342 // In the example above, the loop (LoopHeader,RegionEntry,RegionExit) is
1343 // neither entirely contained in the region RegionEntry->RegionExit
1344 // (containing RegionEntry,EndlessLoop) nor is the region entirely contained
1345 // in the loop.
1346 // The block EndlessLoop is contained in the region because Region::contains
1347 // tests whether it is not dominated by RegionExit. This is probably to not
1348 // having to query the PostdominatorTree. Instead of an endless loop, a dead
1349 // end can also be formed by an UnreachableInst. This case is already caught
1350 // by isErrorBlock(). We hence only have to reject endless loops here.
1351 if (!hasExitingBlocks(L))
1352 return invalid<ReportLoopHasNoExit>(Context, /*Assert=*/true, L);
1353
1354 // The algorithm for domain construction assumes that loops has only a single
1355 // exit block (and hence corresponds to a subregion). Note that we cannot use
1356 // L->getExitBlock() because it does not check whether all exiting edges point
1357 // to the same BB.
1358 SmallVector<BasicBlock *, 4> ExitBlocks;
1359 L->getExitBlocks(ExitBlocks);
1360 BasicBlock *TheExitBlock = ExitBlocks[0];
1361 for (BasicBlock *ExitBB : ExitBlocks) {
1362 if (TheExitBlock != ExitBB)
1363 return invalid<ReportLoopHasMultipleExits>(Context, /*Assert=*/true, L);
1364 }
1365
1366 if (canUseISLTripCount(L, Context))
1367 return true;
1368
1370 Region *R = RI.getRegionFor(L->getHeader());
1371 while (R != &Context.CurRegion && !R->contains(L))
1372 R = R->getParent();
1373
1374 if (addOverApproximatedRegion(R, Context))
1375 return true;
1376 }
1377
1378 const SCEV *LoopCount = SE.getBackedgeTakenCount(L);
1379 return invalid<ReportLoopBound>(Context, /*Assert=*/true, L, LoopCount);
1380}
1381
1382/// Return the number of loops in @p L (incl. @p L) that have a trip
1383/// count that is not known to be less than @MinProfitableTrips.
1386 unsigned MinProfitableTrips) {
1387 const SCEV *TripCount = SE.getBackedgeTakenCount(L);
1388
1389 int NumLoops = 1;
1390 int MaxLoopDepth = 1;
1391 if (MinProfitableTrips > 0)
1392 if (auto *TripCountC = dyn_cast<SCEVConstant>(TripCount))
1393 if (TripCountC->getType()->getScalarSizeInBits() <= 64)
1394 if (TripCountC->getValue()->getZExtValue() <= MinProfitableTrips)
1395 NumLoops -= 1;
1396
1397 for (auto &SubLoop : *L) {
1398 LoopStats Stats = countBeneficialSubLoops(SubLoop, SE, MinProfitableTrips);
1399 NumLoops += Stats.NumLoops;
1400 MaxLoopDepth = std::max(MaxLoopDepth, Stats.MaxDepth + 1);
1401 }
1402
1403 return {NumLoops, MaxLoopDepth};
1404}
1405
1407ScopDetection::countBeneficialLoops(Region *R, ScalarEvolution &SE,
1408 LoopInfo &LI, unsigned MinProfitableTrips) {
1409 int LoopNum = 0;
1410 int MaxLoopDepth = 0;
1411
1412 auto L = LI.getLoopFor(R->getEntry());
1413
1414 // If L is fully contained in R, move to first loop surrounding R. Otherwise,
1415 // L is either nullptr or already surrounding R.
1416 if (L && R->contains(L)) {
1417 L = R->outermostLoopInRegion(L);
1418 L = L->getParentLoop();
1419 }
1420
1421 auto SubLoops =
1422 L ? L->getSubLoops() : std::vector<Loop *>(LI.begin(), LI.end());
1423
1424 for (auto &SubLoop : SubLoops)
1425 if (R->contains(SubLoop)) {
1426 LoopStats Stats =
1427 countBeneficialSubLoops(SubLoop, SE, MinProfitableTrips);
1428 LoopNum += Stats.NumLoops;
1429 MaxLoopDepth = std::max(MaxLoopDepth, Stats.MaxDepth);
1430 }
1431
1432 return {LoopNum, MaxLoopDepth};
1433}
1434
1435static bool isErrorBlockImpl(BasicBlock &BB, const Region &R, LoopInfo &LI,
1436 const DominatorTree &DT) {
1437 if (isa<UnreachableInst>(BB.getTerminator()))
1438 return true;
1439
1440 if (LI.isLoopHeader(&BB))
1441 return false;
1442
1443 // Don't consider something outside the SCoP as error block. It will precede
1444 // the code versioning runtime check.
1445 if (!R.contains(&BB))
1446 return false;
1447
1448 // Basic blocks that are always executed are not considered error blocks,
1449 // as their execution can not be a rare event.
1450 bool DominatesAllPredecessors = true;
1451 if (R.isTopLevelRegion()) {
1452 for (BasicBlock &I : *R.getEntry()->getParent()) {
1453 if (isa<ReturnInst>(I.getTerminator()) && !DT.dominates(&BB, &I)) {
1454 DominatesAllPredecessors = false;
1455 break;
1456 }
1457 }
1458 } else {
1459 for (auto Pred : predecessors(R.getExit())) {
1460 if (R.contains(Pred) && !DT.dominates(&BB, Pred)) {
1461 DominatesAllPredecessors = false;
1462 break;
1463 }
1464 }
1465 }
1466
1467 if (DominatesAllPredecessors)
1468 return false;
1469
1470 for (Instruction &Inst : BB)
1471 if (CallInst *CI = dyn_cast<CallInst>(&Inst)) {
1472 if (isDebugCall(CI))
1473 continue;
1474
1475 if (isIgnoredIntrinsic(CI))
1476 continue;
1477
1478 // memset, memcpy and memmove are modeled intrinsics.
1479 if (isa<MemSetInst>(CI) || isa<MemTransferInst>(CI))
1480 continue;
1481
1482 if (!CI->doesNotAccessMemory())
1483 return true;
1484 if (CI->doesNotReturn())
1485 return true;
1486 }
1487
1488 return false;
1489}
1490
1491bool ScopDetection::isErrorBlock(llvm::BasicBlock &BB, const llvm::Region &R) {
1493 return false;
1494
1495 auto It = ErrorBlockCache.insert({std::make_pair(&BB, &R), false});
1496 if (!It.second)
1497 return It.first->getSecond();
1498
1499 bool Result = isErrorBlockImpl(BB, R, LI, DT);
1500 It.first->second = Result;
1501 return Result;
1502}
1503
1505 // Initial no valid region was found (greater than R)
1506 std::unique_ptr<Region> LastValidRegion;
1507 auto ExpandedRegion = std::unique_ptr<Region>(R.getExpandedRegion());
1508
1509 POLLY_DEBUG(dbgs() << "\tExpanding " << R.getNameStr() << "\n");
1510
1511 while (ExpandedRegion) {
1512 BBPair P = getBBPairForRegion(ExpandedRegion.get());
1513 std::unique_ptr<DetectionContext> &Entry = DetectionContextMap[P];
1514 Entry = std::make_unique<DetectionContext>(*ExpandedRegion, AA,
1515 /*Verifying=*/false);
1516 DetectionContext &Context = *Entry;
1517
1518 POLLY_DEBUG(dbgs() << "\t\tTrying " << ExpandedRegion->getNameStr()
1519 << "\n");
1520 // Only expand when we did not collect errors.
1521
1522 if (!Context.Log.hasErrors()) {
1523 // If the exit is valid check all blocks
1524 // - if true, a valid region was found => store it + keep expanding
1525 // - if false, .tbd. => stop (should this really end the loop?)
1526 if (!allBlocksValid(Context) || Context.Log.hasErrors()) {
1527 removeCachedResults(*ExpandedRegion);
1528 DetectionContextMap.erase(P);
1529 break;
1530 }
1531
1532 // Store this region, because it is the greatest valid (encountered so
1533 // far).
1534 if (LastValidRegion) {
1535 removeCachedResults(*LastValidRegion);
1536 DetectionContextMap.erase(P);
1537 }
1538 LastValidRegion = std::move(ExpandedRegion);
1539
1540 // Create and test the next greater region (if any)
1541 ExpandedRegion =
1542 std::unique_ptr<Region>(LastValidRegion->getExpandedRegion());
1543
1544 } else {
1545 // Create and test the next greater region (if any)
1546 removeCachedResults(*ExpandedRegion);
1547 DetectionContextMap.erase(P);
1548 ExpandedRegion =
1549 std::unique_ptr<Region>(ExpandedRegion->getExpandedRegion());
1550 }
1551 }
1552
1553 POLLY_DEBUG({
1554 if (LastValidRegion)
1555 dbgs() << "\tto " << LastValidRegion->getNameStr() << "\n";
1556 else
1557 dbgs() << "\tExpanding " << R.getNameStr() << " failed\n";
1558 });
1559
1560 return LastValidRegion.release();
1561}
1562
1563static bool regionWithoutLoops(Region &R, LoopInfo &LI) {
1564 for (const BasicBlock *BB : R.blocks())
1565 if (R.contains(LI.getLoopFor(BB)))
1566 return false;
1567
1568 return true;
1569}
1570
1572 for (auto &SubRegion : R) {
1573 if (ValidRegions.count(SubRegion.get())) {
1574 removeCachedResults(*SubRegion);
1575 } else
1577 }
1578}
1579
1581 ValidRegions.remove(&R);
1582}
1583
1585 std::unique_ptr<DetectionContext> &Entry =
1587 Entry = std::make_unique<DetectionContext>(R, AA, /*Verifying=*/false);
1588 DetectionContext &Context = *Entry;
1589
1590 bool DidBailout = true;
1592 invalid<ReportUnprofitable>(Context, /*Assert=*/true, &R);
1593 else
1594 DidBailout = !isValidRegion(Context);
1595
1596 (void)DidBailout;
1597 if (KeepGoing) {
1598 assert((!DidBailout || Context.IsInvalid) &&
1599 "With -polly-detect-keep-going, it is sufficient that if "
1600 "isValidRegion short-circuited, that SCoP is invalid");
1601 } else {
1602 assert(DidBailout == Context.IsInvalid &&
1603 "isValidRegion must short-circuit iff the ScoP is invalid");
1604 }
1605
1606 if (Context.IsInvalid) {
1608 } else {
1609 ValidRegions.insert(&R);
1610 return;
1611 }
1612
1613 for (auto &SubRegion : R)
1614 findScops(*SubRegion);
1615
1616 // Try to expand regions.
1617 //
1618 // As the region tree normally only contains canonical regions, non canonical
1619 // regions that form a Scop are not found. Therefore, those non canonical
1620 // regions are checked by expanding the canonical ones.
1621
1622 std::vector<Region *> ToExpand;
1623
1624 for (auto &SubRegion : R)
1625 ToExpand.push_back(SubRegion.get());
1626
1627 for (Region *CurrentRegion : ToExpand) {
1628 // Skip invalid regions. Regions may become invalid, if they are element of
1629 // an already expanded region.
1630 if (!ValidRegions.count(CurrentRegion))
1631 continue;
1632
1633 // Skip regions that had errors.
1634 bool HadErrors = lookupRejectionLog(CurrentRegion)->hasErrors();
1635 if (HadErrors)
1636 continue;
1637
1638 Region *ExpandedR = expandRegion(*CurrentRegion);
1639
1640 if (!ExpandedR)
1641 continue;
1642
1643 R.addSubRegion(ExpandedR, true);
1644 ValidRegions.insert(ExpandedR);
1645 removeCachedResults(*CurrentRegion);
1647 }
1648}
1649
1651 Region &CurRegion = Context.CurRegion;
1652
1653 for (const BasicBlock *BB : CurRegion.blocks()) {
1654 Loop *L = LI.getLoopFor(BB);
1655 if (L && L->getHeader() == BB) {
1656 if (CurRegion.contains(L)) {
1657 if (!isValidLoop(L, Context)) {
1658 Context.IsInvalid = true;
1659 if (!KeepGoing)
1660 return false;
1661 }
1662 } else {
1663 SmallVector<BasicBlock *, 1> Latches;
1664 L->getLoopLatches(Latches);
1665 for (BasicBlock *Latch : Latches)
1666 if (CurRegion.contains(Latch))
1667 return invalid<ReportLoopOnlySomeLatches>(Context, /*Assert=*/true,
1668 L);
1669 }
1670 }
1671 }
1672
1673 for (BasicBlock *BB : CurRegion.blocks()) {
1674 bool IsErrorBlock = isErrorBlock(*BB, CurRegion);
1675
1676 // Also check exception blocks (and possibly register them as non-affine
1677 // regions). Even though exception blocks are not modeled, we use them
1678 // to forward-propagate domain constraints during ScopInfo construction.
1679 if (!isValidCFG(*BB, false, IsErrorBlock, Context) && !KeepGoing)
1680 return false;
1681
1682 if (IsErrorBlock)
1683 continue;
1684
1685 for (BasicBlock::iterator I = BB->begin(), E = --BB->end(); I != E; ++I)
1686 if (!isValidInstruction(*I, Context)) {
1687 Context.IsInvalid = true;
1688 if (!KeepGoing)
1689 return false;
1690 }
1691 }
1692
1693 if (!hasAffineMemoryAccesses(Context))
1694 return false;
1695
1696 return true;
1697}
1698
1700 int NumLoops) const {
1701 int InstCount = 0;
1702
1703 if (NumLoops == 0)
1704 return false;
1705
1706 for (auto *BB : Context.CurRegion.blocks())
1707 if (Context.CurRegion.contains(LI.getLoopFor(BB)))
1708 InstCount += BB->size();
1709
1710 InstCount = InstCount / NumLoops;
1711
1712 return InstCount >= ProfitabilityMinPerLoopInstructions;
1713}
1714
1716 DetectionContext &Context) const {
1717 for (auto *BB : Context.CurRegion.blocks()) {
1718 auto *L = LI.getLoopFor(BB);
1719 if (!L)
1720 continue;
1721 if (!Context.CurRegion.contains(L))
1722 continue;
1723 if (Context.BoxedLoopsSet.count(L))
1724 continue;
1725 unsigned StmtsWithStoresInLoops = 0;
1726 for (auto *LBB : L->blocks()) {
1727 bool MemStore = false;
1728 for (auto &I : *LBB)
1729 MemStore |= isa<StoreInst>(&I);
1730 StmtsWithStoresInLoops += MemStore;
1731 }
1732 return (StmtsWithStoresInLoops > 1);
1733 }
1734 return false;
1735}
1736
1738 Region &CurRegion = Context.CurRegion;
1739
1741 return true;
1742
1743 // We can probably not do a lot on scops that only write or only read
1744 // data.
1745 if (!Context.hasStores || !Context.hasLoads)
1746 return invalid<ReportUnprofitable>(Context, /*Assert=*/true, &CurRegion);
1747
1748 int NumLoops =
1750 int NumAffineLoops = NumLoops - Context.BoxedLoopsSet.size();
1751
1752 // Scops with at least two loops may allow either loop fusion or tiling and
1753 // are consequently interesting to look at.
1754 if (NumAffineLoops >= 2)
1755 return true;
1756
1757 // A loop with multiple non-trivial blocks might be amendable to distribution.
1758 if (NumAffineLoops == 1 && hasPossiblyDistributableLoop(Context))
1759 return true;
1760
1761 // Scops that contain a loop with a non-trivial amount of computation per
1762 // loop-iteration are interesting as we may be able to parallelize such
1763 // loops. Individual loops that have only a small amount of computation
1764 // per-iteration are performance-wise very fragile as any change to the
1765 // loop induction variables may affect performance. To not cause spurious
1766 // performance regressions, we do not consider such loops.
1767 if (NumAffineLoops == 1 && hasSufficientCompute(Context, NumLoops))
1768 return true;
1769
1770 return invalid<ReportUnprofitable>(Context, /*Assert=*/true, &CurRegion);
1771}
1772
1774 Region &CurRegion = Context.CurRegion;
1775
1776 POLLY_DEBUG(dbgs() << "Checking region: " << CurRegion.getNameStr()
1777 << "\n\t");
1778
1779 if (!PollyAllowFullFunction && CurRegion.isTopLevelRegion()) {
1780 POLLY_DEBUG(dbgs() << "Top level region is invalid\n");
1781 Context.IsInvalid = true;
1782 return false;
1783 }
1784
1785 DebugLoc DbgLoc;
1786 if (CurRegion.getExit() &&
1787 isa<UnreachableInst>(CurRegion.getExit()->getTerminator())) {
1788 POLLY_DEBUG(dbgs() << "Unreachable in exit\n");
1789 return invalid<ReportUnreachableInExit>(Context, /*Assert=*/true,
1790 CurRegion.getExit(), DbgLoc);
1791 }
1792
1793 if (!OnlyRegion.empty() &&
1794 !CurRegion.getEntry()->getName().count(OnlyRegion)) {
1795 POLLY_DEBUG({
1796 dbgs() << "Region entry does not match -polly-only-region";
1797 dbgs() << "\n";
1798 });
1799 Context.IsInvalid = true;
1800 return false;
1801 }
1802
1803 for (BasicBlock *Pred : predecessors(CurRegion.getEntry())) {
1804 Instruction *PredTerm = Pred->getTerminator();
1805 if (isa<IndirectBrInst>(PredTerm) || isa<CallBrInst>(PredTerm))
1807 Context, /*Assert=*/true, PredTerm, PredTerm->getDebugLoc());
1808 }
1809
1810 // SCoP cannot contain the entry block of the function, because we need
1811 // to insert alloca instruction there when translate scalar to array.
1813 CurRegion.getEntry() ==
1814 &(CurRegion.getEntry()->getParent()->getEntryBlock()))
1815 return invalid<ReportEntry>(Context, /*Assert=*/true, CurRegion.getEntry());
1816
1817 if (!allBlocksValid(Context)) {
1818 // TODO: Every failure condition within allBlocksValid should call
1819 // invalid<Reason>(). Otherwise we reject SCoPs without giving feedback to
1820 // the user.
1821 Context.IsInvalid = true;
1822 return false;
1823 }
1824
1825 if (!isReducibleRegion(CurRegion, DbgLoc))
1826 return invalid<ReportIrreducibleRegion>(Context, /*Assert=*/true,
1827 &CurRegion, DbgLoc);
1828
1829 POLLY_DEBUG(dbgs() << "OK\n");
1830 return true;
1831}
1832
1834 F->addFnAttr(PollySkipFnAttr);
1835}
1836
1838 return !F.hasFnAttribute(PollySkipFnAttr);
1839}
1840
1842 for (const Region *R : *this) {
1843 unsigned LineEntry, LineExit;
1844 std::string FileName;
1845
1846 getDebugLocation(R, LineEntry, LineExit, FileName);
1847 DiagnosticScopFound Diagnostic(F, FileName, LineEntry, LineExit);
1848 F.getContext().diagnose(Diagnostic);
1849 }
1850}
1851
1852void ScopDetection::emitMissedRemarks(const Function &F) {
1853 for (auto &DIt : DetectionContextMap) {
1854 DetectionContext &DC = *DIt.getSecond();
1855 if (DC.Log.hasErrors())
1856 emitRejectionRemarks(DIt.getFirst(), DC.Log, ORE);
1857 }
1858}
1859
1860bool ScopDetection::isReducibleRegion(Region &R, DebugLoc &DbgLoc) const {
1861 /// Enum for coloring BBs in Region.
1862 ///
1863 /// WHITE - Unvisited BB in DFS walk.
1864 /// GREY - BBs which are currently on the DFS stack for processing.
1865 /// BLACK - Visited and completely processed BB.
1866 enum Color { WHITE, GREY, BLACK };
1867
1868 BasicBlock *REntry = R.getEntry();
1869 BasicBlock *RExit = R.getExit();
1870 // Map to match the color of a BasicBlock during the DFS walk.
1871 DenseMap<const BasicBlock *, Color> BBColorMap;
1872 // Stack keeping track of current BB and index of next child to be processed.
1873 std::stack<std::pair<BasicBlock *, unsigned>> DFSStack;
1874
1875 unsigned AdjacentBlockIndex = 0;
1876 BasicBlock *CurrBB, *SuccBB;
1877 CurrBB = REntry;
1878
1879 // Initialize the map for all BB with WHITE color.
1880 for (auto *BB : R.blocks())
1881 BBColorMap[BB] = WHITE;
1882
1883 // Process the entry block of the Region.
1884 BBColorMap[CurrBB] = GREY;
1885 DFSStack.push(std::make_pair(CurrBB, 0));
1886
1887 while (!DFSStack.empty()) {
1888 // Get next BB on stack to be processed.
1889 CurrBB = DFSStack.top().first;
1890 AdjacentBlockIndex = DFSStack.top().second;
1891 DFSStack.pop();
1892
1893 // Loop to iterate over the successors of current BB.
1894 const Instruction *TInst = CurrBB->getTerminator();
1895 unsigned NSucc = TInst->getNumSuccessors();
1896 for (unsigned I = AdjacentBlockIndex; I < NSucc;
1897 ++I, ++AdjacentBlockIndex) {
1898 SuccBB = TInst->getSuccessor(I);
1899
1900 // Checks for region exit block and self-loops in BB.
1901 if (SuccBB == RExit || SuccBB == CurrBB)
1902 continue;
1903
1904 // WHITE indicates an unvisited BB in DFS walk.
1905 if (BBColorMap[SuccBB] == WHITE) {
1906 // Push the current BB and the index of the next child to be visited.
1907 DFSStack.push(std::make_pair(CurrBB, I + 1));
1908 // Push the next BB to be processed.
1909 DFSStack.push(std::make_pair(SuccBB, 0));
1910 // First time the BB is being processed.
1911 BBColorMap[SuccBB] = GREY;
1912 break;
1913 } else if (BBColorMap[SuccBB] == GREY) {
1914 // GREY indicates a loop in the control flow.
1915 // If the destination dominates the source, it is a natural loop
1916 // else, an irreducible control flow in the region is detected.
1917 if (!DT.dominates(SuccBB, CurrBB)) {
1918 // Get debug info of instruction which causes irregular control flow.
1919 DbgLoc = TInst->getDebugLoc();
1920 return false;
1921 }
1922 }
1923 }
1924
1925 // If all children of current BB have been processed,
1926 // then mark that BB as fully processed.
1927 if (AdjacentBlockIndex == NSucc)
1928 BBColorMap[CurrBB] = BLACK;
1929 }
1930
1931 return true;
1932}
1933
1935 bool OnlyProfitable) {
1936 if (!OnlyProfitable) {
1937 NumLoopsInScop += Stats.NumLoops;
1938 MaxNumLoopsInScop =
1939 std::max(MaxNumLoopsInScop.getValue(), (uint64_t)Stats.NumLoops);
1940 if (Stats.MaxDepth == 0)
1941 NumScopsDepthZero++;
1942 else if (Stats.MaxDepth == 1)
1943 NumScopsDepthOne++;
1944 else if (Stats.MaxDepth == 2)
1945 NumScopsDepthTwo++;
1946 else if (Stats.MaxDepth == 3)
1947 NumScopsDepthThree++;
1948 else if (Stats.MaxDepth == 4)
1949 NumScopsDepthFour++;
1950 else if (Stats.MaxDepth == 5)
1951 NumScopsDepthFive++;
1952 else
1953 NumScopsDepthLarger++;
1954 } else {
1955 NumLoopsInProfScop += Stats.NumLoops;
1956 MaxNumLoopsInProfScop =
1957 std::max(MaxNumLoopsInProfScop.getValue(), (uint64_t)Stats.NumLoops);
1958 if (Stats.MaxDepth == 0)
1959 NumProfScopsDepthZero++;
1960 else if (Stats.MaxDepth == 1)
1961 NumProfScopsDepthOne++;
1962 else if (Stats.MaxDepth == 2)
1963 NumProfScopsDepthTwo++;
1964 else if (Stats.MaxDepth == 3)
1965 NumProfScopsDepthThree++;
1966 else if (Stats.MaxDepth == 4)
1967 NumProfScopsDepthFour++;
1968 else if (Stats.MaxDepth == 5)
1969 NumProfScopsDepthFive++;
1970 else
1971 NumProfScopsDepthLarger++;
1972 }
1973}
1974
1977 auto DCMIt = DetectionContextMap.find(getBBPairForRegion(R));
1978 if (DCMIt == DetectionContextMap.end())
1979 return nullptr;
1980 return DCMIt->second.get();
1981}
1982
1983const RejectLog *ScopDetection::lookupRejectionLog(const Region *R) const {
1985 return DC ? &DC->Log : nullptr;
1986}
1987
1988void ScopDetection::verifyRegion(const Region &R) {
1989 assert(isMaxRegionInScop(R) && "Expect R is a valid region.");
1990
1991 DetectionContext Context(const_cast<Region &>(R), AA, true /*verifying*/);
1992 isValidRegion(Context);
1993}
1994
1996 if (!VerifyScops)
1997 return;
1998
1999 for (const Region *R : ValidRegions)
2000 verifyRegion(*R);
2001}
2002
2004 // Disable runtime alias checks if we ignore aliasing all together.
2005 if (IgnoreAliasing)
2007}
2008
2009AnalysisKey ScopAnalysis::Key;
2010
2011ScopDetection ScopAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
2012 auto &LI = FAM.getResult<LoopAnalysis>(F);
2013 auto &RI = FAM.getResult<RegionInfoAnalysis>(F);
2014 auto &AA = FAM.getResult<AAManager>(F);
2015 auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(F);
2016 auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
2017 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
2018
2019 ScopDetection Result(DT, SE, LI, RI, AA, ORE);
2020 Result.detect(F);
2021 return Result;
2022}
2023
2024PreservedAnalyses ScopAnalysisPrinterPass::run(Function &F,
2025 FunctionAnalysisManager &FAM) {
2026 OS << "Detected Scops in Function " << F.getName() << "\n";
2027 auto &SD = FAM.getResult<ScopAnalysis>(F);
2028 for (const Region *R : SD.ValidRegions)
2029 OS << "Valid Region for Scop: " << R->getNameStr() << '\n';
2030
2031 OS << "\n";
2032 return PreservedAnalyses::all();
2033}
S1()
static cl::opt< bool > Verify("polly-codegen-verify", cl::desc("Verify the function generated by Polly"), cl::Hidden, cl::cat(PollyCategory))
llvm::cl::OptionCategory PollyCategory
#define POLLY_DEBUG(X)
Definition PollyDebug.h:23
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.
Definition ScopHelper.h:141
static MemAccInst dyn_cast(llvm::Value &V)
Definition ScopHelper.h:179
llvm::Value * getPointerOperand() const
Definition ScopHelper.h:249
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.
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.
void detect(Function &F)
ScalarEvolution & SE
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 hasPossiblyDistributableLoop(DetectionContext &Context) const
Check if the unique affine loop might be amendable to distribution.
bool isValidBranch(BasicBlock &BB, CondBrInst *BI, Value *Condition, bool IsLoopBranch, DetectionContext &Context)
Check if the branch BI with condition Condition is valid.
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.
bool isCompatibleType(Instruction *Inst, llvm::Type *Ty, DetectionContext &Context)
Filter out types that we do not support.
static ScopDetection::LoopStats countBeneficialSubLoops(Loop *L, ScalarEvolution &SE, unsigned MinProfitableTrips)
Count the number of loops and the maximal loop depth in L.
#define assert(exp)
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.
std::shared_ptr< RejectReason > RejectReasonPtr
StringRef PollySkipFnAttr
A function attribute which will cause Polly to skip the function.
bool PollyAllowFullFunction
llvm::SetVector< llvm::AssertingVH< llvm::LoadInst > > InvariantLoadsSetTy
Type for a set of invariant loads.
Definition ScopHelper.h:110
bool PollyTrackFailures
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.
Definition ScopInfo.h:150
@ PHI
MemoryKind::PHI: Models PHI nodes within the SCoP.
Definition ScopInfo.h:187
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.
std::map< const Instruction *, MemAcc > MapInsnToMemAcc
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
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 PollyDelinearize
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.
std::pair< llvm::BasicBlock *, llvm::BasicBlock * > BBPair
Type to hold region delimiters (entry & exit block).
Definition Utils.h:31
SmallVector< const SCEV *, 4 > DelinearizedSubscripts
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
ScopDetection Result
Result run(Function &F, FunctionAnalysisManager &FAM)
static AnalysisKey Key
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.
static TupleKindPtr Res
static TupleKindPtr Str
static TupleKindPtr Ctx