LLVM 22.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. This pass is
11// only used for testing purposes: if your pass needs delinearization, please
12// use the on-demand SCEVAddRecExpr::delinearize() function.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_ANALYSIS_DELINEARIZATION_H
17#define LLVM_ANALYSIS_DELINEARIZATION_H
18
19#include "llvm/IR/PassManager.h"
20#include "llvm/IR/Value.h"
21
22namespace llvm {
23class raw_ostream;
24template <typename T> class SmallVectorImpl;
26class Instruction;
27class ScalarEvolution;
28class SCEV;
29
30/// Compute the array dimensions Sizes from the set of Terms extracted from
31/// the memory access function of this SCEVAddRecExpr (second step of
32/// delinearization).
36 const SCEV *ElementSize);
37
38/// Collect parametric terms occurring in step expressions (first step of
39/// delinearization).
40void collectParametricTerms(ScalarEvolution &SE, const SCEV *Expr,
42
43/// Return in Subscripts the access functions for each dimension in Sizes
44/// (third step of delinearization).
45void computeAccessFunctions(ScalarEvolution &SE, const SCEV *Expr,
48/// Split this SCEVAddRecExpr into two vectors of SCEVs representing the
49/// subscripts and sizes of an array access.
50///
51/// The delinearization is a 3 step process: the first two steps compute the
52/// sizes of each subscript and the third step computes the access functions
53/// for the delinearized array:
54///
55/// 1. Find the terms in the step functions
56/// 2. Compute the array size
57/// 3. Compute the access function: divide the SCEV by the array size
58/// starting with the innermost dimensions found in step 2. The Quotient
59/// is the SCEV to be divided in the next step of the recursion. The
60/// Remainder is the subscript of the innermost dimension. Loop over all
61/// array dimensions computed in step 2.
62///
63/// To compute a uniform array size for several memory accesses to the same
64/// object, one can collect in step 1 all the step terms for all the memory
65/// accesses, and compute in step 2 a unique array shape. This guarantees
66/// that the array shape will be the same across all memory accesses.
67///
68/// FIXME: We could derive the result of steps 1 and 2 from a description of
69/// the array shape given in metadata.
70///
71/// Example:
72///
73/// A[][n][m]
74///
75/// for i
76/// for j
77/// for k
78/// A[j+k][2i][5i] =
79///
80/// The initial SCEV:
81///
82/// A[{{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k]
83///
84/// 1. Find the different terms in the step functions:
85/// -> [2*m, 5, n*m, n*m]
86///
87/// 2. Compute the array size: sort and unique them
88/// -> [n*m, 2*m, 5]
89/// find the GCD of all the terms = 1
90/// divide by the GCD and erase constant terms
91/// -> [n*m, 2*m]
92/// GCD = m
93/// divide by GCD -> [n, 2]
94/// remove constant terms
95/// -> [n]
96/// size of the array is A[unknown][n][m]
97///
98/// 3. Compute the access function
99/// a. Divide {{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k by the innermost size m
100/// Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k
101/// Remainder: {{{0,+,5}_i, +, 0}_j, +, 0}_k
102/// The remainder is the subscript of the innermost array dimension: [5i].
103///
104/// b. Divide Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k by next outer size n
105/// Quotient: {{{0,+,0}_i, +, 1}_j, +, 1}_k
106/// Remainder: {{{0,+,2}_i, +, 0}_j, +, 0}_k
107/// The Remainder is the subscript of the next array dimension: [2i].
108///
109/// The subscript of the outermost dimension is the Quotient: [j+k].
110///
111/// Overall, we have: A[][n][m], and the access function: A[j+k][2i][5i].
112void delinearize(ScalarEvolution &SE, const SCEV *Expr,
114 SmallVectorImpl<const SCEV *> &Sizes, const SCEV *ElementSize);
115
116/// Compute the dimensions of fixed size array from \Expr and save the results
117/// in \p Sizes.
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.
142 const SCEV *ElementSize);
143
144/// Check that each subscript in \p Subscripts is within the corresponding size
145/// in \p Sizes. For the outermost dimension, the subscript being negative is
146/// allowed. If \p Ptr is not nullptr, it may be used to get information from
147/// the IR pointer value, which may help in the validation.
150 ArrayRef<const SCEV *> Subscripts,
151 const Value *Ptr = nullptr);
152
153/// Gathers the individual index expressions from a GEP instruction.
154///
155/// This function optimistically assumes the GEP references into a fixed size
156/// array. If this is actually true, this function returns a list of array
157/// subscript expressions in \p Subscripts and a list of integers describing
158/// the size of the individual array dimensions in \p Sizes. Both lists have
159/// either equal length or the size list is one element shorter in case there
160/// is no known size available for the outermost array dimension. Returns true
161/// if successful and false otherwise.
163 const GetElementPtrInst *GEP,
165 SmallVectorImpl<int> &Sizes);
166
168 : public PassInfoMixin<DelinearizationPrinterPass> {
171 static bool isRequired() { return true; }
172
173private:
174 raw_ostream &OS;
175};
176} // namespace llvm
177
178#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...
LLVM Value Representation.
Definition Value.h:75
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.
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...
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...
bool getIndexExpressionsFromGEP(ScalarEvolution &SE, const GetElementPtrInst *GEP, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< int > &Sizes)
Gathers the individual index expressions from a GEP instruction.
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 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.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition PassManager.h:69