FLANG

BoxValue.h
1 //===-- Lower/Support/BoxValue.h -- internal box values ---------*- C++ -*-===//
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 LOWER_SUPPORT_BOXVALUE_H
10 #define LOWER_SUPPORT_BOXVALUE_H
11
12 #include "mlir/IR/Value.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/Support/Compiler.h"
15 #include "llvm/Support/raw_ostream.h"
16 #include <utility>
17 #include <variant>
18
19 namespace fir {
20 class CharBoxValue;
21 class ArrayBoxValue;
22 class CharArrayBoxValue;
23 class BoxValue;
24 class ProcBoxValue;
25
26 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const CharBoxValue &);
27 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ArrayBoxValue &);
28 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const CharArrayBoxValue &);
29 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const BoxValue &);
30 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ProcBoxValue &);
31
32 //===----------------------------------------------------------------------===//
33 //
34 // Boxed values
35 //
36 // Define a set of containers used internally by the lowering bridge to keep
37 // track of extended values associated with a Fortran subexpression. These
38 // associations are maintained during the construction of FIR.
39 //
40 //===----------------------------------------------------------------------===//
41
44 using UnboxedValue = mlir::Value;
45
47 class AbstractBox {
48 public:
49 AbstractBox() = delete;
50 AbstractBox(mlir::Value addr) : addr{addr} {}
51 mlir::Value getAddr() const { return addr; }
52
53 protected:
54 mlir::Value addr;
55 };
56
59 class CharBoxValue : public AbstractBox {
60 public:
61 CharBoxValue(mlir::Value addr, mlir::Value len)
62 : AbstractBox{addr}, len{len} {}
63
64 CharBoxValue clone(mlir::Value newBase) const { return {newBase, len}; }
65
66 mlir::Value getLen() const { return len; }
67 mlir::Value getBuffer() const { return getAddr(); }
68
69 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
70 const CharBoxValue &);
71 LLVM_DUMP_METHOD void dump() const { llvm::errs() << *this; }
72
73 protected:
74 mlir::Value len;
75 };
76
81 class AbstractArrayBox {
82 public:
83 AbstractArrayBox() = default;
84 AbstractArrayBox(llvm::ArrayRef<mlir::Value> extents,
85 llvm::ArrayRef<mlir::Value> lbounds)
86 : extents{extents.begin(), extents.end()}, lbounds{lbounds.begin(),
87 lbounds.end()} {}
88
89 // Every array has extents that describe its shape.
90 const llvm::SmallVectorImpl<mlir::Value> &getExtents() const {
91 return extents;
92 }
93
94 // An array expression may have user-defined lower bound values.
95 // If this vector is empty, the default in all dimensions in `1`.
96 const llvm::SmallVectorImpl<mlir::Value> &getLBounds() const {
97 return lbounds;
98 }
99
100 bool lboundsAllOne() const { return lbounds.empty(); }
101
102 protected:
103 llvm::SmallVector<mlir::Value, 4> extents;
104 llvm::SmallVector<mlir::Value, 4> lbounds;
105 };
106
109 class ArrayBoxValue : public AbstractBox, public AbstractArrayBox {
110 public:
111 ArrayBoxValue(mlir::Value addr, llvm::ArrayRef<mlir::Value> extents,
112 llvm::ArrayRef<mlir::Value> lbounds = {})
113 : AbstractBox{addr}, AbstractArrayBox{extents, lbounds} {}
114
115 ArrayBoxValue clone(mlir::Value newBase) const {
116 return {newBase, extents, lbounds};
117 }
118
119 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
120 const ArrayBoxValue &);
121 LLVM_DUMP_METHOD void dump() const { operator<<(llvm::errs(), *this); }
122 };
123
125 class CharArrayBoxValue : public CharBoxValue, public AbstractArrayBox {
126 public:
127 CharArrayBoxValue(mlir::Value addr, mlir::Value len,
128 llvm::ArrayRef<mlir::Value> extents,
129 llvm::ArrayRef<mlir::Value> lbounds = {})
130 : CharBoxValue{addr, len}, AbstractArrayBox{extents, lbounds} {}
131
132 CharArrayBoxValue clone(mlir::Value newBase) const {
133 return {newBase, len, extents, lbounds};
134 }
135
136 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
137 const CharArrayBoxValue &);
138 LLVM_DUMP_METHOD void dump() const { operator<<(llvm::errs(), *this); }
139 };
140
143 class ProcBoxValue : public AbstractBox {
144 public:
145 ProcBoxValue(mlir::Value addr, mlir::Value context)
146 : AbstractBox{addr}, hostContext{context} {}
147
148 ProcBoxValue clone(mlir::Value newBase) const {
149 return {newBase, hostContext};
150 }
151
152 mlir::Value getHostContext() const { return hostContext; }
153
154 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
155 const ProcBoxValue &);
156 LLVM_DUMP_METHOD void dump() const { operator<<(llvm::errs(), *this); }
157
158 protected:
159 mlir::Value hostContext;
160 };
161
164 class BoxValue : public AbstractBox, public AbstractArrayBox {
165 public:
166 BoxValue(mlir::Value addr) : AbstractBox{addr}, AbstractArrayBox{} {}
167 BoxValue(mlir::Value addr, mlir::Value len)
168 : AbstractBox{addr}, AbstractArrayBox{}, len{len} {}
169 BoxValue(mlir::Value addr, llvm::ArrayRef<mlir::Value> extents,
170 llvm::ArrayRef<mlir::Value> lbounds = {})
171 : AbstractBox{addr}, AbstractArrayBox{extents, lbounds} {}
172 BoxValue(mlir::Value addr, mlir::Value len,
173 llvm::ArrayRef<mlir::Value> params,
174 llvm::ArrayRef<mlir::Value> extents,
175 llvm::ArrayRef<mlir::Value> lbounds = {})
176 : AbstractBox{addr}, AbstractArrayBox{extents, lbounds}, len{len},
177 params{params.begin(), params.end()} {}
178
179 BoxValue clone(mlir::Value newBase) const {
180 return {newBase, len, params, extents, lbounds};
181 }
182
183 mlir::Value getLen() const { return len; }
184 const llvm::SmallVectorImpl<mlir::Value> &getLenTypeParams() const {
185 return params;
186 }
187
188 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const BoxValue &);
189 LLVM_DUMP_METHOD void dump() const { operator<<(llvm::errs(), *this); }
190
191 protected:
192 mlir::Value len;
193 llvm::SmallVector<mlir::Value, 2> params;
194 };
195
197 using RangeBoxValue = std::tuple<mlir::Value, mlir::Value, mlir::Value>;
198
199 class ExtendedValue;
200
201 mlir::Value getBase(const ExtendedValue &exv);
202 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ExtendedValue &);
203 ExtendedValue substBase(const ExtendedValue &exv, mlir::Value base);
204
210 class ExtendedValue {
211 public:
212 template <typename A>
213 constexpr ExtendedValue(A &&box) : box{std::forward<A>(box)} {}
214
215 constexpr const CharBoxValue *getCharBox() const {
216 return std::get_if<CharBoxValue>(&box);
217 }
218
219 constexpr const UnboxedValue *getUnboxed() const {
220 return std::get_if<UnboxedValue>(&box);
221 }
222
224 LLVM_DUMP_METHOD void dump() const { llvm::errs() << *this << '\n'; }
225
226 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
227 const ExtendedValue &);
228 friend mlir::Value getBase(const ExtendedValue &exv);
229 friend ExtendedValue substBase(const ExtendedValue &exv, mlir::Value base);
230
231 private:
232 std::variant<UnboxedValue, CharBoxValue, ArrayBoxValue, CharArrayBoxValue,
233 BoxValue, ProcBoxValue>
234 box;
235 };
236 } // namespace fir
237
238 #endif // LOWER_SUPPORT_BOXVALUE_H
fir::AbstractArrayBox
Definition: BoxValue.h:81
fir::ExtendedValue::dump
LLVM_DUMP_METHOD void dump() const
LLVM style debugging of extended values.
Definition: BoxValue.h:224
fir::ArrayBoxValue
Definition: BoxValue.h:109
fir::ProcBoxValue
Definition: BoxValue.h:143
llvm::ArrayRef
Definition: FIRType.h:20
fir::CharBoxValue
Definition: BoxValue.h:59
fir::AbstractBox
Abstract base class.
Definition: BoxValue.h:47
fir::CharArrayBoxValue
Expressions of type CHARACTER and with rank > 0.
Definition: BoxValue.h:125
fir::BoxValue
Definition: BoxValue.h:164
fir::ExtendedValue
Definition: BoxValue.h:210