LLVM 23.0.0git
Delinearization.h
Go to the documentation of this file.
1//===---- Delinearization.h - MultiDimensional Index Delinearization ------===//
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// This implements an analysis pass that tries to delinearize all GEP
10// instructions in all loops using the SCEV analysis functionality.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ANALYSIS_DELINEARIZATION_H
15#define LLVM_ANALYSIS_DELINEARIZATION_H
16
17#include "llvm/IR/PassManager.h"
18#include "llvm/IR/Value.h"
19
20namespace llvm {
21class raw_ostream;
22template <typename T> class SmallVectorImpl;
24class Instruction;
25class ScalarEvolution;
26class SCEV;
27
28/// Compute the array dimensions Sizes from the set of Terms extracted from
29/// the memory access function of this SCEVAddRecExpr (second step of
30/// delinearization).
34 const SCEV *ElementSize);
35
36/// Collect parametric terms occurring in step expressions (first step of
37/// delinearization).
40
41/// Return in Subscripts the access functions for each dimension in Sizes
42/// (third step of delinearization).
46/// Split this SCEVAddRecExpr into two vectors of SCEVs representing the
47/// subscripts and sizes of an array access.
48///
49/// The delinearization is a 3 step process: the first two steps compute the
50/// sizes of each subscript and the third step computes the access functions
51/// for the delinearized array:
52///
53/// 1. Find the terms in the step functions
54/// 2. Compute the array size
55/// 3. Compute the access function: divide the SCEV by the array size
56/// starting with the innermost dimensions found in step 2. The Quotient
57/// is the SCEV to be divided in the next step of the recursion. The
58/// Remainder is the subscript of the innermost dimension. Loop over all
59/// array dimensions computed in step 2.
60///
61/// To compute a uniform array size for several memory accesses to the same
62/// object, one can collect in step 1 all the step terms for all the memory
63/// accesses, and compute in step 2 a unique array shape. This guarantees
64/// that the array shape will be the same across all memory accesses.
65///
66/// FIXME: We could derive the result of steps 1 and 2 from a description of
67/// the array shape given in metadata.
68///
69/// Example:
70///
71/// A[][n][m]
72///
73/// for i
74/// for j
75/// for k
76/// A[j+k][2i][5i] =
77///
78/// The initial SCEV:
79///
80/// A[{{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k]
81///
82/// 1. Find the different terms in the step functions:
83/// -> [2*m, 5, n*m, n*m]
84///
85/// 2. Compute the array size: sort and unique them
86/// -> [n*m, 2*m, 5]
87/// find the GCD of all the terms = 1
88/// divide by the GCD and erase constant terms
89/// -> [n*m, 2*m]
90/// GCD = m
91/// divide by GCD -> [n, 2]
92/// remove constant terms
93/// -> [n]
94/// size of the array is A[unknown][n][m]
95///
96/// 3. Compute the access function
97/// a. Divide {{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k by the innermost size m
98/// Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k
99/// Remainder: {{{0,+,5}_i, +, 0}_j, +, 0}_k
100/// The remainder is the subscript of the innermost array dimension: [5i].
101///
102/// b. Divide Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k by next outer size n
103/// Quotient: {{{0,+,0}_i, +, 1}_j, +, 1}_k
104/// Remainder: {{{0,+,2}_i, +, 0}_j, +, 0}_k
105/// The Remainder is the subscript of the next array dimension: [2i].
106///
107/// The subscript of the outermost dimension is the Quotient: [j+k].
108///
109/// Overall, we have: A[][n][m], and the access function: A[j+k][2i][5i].
110LLVM_ABI void delinearize(ScalarEvolution &SE, const SCEV *Expr,
113 const SCEV *ElementSize);
114
115/// Compute the dimensions of fixed size array from \Expr and save the results
116/// in \p Sizes.
118 const SCEV *Expr,
120 const SCEV *ElementSize);
121
122/// Split this SCEVAddRecExpr into two vectors of SCEVs representing the
123/// subscripts and sizes of an access to a fixed size array. This is a special
124/// case of delinearization for fixed size arrays.
125///
126/// The delinearization is a 2 step process: the first step estimates the sizes
127/// of each dimension of the array. The second step computes the access
128/// functions for the delinearized array:
129///
130/// 1. Compute the array size
131/// 2. Compute the access function: same as normal delinearization
132///
133/// Different from the normal delinearization, this function assumes that NO
134/// terms exist in the \p Expr. In other words, it assumes that the all step
135/// values are constant.
136///
137/// This function is intended to replace getIndexExpressionsFromGEP. They rely
138/// on the GEP source element type so that will be removed in the future.
139LLVM_ABI bool
143 const SCEV *ElementSize);
144
145/// Check that each subscript in \p Subscripts is within the corresponding size
146/// in \p Sizes. For the outermost dimension, the subscript being negative is
147/// allowed.
150 ArrayRef<const SCEV *> Subscripts);
151
152/// Gathers the individual index expressions from a GEP instruction.
153///
154/// This function optimistically assumes the GEP references into a fixed size
155/// array. If this is actually true, this function returns a list of array
156/// subscript expressions in \p Subscripts and a list of SCEV expressions
157/// describing the size of the individual array dimensions in \p Sizes. Both
158/// lists have either equal length or the size list is one element shorter in
159/// case there is no known size available for the outermost array dimension.
160/// Returns true if successful and false otherwise.
161LLVM_ABI bool
165
167 : public RequiredPassInfoMixin<DelinearizationPrinterPass> {
170
171private:
172 raw_ostream &OS;
173};
174} // namespace llvm
175
176#endif // LLVM_ANALYSIS_DELINEARIZATION_H
#define LLVM_ABI
Definition Compiler.h:213
Hexagon Common GEP
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition MD5.cpp:54
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
This class represents an analyzed expression in the program.
The main scalar evolution driver.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void collectParametricTerms(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Terms)
Collect parametric terms occurring in step expressions (first step of delinearization).
LLVM_ABI 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...
LLVM_ABI bool validateDelinearizationResult(ScalarEvolution &SE, ArrayRef< const SCEV * > Sizes, ArrayRef< const SCEV * > Subscripts)
Check that each subscript in Subscripts is within the corresponding size in Sizes.
LLVM_ABI 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)...
LLVM_ABI 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...
LLVM_ABI 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...
LLVM_ABI 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.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool getIndexExpressionsFromGEP(ScalarEvolution &SE, const GetElementPtrInst *GEP, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< const SCEV * > &Sizes)
Gathers the individual index expressions from a GEP instruction.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI DelinearizationPrinterPass(raw_ostream &OS)
A CRTP mix-in for passes that should not be skipped.