FLANG
ArraySectionAnalyzer.h
1//===- ArraySectionAnalyzer.h - Analyze array sections --------------------===//
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#ifndef FORTRAN_OPTIMIZER_ANALYSIS_ARRAYSECTIONANALYZER_H
10#define FORTRAN_OPTIMIZER_ANALYSIS_ARRAYSECTIONANALYZER_H
11
12#include "mlir/IR/Operation.h"
13#include "mlir/IR/Value.h"
14
15namespace mlir {
16class Operation;
17class Value;
18} // namespace mlir
19
20namespace hlfir {
21class ElementalOpInterface;
22class DesignateOp;
23} // namespace hlfir
24
25namespace fir {
27public:
28 // The result of the analyzis is one of the values below.
29 enum class SlicesOverlapKind {
30 // Slices overlap is unknown.
31 Unknown,
32 // Slices are definitely identical.
33 DefinitelyIdentical,
34 // Slices are definitely disjoint.
35 DefinitelyDisjoint,
36 // Slices may be either disjoint or identical,
37 // i.e. there is definitely no partial overlap.
38 EitherIdenticalOrDisjoint
39 };
40
41 // Analyzes two hlfir.designate results and returns the overlap kind.
42 // The callers may use this method when the alias analysis reports
43 // an alias of some kind, so that we can run Fortran specific analysis
44 // on the array slices to see if they are identical or disjoint.
45 // Note that the alias analysis are not able to give such an answer
46 // about the references.
47 static SlicesOverlapKind analyze(mlir::Value ref1, mlir::Value ref2);
48
49 static bool isDesignatingArrayInOrder(hlfir::DesignateOp designate,
50 hlfir::ElementalOpInterface elemental);
51
52private:
53 struct SectionDesc {
54 // An array section is described by <lb, ub, stride> tuple.
55 // If the designator's subscript is not a triple, then
56 // the section descriptor is constructed as <lb, nullptr, nullptr>.
57 mlir::Value lb, ub, stride;
58
59 SectionDesc(mlir::Value lb, mlir::Value ub, mlir::Value stride);
60
61 // Normalize the section descriptor:
62 // 1. If UB is nullptr, then it is set to LB.
63 // 2. If LB==UB, then stride does not matter,
64 // so it is reset to nullptr.
65 // 3. If STRIDE==1, then it is reset to nullptr.
66 void normalize();
67
68 bool operator==(const SectionDesc &other) const;
69 };
70
71 // Given an operand_iterator over the indices operands,
72 // read the subscript values and return them as SectionDesc
73 // updating the iterator. If isTriplet is true,
74 // the subscript is a triplet, and the result is <lb, ub, stride>.
75 // Otherwise, the subscript is a scalar index, and the result
76 // is <index, nullptr, nullptr>.
77 static SectionDesc readSectionDesc(mlir::Operation::operand_iterator &it,
78 bool isTriplet);
79
80 // Return the ordered lower and upper bounds of the section.
81 // If stride is known to be non-negative, then the ordered
82 // bounds match the <lb, ub> of the descriptor.
83 // If stride is known to be negative, then the ordered
84 // bounds are <ub, lb> of the descriptor.
85 // If stride is unknown, we cannot deduce any order,
86 // so the result is <nullptr, nullptr>
87 static std::pair<mlir::Value, mlir::Value>
88 getOrderedBounds(const SectionDesc &desc);
89
90 // Given two array sections <lb1, ub1, stride1> and
91 // <lb2, ub2, stride2>, return true only if the sections
92 // are known to be disjoint.
93 //
94 // For example, for any positive constant C:
95 // X:Y does not overlap with (Y+C):Z
96 // X:Y does not overlap with Z:(X-C)
97 static bool areDisjointSections(const SectionDesc &desc1,
98 const SectionDesc &desc2);
99
100 // Given two array sections <lb1, ub1, stride1> and
101 // <lb2, ub2, stride2>, return true only if the sections
102 // are known to be identical.
103 //
104 // For example:
105 // <x, x, stride>
106 // <x, nullptr, nullptr>
107 //
108 // These sections are identical, from the point of which array
109 // elements are being addresses, even though the shape
110 // of the array slices might be different.
111 static bool areIdenticalSections(const SectionDesc &desc1,
112 const SectionDesc &desc2);
113
114 // Return true, if v1 is known to be less than v2.
115 static bool isLess(mlir::Value v1, mlir::Value v2);
116};
117} // namespace fir
118
119#endif // FORTRAN_OPTIMIZER_ANALYSIS_ARRAYSECTIONANALYZER_H
Definition ArraySectionAnalyzer.h:26
Definition AbstractConverter.h:37
Definition AbstractConverter.h:32