|
|
|||
File indexing completed on 2026-05-10 08:43:12
0001 //===---- Delinearization.h - MultiDimensional Index Delinearization ------===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This implements an analysis pass that tries to delinearize all GEP 0010 // instructions in all loops using the SCEV analysis functionality. This pass is 0011 // only used for testing purposes: if your pass needs delinearization, please 0012 // use the on-demand SCEVAddRecExpr::delinearize() function. 0013 // 0014 //===----------------------------------------------------------------------===// 0015 0016 #ifndef LLVM_ANALYSIS_DELINEARIZATION_H 0017 #define LLVM_ANALYSIS_DELINEARIZATION_H 0018 0019 #include "llvm/IR/PassManager.h" 0020 0021 namespace llvm { 0022 class raw_ostream; 0023 template <typename T> class SmallVectorImpl; 0024 class GetElementPtrInst; 0025 class Instruction; 0026 class ScalarEvolution; 0027 class SCEV; 0028 0029 /// Compute the array dimensions Sizes from the set of Terms extracted from 0030 /// the memory access function of this SCEVAddRecExpr (second step of 0031 /// delinearization). 0032 void findArrayDimensions(ScalarEvolution &SE, 0033 SmallVectorImpl<const SCEV *> &Terms, 0034 SmallVectorImpl<const SCEV *> &Sizes, 0035 const SCEV *ElementSize); 0036 0037 /// Collect parametric terms occurring in step expressions (first step of 0038 /// delinearization). 0039 void collectParametricTerms(ScalarEvolution &SE, const SCEV *Expr, 0040 SmallVectorImpl<const SCEV *> &Terms); 0041 0042 /// Return in Subscripts the access functions for each dimension in Sizes 0043 /// (third step of delinearization). 0044 void computeAccessFunctions(ScalarEvolution &SE, const SCEV *Expr, 0045 SmallVectorImpl<const SCEV *> &Subscripts, 0046 SmallVectorImpl<const SCEV *> &Sizes); 0047 /// Split this SCEVAddRecExpr into two vectors of SCEVs representing the 0048 /// subscripts and sizes of an array access. 0049 /// 0050 /// The delinearization is a 3 step process: the first two steps compute the 0051 /// sizes of each subscript and the third step computes the access functions 0052 /// for the delinearized array: 0053 /// 0054 /// 1. Find the terms in the step functions 0055 /// 2. Compute the array size 0056 /// 3. Compute the access function: divide the SCEV by the array size 0057 /// starting with the innermost dimensions found in step 2. The Quotient 0058 /// is the SCEV to be divided in the next step of the recursion. The 0059 /// Remainder is the subscript of the innermost dimension. Loop over all 0060 /// array dimensions computed in step 2. 0061 /// 0062 /// To compute a uniform array size for several memory accesses to the same 0063 /// object, one can collect in step 1 all the step terms for all the memory 0064 /// accesses, and compute in step 2 a unique array shape. This guarantees 0065 /// that the array shape will be the same across all memory accesses. 0066 /// 0067 /// FIXME: We could derive the result of steps 1 and 2 from a description of 0068 /// the array shape given in metadata. 0069 /// 0070 /// Example: 0071 /// 0072 /// A[][n][m] 0073 /// 0074 /// for i 0075 /// for j 0076 /// for k 0077 /// A[j+k][2i][5i] = 0078 /// 0079 /// The initial SCEV: 0080 /// 0081 /// A[{{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k] 0082 /// 0083 /// 1. Find the different terms in the step functions: 0084 /// -> [2*m, 5, n*m, n*m] 0085 /// 0086 /// 2. Compute the array size: sort and unique them 0087 /// -> [n*m, 2*m, 5] 0088 /// find the GCD of all the terms = 1 0089 /// divide by the GCD and erase constant terms 0090 /// -> [n*m, 2*m] 0091 /// GCD = m 0092 /// divide by GCD -> [n, 2] 0093 /// remove constant terms 0094 /// -> [n] 0095 /// size of the array is A[unknown][n][m] 0096 /// 0097 /// 3. Compute the access function 0098 /// a. Divide {{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k by the innermost size m 0099 /// Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k 0100 /// Remainder: {{{0,+,5}_i, +, 0}_j, +, 0}_k 0101 /// The remainder is the subscript of the innermost array dimension: [5i]. 0102 /// 0103 /// b. Divide Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k by next outer size n 0104 /// Quotient: {{{0,+,0}_i, +, 1}_j, +, 1}_k 0105 /// Remainder: {{{0,+,2}_i, +, 0}_j, +, 0}_k 0106 /// The Remainder is the subscript of the next array dimension: [2i]. 0107 /// 0108 /// The subscript of the outermost dimension is the Quotient: [j+k]. 0109 /// 0110 /// Overall, we have: A[][n][m], and the access function: A[j+k][2i][5i]. 0111 void delinearize(ScalarEvolution &SE, const SCEV *Expr, 0112 SmallVectorImpl<const SCEV *> &Subscripts, 0113 SmallVectorImpl<const SCEV *> &Sizes, const SCEV *ElementSize); 0114 0115 /// Gathers the individual index expressions from a GEP instruction. 0116 /// 0117 /// This function optimistically assumes the GEP references into a fixed size 0118 /// array. If this is actually true, this function returns a list of array 0119 /// subscript expressions in \p Subscripts and a list of integers describing 0120 /// the size of the individual array dimensions in \p Sizes. Both lists have 0121 /// either equal length or the size list is one element shorter in case there 0122 /// is no known size available for the outermost array dimension. Returns true 0123 /// if successful and false otherwise. 0124 bool getIndexExpressionsFromGEP(ScalarEvolution &SE, 0125 const GetElementPtrInst *GEP, 0126 SmallVectorImpl<const SCEV *> &Subscripts, 0127 SmallVectorImpl<int> &Sizes); 0128 0129 /// Implementation of fixed size array delinearization. Try to delinearize 0130 /// access function for a fixed size multi-dimensional array, by deriving 0131 /// subscripts from GEP instructions. Returns true upon success and false 0132 /// otherwise. \p Inst is the load/store instruction whose pointer operand is 0133 /// the one we want to delinearize. \p AccessFn is its corresponding SCEV 0134 /// expression w.r.t. the surrounding loop. 0135 bool tryDelinearizeFixedSizeImpl(ScalarEvolution *SE, Instruction *Inst, 0136 const SCEV *AccessFn, 0137 SmallVectorImpl<const SCEV *> &Subscripts, 0138 SmallVectorImpl<int> &Sizes); 0139 0140 struct DelinearizationPrinterPass 0141 : public PassInfoMixin<DelinearizationPrinterPass> { 0142 explicit DelinearizationPrinterPass(raw_ostream &OS); 0143 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 0144 static bool isRequired() { return true; } 0145 0146 private: 0147 raw_ostream &OS; 0148 }; 0149 } // namespace llvm 0150 0151 #endif // LLVM_ANALYSIS_DELINEARIZATION_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|