LLVM: lib/Analysis/Delinearization.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
30
31using namespace llvm;
32
33#define DL_NAME "delinearize"
34#define DEBUG_TYPE DL_NAME
35
37 "delinearize-use-fixed-size-array-heuristic", cl::init(false), cl::Hidden,
38 cl::desc("When printing analysis, use the heuristic for fixed-size arrays "
39 "if the default delinearizetion fails."));
40
41
46 return false;
47 });
48}
49
50namespace {
51
52
53struct SCEVCollectStrides {
54 ScalarEvolution &SE;
55 SmallVectorImpl<const SCEV *> &Strides;
56
57 SCEVCollectStrides(ScalarEvolution &SE, SmallVectorImpl<const SCEV *> &S)
58 : SE(SE), Strides(S) {}
59
60 bool follow(const SCEV *S) {
62 Strides.push_back(AR->getStepRecurrence(SE));
63 return true;
64 }
65
66 bool isDone() const { return false; }
67};
68
69
70struct SCEVCollectTerms {
71 SmallVectorImpl<const SCEV *> &Terms;
72
73 SCEVCollectTerms(SmallVectorImpl<const SCEV *> &T) : Terms(T) {}
74
75 bool follow(const SCEV *S) {
79 Terms.push_back(S);
80
81
82 return false;
83 }
84
85
86 return true;
87 }
88
89 bool isDone() const { return false; }
90};
91
92
93struct SCEVHasAddRec {
94 bool &ContainsAddRec;
95
96 SCEVHasAddRec(bool &ContainsAddRec) : ContainsAddRec(ContainsAddRec) {
97 ContainsAddRec = false;
98 }
99
100 bool follow(const SCEV *S) {
102 ContainsAddRec = true;
103
104
105 return false;
106 }
107
108
109 return true;
110 }
111
112 bool isDone() const { return false; }
113};
114
115
116
117
118
119
120
121
122
123
124
125
126
127struct SCEVCollectAddRecMultiplies {
128 SmallVectorImpl<const SCEV *> &Terms;
129 ScalarEvolution &SE;
130
131 SCEVCollectAddRecMultiplies(SmallVectorImpl<const SCEV *> &T,
132 ScalarEvolution &SE)
133 : Terms(T), SE(SE) {}
134
135 bool follow(const SCEV *S) {
137 bool HasAddRec = false;
139 for (const SCEV *Op : Mul->operands()) {
144 HasAddRec = true;
145 } else {
146 bool ContainsAddRec = false;
147 SCEVHasAddRec ContiansAddRec(ContainsAddRec);
149 HasAddRec |= ContainsAddRec;
150 }
151 }
152 if (Operands.size() == 0)
153 return true;
154
155 if (!HasAddRec)
156 return false;
157
158 Terms.push_back(SE.getMulExpr(Operands));
159
160 return false;
161 }
162
163
164 return true;
165 }
166
167 bool isDone() const { return false; }
168};
169
170}
171
172
173
174
175
179 SCEVCollectStrides StrideCollector(SE, Strides);
180 visitAll(Expr, StrideCollector);
181
183 dbgs() << "Strides:\n";
184 for (const SCEV *S : Strides)
186 });
187
188 for (const SCEV *S : Strides) {
189 SCEVCollectTerms TermCollector(Terms);
191 }
192
194 dbgs() << "Terms:\n";
195 for (const SCEV *T : Terms)
197 });
198
199 SCEVCollectAddRecMultiplies MulCollector(Terms, SE);
200 visitAll(Expr, MulCollector);
201}
202
207 const SCEV *Step = Terms[Last];
208
209
210 if (Last == 0) {
213 for (const SCEV *Op : M->operands())
216
218 }
219
220 Sizes.push_back(Step);
221 return true;
222 }
223
224 for (const SCEV *&Term : Terms) {
225
226 const SCEV *Q, *R;
228
229
230 if (!R->isZero())
231 return false;
232
233 Term = Q;
234 }
235
236
238
239 if (Terms.size() > 0)
241 return false;
242
243 Sizes.push_back(Step);
244 return true;
245}
246
247
249 for (const SCEV *T : Terms)
251 return true;
252
253 return false;
254}
255
256
259 return Expr->getNumOperands();
260 return 1;
261}
262
265 return nullptr;
266
268 return T;
269
272 for (const SCEV *Op : M->operands())
275
277 }
278
279 return T;
280}
281
285 const SCEV *ElementSize) {
286 if (Terms.size() < 1 || !ElementSize)
287 return;
288
289
290
292 return;
293
295 dbgs() << "Terms:\n";
296 for (const SCEV *T : Terms)
298 });
299
300
303
304
307 });
308
309
310
311 for (const SCEV *&Term : Terms) {
312 const SCEV *Q, *R;
315 Term = Q;
316 }
317
319
320
321 for (const SCEV *T : Terms)
324
326 dbgs() << "Terms after sorting:\n";
327 for (const SCEV *T : NewTerms)
329 });
330
332 Sizes.clear();
333 return;
334 }
335
336
337 Sizes.push_back(ElementSize);
338
340 dbgs() << "Sizes:\n";
341 for (const SCEV *S : Sizes)
343 });
344}
345
349
350 if (Sizes.empty())
351 return;
352
354 if (!AR->isAffine())
355 return;
356
357
358 Subscripts.clear();
359
361 << "Memory Access Function: " << *Expr << "\n");
362
363 const SCEV *Res = Expr;
364 int Last = Sizes.size() - 1;
365
366 for (int i = Last; i >= 0; i--) {
368 const SCEV *Q, *R;
369
371
373 dbgs() << "Computing 'MemAccFn / Sizes[" << i << "]':\n";
374 dbgs() << " MemAccFn: " << *Res << "\n";
375 dbgs() << " Sizes[" << i << "]: " << *Size << "\n";
376 dbgs() << " Quotient (Leftover): " << *Q << "\n";
377 dbgs() << " Remainder (Subscript Access Function): " << *R << "\n";
378 });
379
380 Res = Q;
381
382
383
384 if (i == Last) {
385
386
387 if (!R->isZero()) {
388 Subscripts.clear();
389 Sizes.clear();
390 return;
391 }
392
393 continue;
394 }
395
396
398 }
399
400
401
403
404 std::reverse(Subscripts.begin(), Subscripts.end());
405
407 dbgs() << "Subscripts:\n";
408 for (const SCEV *S : Subscripts)
410 dbgs() << "\n";
411 });
412}
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
466 const SCEV *ElementSize) {
467
468 Subscripts.clear();
469 Sizes.clear();
470
471
474
475 if (Terms.empty())
476 return;
477
478
480
481 if (Sizes.empty())
482 return;
483
484
486}
487
490 return Const->getAPInt();
491 return std::nullopt;
492}
493
494
495
496
497
501
502
504 const uint64_t Mod = Const->getAPInt().urem(ElementSize);
505 return Mod == 0;
506 }
507
510 return false;
511
513 std::optional StepAPInt = tryIntoAPInt(Step);
514 if (!StepAPInt)
515 return false;
516
520 if (R != 0)
521 return false;
522
523
524 std::optional<uint64_t> StepVal = Q.tryZExtValue();
525 if (!StepVal)
526 return false;
527
530}
531
534 const SCEV *ElementSize) {
535 if (!ElementSize)
536 return false;
537
538 std::optional ElementSizeAPInt = tryIntoAPInt(ElementSize);
539 if (!ElementSizeAPInt || *ElementSizeAPInt == 0)
540 return false;
541
542 std::optional<uint64_t> ElementSizeConst = ElementSizeAPInt->tryZExtValue();
543
544
545 if (!ElementSizeConst)
546 return false;
547
549 Sizes.empty()) {
550 Sizes.clear();
551 return false;
552 }
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571 llvm::sort(Sizes.rbegin(), Sizes.rend());
572 Sizes.erase(llvm::unique(Sizes), Sizes.end());
573
574
575
576 assert(Sizes.back() != 0 && "Unexpected zero size in Sizes.");
577 Sizes.back() = 1;
578
579 for (unsigned I = 0; I + 1 < Sizes.size(); I++) {
580 uint64_t PrevSize = Sizes[I + 1];
581 if (Sizes[I] % PrevSize) {
582 Sizes.clear();
583 return false;
584 }
585 Sizes[I] /= PrevSize;
586 }
587
588
589 Sizes.back() = *ElementSizeConst;
590 return true;
591}
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
647 const SCEV *ElementSize) {
648
649 Subscripts.clear();
650 Sizes.clear();
651
652
655 Sizes.clear();
656 return false;
657 }
658
659
662
663
665
666 return !Subscripts.empty();
667}
668
670 const Value *Ptr) {
671 bool Inbounds = false;
673 Inbounds = SrcGEP->isInBounds();
674 if (Inbounds) {
676 if (AddRec->isAffine()) {
677
678
681 return true;
682 }
683 }
684 }
685
687}
688
689
690
691
692
693
694
697
700 if (!SType || !SizeType)
701 return false;
702 Type *MaxType =
703 (SType->getBitWidth() >= SizeType->getBitWidth()) ? SType : SizeType;
706
707 auto CollectUpperBound = [&](const Loop *L, Type *T) -> const SCEV * {
711 }
712 return nullptr;
713 };
714
715 auto CheckAddRecBECount = [&]() {
718 return false;
719 const SCEV *BECount = CollectUpperBound(AddRec->getLoop(), MaxType);
720
722 return false;
728
729
730
731
733 return true;
734
735
736
738 return true;
739
740
741
743 return true;
744
745 return false;
746 };
747
748 if (CheckAddRecBECount())
749 return true;
750
751
754}
755
759 const Value *Ptr) {
760
761
762
763
764
765
766
768 if (!SE.willNotOverflow(Instruction::Add, true, A, B))
769 return nullptr;
771 };
772
774 if (!SE.willNotOverflow(Instruction::Mul, true, A, B))
775 return nullptr;
777 };
778
779
780 for (size_t I = 1; I < Sizes.size(); ++I) {
782 const SCEV *Subscript = Subscripts[I];
784 return false;
786 return false;
787 }
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
813 for (const SCEV *Size : Sizes) {
815 if (!Prod)
816 return false;
817 }
819 if (!Min)
820 return false;
821
822
823
825 if (!MaxPlusOne)
826 return false;
827 if (!SE.willNotOverflow(Instruction::Sub, true, MaxPlusOne,
829 return false;
830
831 return true;
832}
833
838 assert(Subscripts.empty() && Sizes.empty() &&
839 "Expected output lists to be empty on entry to this function.");
840 assert(GEP && "getIndexExpressionsFromGEP called with a null GEP");
842 Type *Ty = nullptr;
844 bool DroppedFirstDim = false;
845 for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
847 if (i == 1) {
848 Ty = GEP->getSourceElementType();
850 if (Const->getValue()->isZero()) {
851 DroppedFirstDim = true;
852 continue;
853 }
855 continue;
856 }
857
859 if (!ArrayTy) {
860 LLVM_DEBUG(dbgs() << "GEP delinearize failed: " << *Ty
861 << " is not an array type.\n");
862 Subscripts.clear();
863 Sizes.clear();
864 return false;
865 }
866
868 if (!(DroppedFirstDim && i == 2))
869 Sizes.push_back(SE.getConstant(IndexTy, ArrayTy->getNumElements()));
870
871 Ty = ArrayTy->getElementType();
872 }
874 dbgs() << "Subscripts:\n";
875 for (const SCEV *S : Subscripts)
876 dbgs() << *S << "\n";
877 dbgs() << "\n";
878 });
879
880 return !Subscripts.empty();
881}
882
883namespace {
884
887 O << "Printing analysis 'Delinearization' for function '" << F->getName()
888 << "':";
890
892 continue;
893
896
897
898 if (!L)
899 continue;
900
902
905
906 if (!BasePointer)
907 break;
908 AccessFn = SE->getMinusSCEV(AccessFn, BasePointer);
909
910 O << "\n";
911 O << "Inst:" << Inst << "\n";
912 O << "AccessFunction: " << *AccessFn << "\n";
913
915
916 auto IsDelinearizationFailed = [&]() {
917 return Subscripts.size() == 0 || Sizes.size() == 0 ||
918 Subscripts.size() != Sizes.size();
919 };
920
923 Subscripts.clear();
927 }
928
929 if (IsDelinearizationFailed()) {
930 O << "failed to delinearize\n";
931 continue;
932 }
933
934 O << "Base offset: " << *BasePointer << "\n";
935 O << "ArrayDecl[UnknownSize]";
936 int Size = Subscripts.size();
937 for (int i = 0; i < Size - 1; i++)
938 O << "[" << *Sizes[i] << "]";
939 O << " with elements of " << *Sizes[Size - 1] << " bytes.\n";
940
941 O << "ArrayRef";
942 for (int i = 0; i < Size; i++)
943 O << "[" << *Subscripts[i] << "]";
944 O << "\n";
945
948 O << "Delinearization validation: " << (IsValid ? "Succeeded" : "Failed")
949 << "\n";
950 }
951}
952
953}
954
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static const SCEV * removeConstantFactors(ScalarEvolution &SE, const SCEV *T)
Definition Delinearization.cpp:263
static bool collectConstantAbsSteps(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< uint64_t > &Steps, uint64_t ElementSize)
Collects the absolute values of constant steps for all induction variables.
Definition Delinearization.cpp:498
static bool isKnownLessThan(ScalarEvolution *SE, const SCEV *S, const SCEV *Size)
Compare to see if S is less than Size, using.
Definition Delinearization.cpp:695
static cl::opt< bool > UseFixedSizeArrayHeuristic("delinearize-use-fixed-size-array-heuristic", cl::init(false), cl::Hidden, cl::desc("When printing analysis, use the heuristic for fixed-size arrays " "if the default delinearizetion fails."))
static bool findArrayDimensionsRec(ScalarEvolution &SE, SmallVectorImpl< const SCEV * > &Terms, SmallVectorImpl< const SCEV * > &Sizes)
Definition Delinearization.cpp:203
static bool containsUndefs(const SCEV *S)
Definition Delinearization.cpp:42
static std::optional< APInt > tryIntoAPInt(const SCEV *S)
Definition Delinearization.cpp:488
static bool containsParameters(SmallVectorImpl< const SCEV * > &Terms)
Definition Delinearization.cpp:248
static int numberOfTerms(const SCEV *S)
Definition Delinearization.cpp:257
This header defines various interfaces for pass management in LLVM.
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
static SymbolRef::Type getType(const Symbol *Sym)
Class for arbitrary precision integers.
std::optional< uint64_t > tryZExtValue() const
Get zero extended value if possible.
static LLVM_ABI void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)
Dual division/remainder interface.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Analysis pass that exposes the LoopInfo for a function.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This node represents a polynomial recurrence on the trip count of the specified loop.
const SCEV * getStart() const
LLVM_ABI const SCEV * evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const
Return the value of this chain of recurrences at the specified iteration number.
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values.
const Loop * getLoop() const
This node represents multiplication of some number of SCEVs.
bool hasNoSignedWrap() const
This means that we are dealing with an entirely unknown SCEV value, and only represent it as its LLVM...
This class represents an analyzed expression in the program.
LLVM_ABI bool isZero() const
Return true if the expression is a constant zero.
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
Analysis pass that exposes the ScalarEvolution for a function.
The main scalar evolution driver.
LLVM_ABI bool isKnownNonNegative(const SCEV *S)
Test if the given expression is known to be non-negative.
LLVM_ABI bool isKnownNonPositive(const SCEV *S)
Test if the given expression is known to be non-positive.
LLVM_ABI bool isKnownNegative(const SCEV *S)
Test if the given expression is known to be negative.
LLVM_ABI const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
LLVM_ABI const SCEV * getBackedgeTakenCount(const Loop *L, ExitCountKind Kind=Exact)
If the specified loop has a predictable backedge-taken count, return it, otherwise return a SCEVCould...
LLVM_ABI bool willNotOverflow(Instruction::BinaryOps BinOp, bool Signed, const SCEV *LHS, const SCEV *RHS, const Instruction *CtxI=nullptr)
Is operation BinOp between LHS and RHS provably does not have a signed/unsigned overflow (Signed)?
LLVM_ABI const SCEV * getConstant(ConstantInt *V)
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
LLVM_ABI Type * getEffectiveSCEVType(Type *Ty) const
Return a type with the same bitwidth as the given type and which represents how SCEV will treat the g...
LLVM_ABI const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI bool hasLoopInvariantBackedgeTakenCount(const Loop *L)
Return true if the specified loop has an analyzable loop-invariant backedge-taken count.
LLVM_ABI const SCEV * getPointerBase(const SCEV *V)
Transitively follow the chain of pointer-type operands until reaching a SCEV that does not have a sin...
LLVM_ABI const SCEV * getMulExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
LLVM_ABI const SCEV * getElementSize(Instruction *Inst)
Return the size of an element read or written by Inst.
LLVM_ABI const SCEV * getTruncateOrZeroExtend(const SCEV *V, Type *Ty, unsigned Depth=0)
Return a SCEV corresponding to a conversion of the input value to the specified type.
LLVM_ABI const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void visitAll(const SCEV *Root, SV &Visitor)
Use SCEVTraversal to visit all nodes in the given expression tree.
std::enable_if_t< std::is_signed_v< T >, T > MulOverflow(T X, T Y, T &Result)
Multiply two signed integers, computing the two's complement truncated result, returning true if an o...
void collectParametricTerms(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Terms)
Collect parametric terms occurring in step expressions (first step of delinearization).
Definition Delinearization.cpp:176
void findArrayDimensions(ScalarEvolution &SE, SmallVectorImpl< const SCEV * > &Terms, SmallVectorImpl< const SCEV * > &Sizes, const SCEV *ElementSize)
Compute the array dimensions Sizes from the set of Terms extracted from the memory access function of...
Definition Delinearization.cpp:282
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
auto unique(Range &&R, Predicate P)
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
void computeAccessFunctions(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< const SCEV * > &Sizes)
Return in Subscripts the access functions for each dimension in Sizes (third step of delinearization)...
Definition Delinearization.cpp:346
bool delinearizeFixedSizeArray(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< const SCEV * > &Sizes, const SCEV *ElementSize)
Split this SCEVAddRecExpr into two vectors of SCEVs representing the subscripts and sizes of an acces...
Definition Delinearization.cpp:644
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
@ Mul
Product of integers.
DWARFExpression::Operation Op
void delinearize(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< const SCEV * > &Sizes, const SCEV *ElementSize)
Split this SCEVAddRecExpr into two vectors of SCEVs representing the subscripts and sizes of an array...
Definition Delinearization.cpp:463
bool findFixedSizeArrayDimensions(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< uint64_t > &Sizes, const SCEV *ElementSize)
Compute the dimensions of fixed size array from \Expr and save the results in Sizes.
Definition Delinearization.cpp:532
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
std::enable_if_t< std::is_signed_v< T >, T > AddOverflow(T X, T Y, T &Result)
Add two signed integers, computing the two's complement truncated result, returning true if overflow ...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
bool validateDelinearizationResult(ScalarEvolution &SE, ArrayRef< const SCEV * > Sizes, ArrayRef< const SCEV * > Subscripts, const Value *Ptr=nullptr)
Check that each subscript in Subscripts is within the corresponding size in Sizes.
Definition Delinearization.cpp:756
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
bool getIndexExpressionsFromGEP(ScalarEvolution &SE, const GetElementPtrInst *GEP, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< const SCEV * > &Sizes)
Gathers the individual index expressions from a GEP instruction.
Definition Delinearization.cpp:834
bool SCEVExprContains(const SCEV *Root, PredTy Pred)
Return true if any node in Root satisfies the predicate Pred.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition Delinearization.cpp:957
DelinearizationPrinterPass(raw_ostream &OS)
Definition Delinearization.cpp:955
static void divide(ScalarEvolution &SE, const SCEV *Numerator, const SCEV *Denominator, const SCEV **Quotient, const SCEV **Remainder)
Computes the Quotient and Remainder of the division of Numerator by Denominator.