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).
38void collectParametricTerms(ScalarEvolution &SE, const SCEV *Expr,
40
41/// Return in Subscripts the access functions for each dimension in Sizes
42/// (third step of delinearization).
43void computeAccessFunctions(ScalarEvolution &SE, const SCEV *Expr,
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].
110void delinearize(ScalarEvolution &SE, const SCEV *Expr,
112 SmallVectorImpl<const SCEV *> &Sizes, const SCEV *ElementSize);
113
114/// Compute the dimensions of fixed size array from \Expr and save the results
115/// in \p Sizes.
118 const SCEV *ElementSize);
119
120/// Split this SCEVAddRecExpr into two vectors of SCEVs representing the
121/// subscripts and sizes of an access to a fixed size array. This is a special
122/// case of delinearization for fixed size arrays.
123///
124/// The delinearization is a 2 step process: the first step estimates the sizes
125/// of each dimension of the array. The second step computes the access
126/// functions for the delinearized array:
127///
128/// 1. Compute the array size
129/// 2. Compute the access function: same as normal delinearization
130///
131/// Different from the normal delinearization, this function assumes that NO
132/// terms exist in the \p Expr. In other words, it assumes that the all step
133/// values are constant.
134///
135/// This function is intended to replace getIndexExpressionsFromGEP. They rely
136/// on the GEP source element type so that will be removed in the future.
140 const SCEV *ElementSize);
141
142/// Check that each subscript in \p Subscripts is within the corresponding size
143/// in \p Sizes. For the outermost dimension, the subscript being negative is
144/// allowed.
147 ArrayRef<const SCEV *> Subscripts);
148
149/// Gathers the individual index expressions from a GEP instruction.
150///
151/// This function optimistically assumes the GEP references into a fixed size
152/// array. If this is actually true, this function returns a list of array
153/// subscript expressions in \p Subscripts and a list of SCEV expressions
154/// describing the size of the individual array dimensions in \p Sizes. Both
155/// lists have either equal length or the size list is one element shorter in
156/// case there is no known size available for the outermost array dimension.
157/// Returns true if successful and false otherwise.
159 const GetElementPtrInst *GEP,
162
164 : public PassInfoMixin<DelinearizationPrinterPass> {
167 static bool isRequired() { return true; }
168
169private:
170 raw_ostream &OS;
171};
172} // namespace llvm
173
174#endif // LLVM_ANALYSIS_DELINEARIZATION_H
Hexagon Common GEP
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition MD5.cpp:54
ArrayRef - 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.
Definition Types.h:26
void collectParametricTerms(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Terms)
Collect parametric terms occurring in step expressions (first step of delinearization).
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...
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.
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)...
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...
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...
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.
bool getIndexExpressionsFromGEP(ScalarEvolution &SE, const GetElementPtrInst *GEP, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< const SCEV * > &Sizes)
Gathers the individual index expressions from a GEP instruction.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition PassManager.h:70