LLVM 24.0.0git
DependenceAnalysis.h
Go to the documentation of this file.
1//===-- llvm/Analysis/DependenceAnalysis.h -------------------- -*- C++ -*-===//
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// DependenceAnalysis is an LLVM pass that analyses dependences between memory
10// accesses. Currently, it is an implementation of the approach described in
11//
12// Practical Dependence Testing
13// Goff, Kennedy, Tseng
14// PLDI 1991
15//
16// There's a single entry point that analyzes the dependence between a pair
17// of memory references in a function, returning either NULL, for no dependence,
18// or a more-or-less detailed description of the dependence between them.
19//
20// This pass exists to support the DependenceGraph pass. There are two separate
21// passes because there's a useful separation of concerns. A dependence exists
22// if two conditions are met:
23//
24// 1) Two instructions reference the same memory location, and
25// 2) There is a flow of control leading from one instruction to the other.
26//
27// DependenceAnalysis attacks the first condition; DependenceGraph will attack
28// the second (it's not yet ready).
29//
30// Please note that this is work in progress and the interface is subject to
31// change.
32//
33// Plausible changes:
34// Return a set of more precise dependences instead of just one dependence
35// summarizing all.
36//
37//===----------------------------------------------------------------------===//
38
39#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
40#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
41
45#include "llvm/IR/PassManager.h"
46#include "llvm/Pass.h"
48
49namespace llvm {
50class AAResults;
51struct AnalysisOptions;
52template <typename T> class ArrayRef;
53class Loop;
54class LoopInfo;
55class SCEVConstant;
56class raw_ostream;
57
58/// Dependence - This class represents a dependence between two memory
59/// memory references in a function. It contains minimal information and
60/// is used in the very common situation where the compiler is unable to
61/// determine anything beyond the existence of a dependence; that is, it
62/// represents a confused dependence (see also FullDependence). In most
63/// cases (for output, flow, and anti dependences), the dependence implies
64/// an ordering, where the source must precede the destination; in contrast,
65/// input dependences are unordered.
66///
67/// When a dependence graph is built, each Dependence will be a member of
68/// the set of predecessor edges for its destination instruction and a set
69/// if successor edges for its source instruction. These sets are represented
70/// as singly-linked lists, with the "next" fields stored in the dependence
71/// itelf.
73protected:
74 Dependence(Dependence &&) = default;
76
77public:
78 Dependence(Instruction *Source, Instruction *Destination,
79 const SCEVUnionPredicate &A)
80 : Src(Source), Dst(Destination), Assumptions(A) {}
81 virtual ~Dependence() = default;
82
83 /// Dependence::DVEntry - Each level in the distance/direction vector
84 /// has a direction (or perhaps a union of several directions), and
85 /// perhaps a distance.
86 /// The dependency information could be across a single loop level or across
87 /// two separate levels that have the same trip count and nesting depth,
88 /// which helps to provide information for loop fusion candidation.
89 /// For example, loops b and c have the same iteration count and depth:
90 /// for (a = ...) {
91 /// for (b = 0; b < 10; b++) {
92 /// }
93 /// for (c = 0; c < 10; c++) {
94 /// }
95 /// }
96 struct DVEntry {
97 enum : unsigned char {
98 NONE = 0,
99 LT = 1,
100 EQ = 2,
101 LE = 3,
102 GT = 4,
103 NE = 5,
104 GE = 6,
105 ALL = 7
106 };
107 unsigned char Direction : 3; // Init to ALL, then refine.
108 bool Scalar : 1; // Init to true.
109 const SCEV *Distance = nullptr; // NULL implies no distance available.
111 };
112
113 /// getSrc - Returns the source instruction for this dependence.
114 Instruction *getSrc() const { return Src; }
115
116 /// getDst - Returns the destination instruction for this dependence.
117 Instruction *getDst() const { return Dst; }
118
119 /// isInput - Returns true if this is an input dependence.
120 bool isInput() const;
121
122 /// isOutput - Returns true if this is an output dependence.
123 bool isOutput() const;
124
125 /// isFlow - Returns true if this is a flow (aka true) dependence.
126 bool isFlow() const;
127
128 /// isAnti - Returns true if this is an anti dependence.
129 bool isAnti() const;
130
131 /// isOrdered - Returns true if dependence is Output, Flow, or Anti
132 bool isOrdered() const { return isOutput() || isFlow() || isAnti(); }
133
134 /// isUnordered - Returns true if dependence is Input
135 bool isUnordered() const { return isInput(); }
136
137 /// isLoopIndependent - Returns true if this is a loop-independent
138 /// dependence.
139 virtual bool isLoopIndependent() const { return true; }
140
141 /// isConfused - Returns true if this dependence is confused
142 /// (the compiler understands nothing and makes worst-case assumptions).
143 virtual bool isConfused() const { return true; }
144
145 /// getLevels - Returns the number of common loops surrounding the
146 /// source and destination of the dependence.
147 virtual unsigned getLevels() const { return 0; }
148
149 /// getSameSDLevels - Returns the number of separate SameSD loops surrounding
150 /// the source and destination of the dependence.
151 virtual unsigned getSameSDLevels() const { return 0; }
152
153 /// getDirection - Returns the direction associated with a particular
154 /// common or SameSD level.
155 virtual unsigned getDirection(unsigned Level, bool SameSD = false) const {
156 return DVEntry::ALL;
157 }
158
159 /// getDistance - Returns the distance (or NULL) associated with a
160 /// particular common or SameSD level.
161 virtual const SCEV *getDistance(unsigned Level, bool SameSD = false) const {
162 return nullptr;
163 }
164
165 /// Check if the direction vector is negative. A negative direction
166 /// vector means Src and Dst are reversed in the actual program.
167 virtual bool isDirectionNegative() const { return false; }
168
169 /// Negate the dependence by swapping the source and destination, and
170 /// reversing the direction and distance information.
171 virtual void negate(ScalarEvolution &SE) {}
172
173 /// If the direction vector is negative, normalize the direction
174 /// vector to make it non-negative. Normalization is done by reversing
175 /// Src and Dst, plus reversing the dependence directions and distances
176 /// in the vector.
177 virtual bool normalize(ScalarEvolution *SE) { return false; }
178
179 /// inSameSDLoops - Returns true if this level is an SameSD level, i.e.,
180 /// performed across two separate loop nests that have the Same Iteration and
181 /// Depth.
182 virtual bool inSameSDLoops(unsigned Level) const { return false; }
183
184 /// isScalar - Returns true if a particular regular or SameSD level is
185 /// scalar; that is, if no subscript in the source or destination mention
186 /// the induction variable associated with the loop at this level.
187 virtual bool isScalar(unsigned Level, bool SameSD = false) const;
188
189 /// getNextPredecessor - Returns the value of the NextPredecessor field.
190 const Dependence *getNextPredecessor() const { return NextPredecessor; }
191
192 /// getNextSuccessor - Returns the value of the NextSuccessor field.
193 const Dependence *getNextSuccessor() const { return NextSuccessor; }
194
195 /// setNextPredecessor - Sets the value of the NextPredecessor
196 /// field.
197 void setNextPredecessor(const Dependence *pred) { NextPredecessor = pred; }
198
199 /// setNextSuccessor - Sets the value of the NextSuccessor field.
200 void setNextSuccessor(const Dependence *succ) { NextSuccessor = succ; }
201
202 /// getRuntimeAssumptions - Returns the runtime assumptions under which this
203 /// Dependence relation is valid.
204 SCEVUnionPredicate getRuntimeAssumptions() const { return Assumptions; }
205
206 /// dump - For debugging purposes, dumps a dependence to OS.
207 void dump(raw_ostream &OS) const;
208
209 /// dumpImp - For debugging purposes. Dumps a dependence to OS with or
210 /// without considering the SameSD levels.
211 void dumpImp(raw_ostream &OS, bool IsSameSD = false) const;
212
213protected:
215
216private:
217 SCEVUnionPredicate Assumptions;
218 const Dependence *NextPredecessor = nullptr, *NextSuccessor = nullptr;
219 friend class DependenceInfo;
220};
221
222/// FullDependence - This class represents a dependence between two memory
223/// references in a function. It contains detailed information about the
224/// dependence (direction vectors, etc.) and is used when the compiler is
225/// able to accurately analyze the interaction of the references; that is,
226/// it is not a confused dependence (see Dependence). In most cases
227/// (for output, flow, and anti dependences), the dependence implies an
228/// ordering, where the source must precede the destination; in contrast,
229/// input dependences are unordered.
230class LLVM_ABI FullDependence final : public Dependence {
231public:
232 FullDependence(Instruction *Source, Instruction *Destination,
233 const SCEVUnionPredicate &Assumes,
234 bool PossiblyLoopIndependent, unsigned Levels);
235
236 /// isLoopIndependent - Returns true if this is a loop-independent
237 /// dependence.
238 bool isLoopIndependent() const override { return LoopIndependent; }
239
240 /// isConfused - Returns true if this dependence is confused
241 /// (the compiler understands nothing and makes worst-case
242 /// assumptions).
243 bool isConfused() const override { return false; }
244
245 /// getLevels - Returns the number of common loops surrounding the
246 /// source and destination of the dependence.
247 unsigned getLevels() const override { return Levels; }
248
249 /// getSameSDLevels - Returns the number of separate SameSD loops surrounding
250 /// the source and destination of the dependence.
251 unsigned getSameSDLevels() const override { return SameSDLevels; }
252
253 /// getDVEntry - Returns the DV entry associated with a regular or a
254 /// SameSD level.
255 DVEntry getDVEntry(unsigned Level, bool IsSameSD) const {
256 if (!IsSameSD) {
257 assert(0 < Level && Level <= Levels && "Level out of range");
258 return DV[Level - 1];
259 } else {
260 assert(Levels < Level &&
261 Level <= static_cast<unsigned>(Levels) + SameSDLevels &&
262 "isSameSD level out of range");
263 return DVSameSD[Level - Levels - 1];
264 }
265 }
266
267 /// getDirection - Returns the direction associated with a particular
268 /// common or SameSD level.
269 unsigned getDirection(unsigned Level, bool SameSD = false) const override;
270
271 /// getDistance - Returns the distance (or NULL) associated with a
272 /// particular common or SameSD level.
273 const SCEV *getDistance(unsigned Level, bool SameSD = false) const override;
274
275 /// Check if the direction vector is negative. A negative direction
276 /// vector means Src and Dst are reversed in the actual program.
277 bool isDirectionNegative() const override;
278
279 void negate(ScalarEvolution &SE) override;
280
281 /// If the direction vector is negative, normalize the direction
282 /// vector to make it non-negative. Normalization is done by reversing
283 /// Src and Dst, plus reversing the dependence directions and distances
284 /// in the vector.
285 bool normalize(ScalarEvolution *SE) override;
286
287 /// inSameSDLoops - Returns true if this level is an SameSD level, i.e.,
288 /// performed across two separate loop nests that have the Same Iteration and
289 /// Depth.
290 bool inSameSDLoops(unsigned Level) const override;
291
292 /// isScalar - Returns true if a particular regular or SameSD level is
293 /// scalar; that is, if no subscript in the source or destination mention
294 /// the induction variable associated with the loop at this level.
295 bool isScalar(unsigned Level, bool SameSD = false) const override;
296
297private:
298 unsigned short Levels;
299 unsigned short SameSDLevels;
300 bool LoopIndependent;
301 std::unique_ptr<DVEntry[]> DV;
302 std::unique_ptr<DVEntry[]> DVSameSD; // DV entries on SameSD levels
303 friend class DependenceInfo;
304};
305
306/// DependenceInfo - This class is the main dependence-analysis driver.
308public:
310 LoopInfo *LI);
311
312 /// Handle transitive invalidation when the cached analysis results go away.
314 FunctionAnalysisManager::Invalidator &Inv);
315
316 /// depends - Tests for a dependence between the Src and Dst instructions.
317 /// Returns NULL if no dependence; otherwise, returns a Dependence (or a
318 /// FullDependence) with as much information as can be gleaned. By default,
319 /// the dependence test collects a set of runtime assumptions that cannot be
320 /// solved at compilation time. By default UnderRuntimeAssumptions is false
321 /// for a safe approximation of the dependence relation that does not
322 /// require runtime checks.
323 LLVM_ABI std::unique_ptr<Dependence>
325 bool UnderRuntimeAssumptions = false);
326
327 Function *getFunction() const { return F; }
328
329private:
330 const AnalysisOptions &Opts;
331 AAResults *AA;
332 ScalarEvolution *SE;
333 LoopInfo *LI;
334 Function *F;
335
336 /// Subscript - This private struct represents a pair of subscripts from
337 /// a pair of potentially multi-dimensional array references. We use a
338 /// vector of them to guide subscript partitioning.
339 struct Subscript {
340 const SCEV *Src;
341 const SCEV *Dst;
342 enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification;
343 SmallBitVector Loops;
344 };
345
346 struct CoefficientInfo {
347 const SCEV *SrcCoeff;
348 const SCEV *DstCoeff;
349 const SCEV *MaxIterIndex;
350 };
351
352 struct BoundInfo {
353 const SCEV *Upper[8];
354 const SCEV *Lower[8];
355 unsigned char Direction;
356 unsigned char DirSet;
357 };
358
359 /// Returns true if two loops have the Same iteration Space and Depth. To be
360 /// more specific, two loops have SameSD if they are in the same nesting
361 /// depth and have the same backedge count. SameSD stands for Same iteration
362 /// Space and Depth.
363 bool haveSameSD(const Loop *SrcLoop, const Loop *DstLoop) const;
364
365 /// establishNestingLevels - Examines the loop nesting of the Src and Dst
366 /// instructions and establishes their shared loops. Sets the variables
367 /// CommonLevels, SrcLevels, and MaxLevels.
368 /// The source and destination instructions needn't be contained in the same
369 /// loop. The routine establishNestingLevels finds the level of most deeply
370 /// nested loop that contains them both, CommonLevels. An instruction that's
371 /// not contained in a loop is at level = 0. MaxLevels is equal to the level
372 /// of the source plus the level of the destination, minus CommonLevels.
373 /// This lets us allocate vectors MaxLevels in length, with room for every
374 /// distinct loop referenced in both the source and destination subscripts.
375 /// The variable SrcLevels is the nesting depth of the source instruction.
376 /// It's used to help calculate distinct loops referenced by the destination.
377 /// Here's the map from loops to levels:
378 /// 0 - unused
379 /// 1 - outermost common loop
380 /// ... - other common loops
381 /// CommonLevels - innermost common loop
382 /// ... - loops containing Src but not Dst
383 /// SrcLevels - innermost loop containing Src but not Dst
384 /// ... - loops containing Dst but not Src
385 /// MaxLevels - innermost loop containing Dst but not Src
386 /// Consider the follow code fragment:
387 /// for (a = ...) {
388 /// for (b = ...) {
389 /// for (c = ...) {
390 /// for (d = ...) {
391 /// A[] = ...;
392 /// }
393 /// }
394 /// for (e = ...) {
395 /// for (f = ...) {
396 /// for (g = ...) {
397 /// ... = A[];
398 /// }
399 /// }
400 /// }
401 /// }
402 /// }
403 /// If we're looking at the possibility of a dependence between the store
404 /// to A (the Src) and the load from A (the Dst), we'll note that they
405 /// have 2 loops in common, so CommonLevels will equal 2 and the direction
406 /// vector for Result will have 2 entries. SrcLevels = 4 and MaxLevels = 7.
407 /// A map from loop names to level indices would look like
408 /// a - 1
409 /// b - 2 = CommonLevels
410 /// c - 3
411 /// d - 4 = SrcLevels
412 /// e - 5
413 /// f - 6
414 /// g - 7 = MaxLevels
415 /// SameSDLevels counts the number of levels after common levels that are
416 /// not common but have the same iteration space and depth. Internally this
417 /// is checked using haveSameSD. Assume that in this code fragment, levels c
418 /// and e have the same iteration space and depth, but levels d and f does
419 /// not. Then SameSDLevels is set to 1. In that case the level numbers for the
420 /// previous code look like
421 /// a - 1
422 /// b - 2
423 /// c,e - 3 = CommonLevels
424 /// d - 4 = SrcLevels
425 /// f - 5
426 /// g - 6 = MaxLevels
427 void establishNestingLevels(const Instruction *Src, const Instruction *Dst);
428
429 unsigned CommonLevels, SrcLevels, MaxLevels, SameSDLevels;
430
431 /// mapSrcLoop - Given one of the loops containing the source, return
432 /// its level index in our numbering scheme.
433 unsigned mapSrcLoop(const Loop *SrcLoop) const;
434
435 /// mapDstLoop - Given one of the loops containing the destination,
436 /// return its level index in our numbering scheme.
437 unsigned mapDstLoop(const Loop *DstLoop) const;
438
439 /// isLoopInvariant - Returns true if Expression is loop invariant
440 /// in LoopNest.
441 bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const;
442
443 /// collectCommonLoops - Finds the set of loops from the LoopNest that
444 /// have a level <= CommonLevels and are referred to by the SCEV Expression.
445 void collectCommonLoops(const SCEV *Expression, const Loop *LoopNest,
446 SmallBitVector &Loops) const;
447
448 /// checkSrcSubscript - Examines the SCEV Src, returning true iff it's
449 /// linear. Collect the set of loops mentioned by Src.
450 bool checkSrcSubscript(const SCEV *Src, const Loop *LoopNest,
451 SmallBitVector &Loops);
452
453 /// checkDstSubscript - Examines the SCEV Dst, returning true iff it's
454 /// linear. Collect the set of loops mentioned by Dst.
455 bool checkDstSubscript(const SCEV *Dst, const Loop *LoopNest,
456 SmallBitVector &Loops);
457
458 /// collectUpperBound - All subscripts are the same type (on my machine,
459 /// an i64). The loop bound may be a smaller type. collectUpperBound
460 /// find the bound, if available, and zero extends it to the Type T.
461 /// (I zero extend since the bound should always be >= 0.)
462 /// If no upper bound is available, return NULL.
463 const SCEV *collectUpperBound(const Loop *l, Type *T) const;
464
465 /// collectNonNegativeConstantUpperBound - Calls collectUpperBound(), then
466 /// attempts to cast it to APInt. If the cast fails, or the value is negative,
467 /// returns std::nullopt.
468 std::optional<APInt> collectNonNegativeConstantUpperBound(const Loop *L,
469 Type *T) const;
470
471 /// classifyPair - Examines the subscript pair (the Src and Dst SCEVs)
472 /// and classifies it as either ZIV, SIV, RDIV, MIV, or Nonlinear.
473 /// Collects the associated loops in a set.
474 Subscript::ClassificationKind
475 classifyPair(const SCEV *Src, const Loop *SrcLoopNest, const SCEV *Dst,
476 const Loop *DstLoopNest, SmallBitVector &Loops);
477
478 /// testZIV - Tests the ZIV subscript pair (Src and Dst) for dependence.
479 /// Returns true if any possible dependence is disproved.
480 /// If there might be a dependence, returns false.
481 /// If the dependence isn't proven to exist,
482 bool testZIV(const SCEV *Src, const SCEV *Dst, FullDependence &Result) const;
483
484 /// testSIV - Tests the SIV subscript pair (Src and Dst) for dependence.
485 /// Things of the form [c1 + a1*i] and [c2 + a2*j], where
486 /// i and j are induction variables, c1 and c2 are loop invariant,
487 /// and a1 and a2 are constant.
488 /// Returns true if any possible dependence is disproved.
489 /// If there might be a dependence, returns false.
490 /// Sets appropriate direction vector entry and, when possible,
491 /// the distance vector entry.
492 /// If the dependence isn't proven to exist,
493 bool testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
494 FullDependence &Result, bool UnderRuntimeAssumptions);
495
496 /// testRDIV - Tests the RDIV subscript pair (Src and Dst) for dependence.
497 /// Things of the form [c1 + a1*i] and [c2 + a2*j]
498 /// where i and j are induction variables, c1 and c2 are loop invariant,
499 /// and a1 and a2 are constant.
500 /// With minor algebra, this test can also be used for things like
501 /// [c1 + a1*i + a2*j][c2].
502 /// Returns true if any possible dependence is disproved.
503 /// If there might be a dependence, returns false.
504 bool testRDIV(const SCEV *Src, const SCEV *Dst, FullDependence &Result) const;
505
506 /// testMIV - Tests the MIV subscript pair (Src and Dst) for dependence.
507 /// Returns true if dependence disproved.
508 /// Can sometimes refine direction vectors.
509 bool testMIV(const SCEV *Src, const SCEV *Dst, const SmallBitVector &Loops,
510 FullDependence &Result) const;
511
512 /// strongSIVtest - Tests the strong SIV subscript pair (\p Src and \p Dst)
513 /// for dependence.
514 /// Things of the form [c1 + a*i] and [c2 + a*i],
515 /// where i is an induction variable, c1 and c2 are loop invariant,
516 /// and a is a constant
517 /// Returns true if any possible dependence is disproved.
518 /// If there might be a dependence, returns false.
519 /// Sets appropriate direction and distance.
520 bool strongSIVtest(const SCEVAddRecExpr *Src, const SCEVAddRecExpr *Dst,
521 unsigned Level, FullDependence &Result,
522 bool UnderRuntimeAssumptions);
523
524 /// weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
525 /// (Src and Dst) for dependence.
526 /// Things of the form [c1 + a*i] and [c2 - a*i],
527 /// where i is an induction variable, c1 and c2 are loop invariant,
528 /// and a is a constant.
529 /// Returns true if any possible dependence is disproved.
530 /// If there might be a dependence, returns false.
531 /// Sets appropriate direction entry.
532 bool weakCrossingSIVtest(const SCEVAddRecExpr *Src, const SCEVAddRecExpr *Dst,
533 unsigned Level, FullDependence &Result) const;
534
535 /// ExactSIVtest - Tests the SIV subscript pair
536 /// (Src and Dst) for dependence.
537 /// Things of the form [c1 + a1*i] and [c2 + a2*i],
538 /// where i is an induction variable, c1 and c2 are loop invariant,
539 /// and a1 and a2 are constant.
540 /// Returns true if any possible dependence is disproved.
541 /// If there might be a dependence, returns false.
542 /// Sets appropriate direction entry.
543 bool exactSIVtest(const SCEVAddRecExpr *Src, const SCEVAddRecExpr *Dst,
544 unsigned Level, FullDependence &Result) const;
545
546 /// weakZeroSIVtestImpl - Core implementation for weakZeroSrcSIVtest and
547 /// weakZeroDstSIVtest.
548 bool weakZeroSIVtestImpl(const SCEVAddRecExpr *AR, const SCEV *Const,
549 unsigned Level, FullDependence &Result) const;
550
551 /// weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
552 /// (Src and Dst) for dependence.
553 /// Things of the form [c1] and [c2 + a*i],
554 /// where i is an induction variable, c1 and c2 are loop invariant,
555 /// and a is a constant. See also weakZeroDstSIVtest.
556 /// Returns true if any possible dependence is disproved.
557 /// If there might be a dependence, returns false.
558 /// Sets appropriate direction entry.
559 bool weakZeroSrcSIVtest(const SCEV *SrcConst, const SCEVAddRecExpr *Dst,
560 unsigned Level, FullDependence &Result) const;
561
562 /// weakZeroDstSIVtest - Tests the weak-zero SIV subscript pair
563 /// (Src and Dst) for dependence.
564 /// Things of the form [c1 + a*i] and [c2],
565 /// where i is an induction variable, c1 and c2 are loop invariant,
566 /// and a is a constant. See also weakZeroSrcSIVtest.
567 /// Returns true if any possible dependence is disproved.
568 /// If there might be a dependence, returns false.
569 /// Sets appropriate direction entry.
570 bool weakZeroDstSIVtest(const SCEVAddRecExpr *Src, const SCEV *DstConst,
571 unsigned Level, FullDependence &Result) const;
572
573 /// exactRDIVtest - Tests the RDIV subscript pair for dependence.
574 /// Things of the form [c1 + a*i] and [c2 + b*j],
575 /// where i and j are induction variable, c1 and c2 are loop invariant,
576 /// and a and b are constants.
577 /// Returns true if any possible dependence is disproved.
578 /// Works in some cases that symbolicRDIVtest doesn't,
579 /// and vice versa.
580 bool exactRDIVtest(const SCEVAddRecExpr *Src, const SCEVAddRecExpr *Dst,
581 FullDependence &Result) const;
582
583 /// exactTestImpl - Core implementation shared by the Exact SIV test and the
584 /// Exact RDIV test. Returns true if any possible dependence is disproved. If
585 /// \p Level is provided, this function will also attempt to explore
586 /// directions and refine \p Result for the given level.
587 bool exactTestImpl(const SCEVAddRecExpr *Src, const SCEVAddRecExpr *Dst,
588 FullDependence &Result,
589 std::optional<unsigned> Level) const;
590
591 /// gcdMIVtest - Tests an MIV subscript pair for dependence.
592 /// Returns true if any possible dependence is disproved.
593 /// Can sometimes disprove the equal direction for 1 or more loops.
594 // Can handle some symbolics that even the SIV tests don't get,
595 /// so we use it as a backup for everything.
596 bool gcdMIVtest(const SCEV *Src, const SCEV *Dst,
597 FullDependence &Result) const;
598
599 /// banerjeeMIVtest - Tests an MIV subscript pair for dependence.
600 /// Returns true if any possible dependence is disproved.
601 /// Computes directions.
602 bool banerjeeMIVtest(const SCEV *Src, const SCEV *Dst,
603 const SmallBitVector &Loops,
604 FullDependence &Result) const;
605
606 /// collectCoeffInfo - Walks through the subscript, collecting each
607 /// coefficient and the associated maximum iteration index in the
608 /// widened analysis type. Returns the widened constant term.
609 const SCEV *collectCoeffInfo(const SCEV *Subscript, bool SrcFlag,
610 Type *WideType,
612
613 /// Given \p Expr of the form
614 ///
615 /// c_0*X_0*i_0 + c_1*X_1*i_1 + ...c_n*X_n*i_n + C
616 ///
617 /// compute
618 ///
619 /// RunningGCD = gcd(RunningGCD, c_0, c_1, ..., c_n)
620 ///
621 /// where c_0, c_1, ..., and c_n are the constant values. The result is stored
622 /// in \p RunningGCD. Also, the initial value of \p RunningGCD affects the
623 /// result. If we find a term like (c_k * X_k * i_k), where i_k is the
624 /// induction variable of \p CurLoop, c_k is stored in \p CurLoopCoeff and not
625 /// included in the GCD computation. Returns nullptr if we fail to find a
626 /// constant coefficient for some loop, e.g., when a term like (X+Y)*i is
627 /// present. Otherwise returns the remaining constant term C.
628 const SCEV *accumulateCoefficientsGCD(const SCEV *Expr, const Loop *CurLoop,
629 const SCEV *&CurLoopCoeff,
630 APInt &RunningGCD) const;
631
632 /// getLowerBound - Looks through all the bounds info and
633 /// computes the lower bound given the current direction settings
634 /// at each level.
635 const SCEV *getLowerBound(ArrayRef<BoundInfo> Bound) const;
636
637 /// getUpperBound - Looks through all the bounds info and
638 /// computes the upper bound given the current direction settings
639 /// at each level.
640 const SCEV *getUpperBound(ArrayRef<BoundInfo> Bound) const;
641
642 /// exploreDirections - Hierarchically expands the direction vector
643 /// search space, combining the directions of discovered dependences
644 /// in the DirSet field of Bound. Returns the number of distinct
645 /// dependences discovered. If the dependence is disproved,
646 /// it will return 0.
647 unsigned exploreDirections(unsigned Level, MutableArrayRef<BoundInfo> Bound,
648 const SmallBitVector &Loops, const SCEV *Delta,
649 const FullDependence &Result) const;
650
651 /// testBounds - Returns true when the current bounds may be feasible
652 /// or their feasibility is unknown.
653 bool testBounds(unsigned char DirKind, unsigned Level,
654 MutableArrayRef<BoundInfo> Bound, const SCEV *Delta) const;
655
656 /// findBoundsALL - Computes the upper and lower bounds for level K
657 /// using the * direction. Records them in Bound.
658 void findBoundsALL(ArrayRef<CoefficientInfo> CI,
659 MutableArrayRef<BoundInfo> Bound, unsigned K) const;
660
661 /// findBoundsLT - Computes the upper and lower bounds for level K
662 /// using the < direction. Records them in Bound.
663 void findBoundsLT(ArrayRef<CoefficientInfo> CI,
664 MutableArrayRef<BoundInfo> Bound, unsigned K) const;
665
666 /// findBoundsGT - Computes the upper and lower bounds for level K
667 /// using the > direction. Records them in Bound.
668 void findBoundsGT(ArrayRef<CoefficientInfo> CI,
669 MutableArrayRef<BoundInfo> Bound, unsigned K) const;
670
671 /// findBoundsEQ - Computes the upper and lower bounds for level K
672 /// using the = direction. Records them in Bound.
673 void findBoundsEQ(ArrayRef<CoefficientInfo> CI,
674 MutableArrayRef<BoundInfo> Bound, unsigned K) const;
675
676 /// Given a linear access function, tries to recover subscripts
677 /// for each dimension of the array element access.
678 bool tryDelinearize(Instruction *Src, Instruction *Dst,
679 SmallVectorImpl<Subscript> &Pair);
680
681 /// Tries to delinearize \p Src and \p Dst access functions for a fixed size
682 /// multi-dimensional array. Calls delinearizeFixedSizeArray() to delinearize
683 /// \p Src and \p Dst separately,
684 bool tryDelinearizeFixedSize(Instruction *Src, Instruction *Dst,
685 const SCEV *SrcAccessFn, const SCEV *DstAccessFn,
686 SmallVectorImpl<const SCEV *> &SrcSubscripts,
687 SmallVectorImpl<const SCEV *> &DstSubscripts);
688
689 /// Tries to delinearize access function for a multi-dimensional array with
690 /// symbolic runtime sizes.
691 /// Returns true upon success and false otherwise.
692 bool
693 tryDelinearizeParametricSize(Instruction *Src, Instruction *Dst,
694 const SCEV *SrcAccessFn, const SCEV *DstAccessFn,
695 SmallVectorImpl<const SCEV *> &SrcSubscripts,
696 SmallVectorImpl<const SCEV *> &DstSubscripts);
697
698 /// checkSubscript - Helper function for checkSrcSubscript and
699 /// checkDstSubscript to avoid duplicate code
700 bool checkSubscript(const SCEV *Expr, const Loop *LoopNest,
701 SmallBitVector &Loops, bool IsSrc);
702}; // class DependenceInfo
703
704/// AnalysisPass to compute dependence information in a function
705class DependenceAnalysis : public AnalysisInfoMixin<DependenceAnalysis> {
706public:
709
710private:
713}; // class DependenceAnalysis
714
715/// Printer pass to dump DA results.
717 : public RequiredPassInfoMixin<DependenceAnalysisPrinterPass> {
718 DependenceAnalysisPrinterPass(raw_ostream &OS, bool NormalizeResults = false)
719 : OS(OS), NormalizeResults(NormalizeResults) {}
720
722
723private:
724 raw_ostream &OS;
725 bool NormalizeResults;
726}; // class DependenceAnalysisPrinterPass
727
728/// Legacy pass manager pass to access dependence information
730public:
731 static char ID; // Class identification, replacement for typeinfo
733
734 bool runOnFunction(Function &F) override;
735 void releaseMemory() override;
736 void getAnalysisUsage(AnalysisUsage &) const override;
737 void print(raw_ostream &, const Module * = nullptr) const override;
738 DependenceInfo &getDI() const;
739
740private:
741 std::unique_ptr<DependenceInfo> info;
742}; // class DependenceAnalysisWrapperPass
743
744/// createDependenceAnalysisPass - This creates an instance of the
745/// DependenceAnalysis wrapper pass.
747
748} // namespace llvm
749
750#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_ABI
Definition Compiler.h:211
static bool runOnFunction(Function &F, bool PostInlining)
Hexagon Hardware Loops
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition MD5.cpp:54
#define T
static bool isInput(const ArrayRef< StringRef > &Prefixes, StringRef Arg)
Definition OptTable.cpp:143
FunctionAnalysisManager FAM
This file implements the SmallBitVector class.
Represent the analysis usage information of a pass.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
void getAnalysisUsage(AnalysisUsage &) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
AnalysisPass to compute dependence information in a function.
LLVM_ABI Result run(Function &F, FunctionAnalysisManager &FAM)
DependenceInfo - This class is the main dependence-analysis driver.
LLVM_ABI bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv)
Handle transitive invalidation when the cached analysis results go away.
Function * getFunction() const
LLVM_ABI DependenceInfo(Function *F, AAResults *AA, ScalarEvolution *SE, LoopInfo *LI)
LLVM_ABI std::unique_ptr< Dependence > depends(Instruction *Src, Instruction *Dst, bool UnderRuntimeAssumptions=false)
depends - Tests for a dependence between the Src and Dst instructions.
Instruction * getDst() const
getDst - Returns the destination instruction for this dependence.
Dependence & operator=(Dependence &&)=default
bool isOrdered() const
isOrdered - Returns true if dependence is Output, Flow, or Anti
void setNextSuccessor(const Dependence *succ)
setNextSuccessor - Sets the value of the NextSuccessor field.
friend class DependenceInfo
Dependence(Instruction *Source, Instruction *Destination, const SCEVUnionPredicate &A)
Dependence(Dependence &&)=default
bool isUnordered() const
isUnordered - Returns true if dependence is Input
SCEVUnionPredicate getRuntimeAssumptions() const
getRuntimeAssumptions - Returns the runtime assumptions under which this Dependence relation is valid...
virtual bool isConfused() const
isConfused - Returns true if this dependence is confused (the compiler understands nothing and makes ...
virtual unsigned getSameSDLevels() const
getSameSDLevels - Returns the number of separate SameSD loops surrounding the source and destination ...
virtual const SCEV * getDistance(unsigned Level, bool SameSD=false) const
getDistance - Returns the distance (or NULL) associated with a particular common or SameSD level.
virtual void negate(ScalarEvolution &SE)
Negate the dependence by swapping the source and destination, and reversing the direction and distanc...
virtual unsigned getLevels() const
getLevels - Returns the number of common loops surrounding the source and destination of the dependen...
const Dependence * getNextPredecessor() const
getNextPredecessor - Returns the value of the NextPredecessor field.
virtual unsigned getDirection(unsigned Level, bool SameSD=false) const
getDirection - Returns the direction associated with a particular common or SameSD level.
bool isFlow() const
isFlow - Returns true if this is a flow (aka true) dependence.
virtual ~Dependence()=default
virtual bool normalize(ScalarEvolution *SE)
If the direction vector is negative, normalize the direction vector to make it non-negative.
bool isAnti() const
isAnti - Returns true if this is an anti dependence.
const Dependence * getNextSuccessor() const
getNextSuccessor - Returns the value of the NextSuccessor field.
virtual bool isDirectionNegative() const
Check if the direction vector is negative.
Instruction * getSrc() const
getSrc - Returns the source instruction for this dependence.
virtual bool isLoopIndependent() const
isLoopIndependent - Returns true if this is a loop-independent dependence.
bool isOutput() const
isOutput - Returns true if this is an output dependence.
void setNextPredecessor(const Dependence *pred)
setNextPredecessor - Sets the value of the NextPredecessor field.
virtual bool inSameSDLoops(unsigned Level) const
inSameSDLoops - Returns true if this level is an SameSD level, i.e., performed across two separate lo...
FullDependence(Instruction *Source, Instruction *Destination, const SCEVUnionPredicate &Assumes, bool PossiblyLoopIndependent, unsigned Levels)
bool isConfused() const override
isConfused - Returns true if this dependence is confused (the compiler understands nothing and makes ...
DVEntry getDVEntry(unsigned Level, bool IsSameSD) const
getDVEntry - Returns the DV entry associated with a regular or a SameSD level.
bool isLoopIndependent() const override
isLoopIndependent - Returns true if this is a loop-independent dependence.
unsigned getSameSDLevels() const override
getSameSDLevels - Returns the number of separate SameSD loops surrounding the source and destination ...
unsigned getLevels() const override
getLevels - Returns the number of common loops surrounding the source and destination of the dependen...
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
FunctionPass(char &pid)
Definition Pass.h:314
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
This class represents a constant integer value.
This class represents a composition of other SCEV predicates, and is the class that most clients will...
This class represents an analyzed expression in the program.
The main scalar evolution driver.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Abstract Attribute helper functions.
Definition Attributor.h:164
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
ArrayRef(const T &OneElt) -> ArrayRef< T >
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI FunctionPass * createDependenceAnalysisWrapperPass()
createDependenceAnalysisPass - This creates an instance of the DependenceAnalysis wrapper pass.
A CRTP mix-in that provides informational APIs needed for analysis passes.
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29
DependenceAnalysisPrinterPass(raw_ostream &OS, bool NormalizeResults=false)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
Dependence::DVEntry - Each level in the distance/direction vector has a direction (or perhaps a union...
A CRTP mix-in for passes that should not be skipped.