13#ifndef FORTRAN_OPTIMIZER_BUILDER_BOXVALUE_H
14#define FORTRAN_OPTIMIZER_BUILDER_BOXVALUE_H
16#include "flang/Optimizer/Dialect/FIRType.h"
17#include "flang/Optimizer/Support/FatalError.h"
18#include "flang/Optimizer/Support/Matcher.h"
19#include "mlir/IR/OperationSupport.h"
20#include "mlir/IR/Value.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/Support/Compiler.h"
23#include "llvm/Support/raw_ostream.h"
38llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const CharBoxValue &);
39llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const ArrayBoxValue &);
41llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const ProcBoxValue &);
42llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const MutableBoxValue &);
43llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const BoxValue &);
63 AbstractBox() =
delete;
64 AbstractBox(mlir::Value addr) : addr{addr} {}
69 mlir::Value
getAddr()
const {
return addr; }
77class CharBoxValue :
public AbstractBox {
79 CharBoxValue(mlir::Value addr, mlir::Value len)
80 : AbstractBox{addr}, len{len} {
81 if (addr && mlir::isa<fir::BoxCharType>(addr.getType()))
83 "BoxChar should not be in CharBoxValue");
86 CharBoxValue clone(mlir::Value newBase)
const {
return {newBase, len}; }
91 mlir::Value
getLen()
const {
return len; }
93 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
94 const CharBoxValue &);
95 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
102class PolymorphicValue :
public AbstractBox {
104 PolymorphicValue(mlir::Value addr, mlir::Value sourceBox)
105 : AbstractBox{addr}, sourceBox{sourceBox} {}
107 PolymorphicValue clone(mlir::Value newBase)
const {
108 return {newBase, sourceBox};
111 mlir::Value getSourceBox()
const {
return sourceBox; }
113 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
114 const PolymorphicValue &);
115 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
118 mlir::Value sourceBox;
125class AbstractArrayBox {
127 AbstractArrayBox() =
default;
130 : extents{extents}, lbounds{lbounds} {}
133 const llvm::SmallVectorImpl<mlir::Value> &getExtents()
const {
139 const llvm::SmallVectorImpl<mlir::Value> &getLBounds()
const {
143 bool lboundsAllOne()
const {
return lbounds.empty(); }
144 std::size_t rank()
const {
return extents.size(); }
153class ArrayBoxValue :
public PolymorphicValue,
public AbstractArrayBox {
157 mlir::Value sourceBox = {})
158 : PolymorphicValue{addr, sourceBox}, AbstractArrayBox{extents, lbounds} {}
160 ArrayBoxValue clone(mlir::Value newBase)
const {
161 return {newBase, extents, lbounds};
164 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
165 const ArrayBoxValue &);
166 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
170class CharArrayBoxValue :
public CharBoxValue,
public AbstractArrayBox {
172 CharArrayBoxValue(mlir::Value addr, mlir::Value len,
175 : CharBoxValue{addr, len}, AbstractArrayBox{extents, lbounds} {}
177 CharArrayBoxValue clone(mlir::Value newBase)
const {
178 return {newBase, len, extents, lbounds};
181 CharBoxValue cloneElement(mlir::Value newBase)
const {
182 return {newBase, len};
185 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
186 const CharArrayBoxValue &);
187 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
192class ProcBoxValue :
public AbstractBox {
194 ProcBoxValue(mlir::Value addr, mlir::Value context)
195 : AbstractBox{addr}, hostContext{context} {}
197 ProcBoxValue clone(mlir::Value newBase)
const {
198 return {newBase, hostContext};
201 mlir::Value getHostContext()
const {
return hostContext; }
203 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
204 const ProcBoxValue &);
205 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
208 mlir::Value hostContext;
212class AbstractIrBox :
public AbstractBox,
public AbstractArrayBox {
214 AbstractIrBox(mlir::Value addr) : AbstractBox{addr} {}
217 : AbstractBox{addr}, AbstractArrayBox(extents, lbounds) {}
220 auto type =
getAddr().getType();
223 return mlir::cast<fir::BaseBoxType>(type);
245 if (
auto seqTy = mlir::dyn_cast<fir::SequenceType>(type))
246 return seqTy.getEleTy();
254 auto seqTy = mlir::dyn_cast<fir::SequenceType>(
getBaseTy());
255 return seqTy && seqTy.hasUnknownShape();
260 if (
auto seqTy = mlir::dyn_cast<fir::SequenceType>(
getBaseTy()))
261 return seqTy.getDimension();
291class BoxValue :
public AbstractIrBox {
293 BoxValue(mlir::Value addr) : AbstractIrBox{addr} { assert(
verify()); }
297 : AbstractIrBox{addr, lbounds, explicitExtents},
298 explicitParams{explicitParams} {
302 bool isContiguous()
const {
return false; }
305 BoxValue clone(mlir::Value newBox)
const {
306 return {newBox, lbounds, explicitParams, extents};
309 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const BoxValue &);
310 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
324 return explicitParams;
344 bool isEmpty()
const {
return !addr; }
368 : AbstractIrBox(addr),
lenParams{lenParameters.begin(),
369 lenParameters.end()},
375 "MutableBoxValue requires mem ref to fir.box<fir.[heap|ptr]<type>>");
393 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
395 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
429llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const ExtendedValue &);
485 template <
typename A,
typename = std::enable_if_t<
486 !std::is_same_v<std::decay_t<A>, ExtendedValue>>>
487 constexpr ExtendedValue(A &&a) : box{std::forward<A>(a)} {
488 if (
const auto *b = getUnboxed()) {
490 auto type = b->getType();
491 if (mlir::isa<fir::BoxCharType>(type))
496 "character buffer should be in CharBoxValue");
501 template <
typename A>
502 constexpr const A *getBoxOf()
const {
503 return std::get_if<A>(&box);
507 return getBoxOf<CharBoxValue>();
511 return getBoxOf<UnboxedValue>();
514 unsigned rank()
const {
519 [](
const auto &box) ->
unsigned {
return box.rank(); });
522 bool isPolymorphic()
const {
525 return box.getSourceBox() ? true :
false;
527 [](
const auto &box) ->
bool {
return false; });
530 bool hasAssumedRank()
const {
532 [](
const fir::BoxValue &box) ->
bool {
return box.hasAssumedRank(); },
534 return box.hasAssumedRank();
536 [](
const auto &box) ->
bool {
return false; });
540 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this <<
'\n'; }
543 const ExtendedValue &);
545 const VT &matchee()
const {
return box; }
555 [](
const auto &) {
return false; });
mlir::Value getAddr() const
Definition BoxValue.h:69
fir::BaseBoxType getBoxTy() const
Get the fir.box<type> part of the address type.
Definition BoxValue.h:219
bool isUnlimitedPolymorphic() const
Is this a CLASS(*)/TYPE(*)?
Definition BoxValue.h:279
bool isDerived() const
Is this a derived type entity ?
Definition BoxValue.h:269
mlir::Type getBaseTy() const
Definition BoxValue.h:227
mlir::Type getEleTy() const
Get the scalar type related to the described entity.
Definition BoxValue.h:243
bool isCharacter() const
Is this a character entity ?
Definition BoxValue.h:266
bool hasRank() const
Is the entity an array or an assumed rank ?
Definition BoxValue.h:251
bool hasAssumedRank() const
Is this an assumed rank ?
Definition BoxValue.h:253
unsigned rank() const
Definition BoxValue.h:259
mlir::Type getMemTy() const
Definition BoxValue.h:235
bool isPolymorphic() const
Is this a polymorphic entity?
Definition BoxValue.h:276
Definition BoxValue.h:153
This class provides a shared interface for box and class types.
Definition FIRType.h:40
mlir::Type getEleTy() const
Returns the element type of this box type.
Definition FIRType.cpp:1406
Definition BoxValue.h:291
bool verify() const
Definition BoxValue.cpp:212
Expressions of type CHARACTER and with rank > 0.
Definition BoxValue.h:170
mlir::Value getBuffer() const
Convenience alias to get the memory reference to the buffer.
Definition BoxValue.h:89
Definition BoxValue.h:478
LLVM_DUMP_METHOD void dump() const
LLVM style debugging of extended values.
Definition BoxValue.h:540
friend llvm::raw_ostream & operator<<(llvm::raw_ostream &, const ExtendedValue &)
Pretty-print an extended value.
Definition FIRBuilder.h:55
Definition BoxValue.h:360
MutableBoxValue(mlir::Value addr, mlir::ValueRange lenParameters, MutableProperties mutableProperties)
Definition BoxValue.h:366
bool hasNonDeferredLenParams() const
Does this entity has any non deferred LEN parameters?
Definition BoxValue.h:390
bool isAllocatable() const
Is this an allocatable ?
Definition BoxValue.h:382
llvm::SmallVector< mlir::Value, 2 > lenParams
Definition BoxValue.h:411
bool isDescribedByVariables() const
Definition BoxValue.h:399
bool isPointer() const
Is this a Fortran pointer ?
Definition BoxValue.h:378
MutableProperties mutableProperties
Definition BoxValue.h:415
bool verify() const
Validate the address type form in the constructor.
Definition BoxValue.cpp:190
llvm::ArrayRef< mlir::Value > nonDeferredLenParams() const
Return the non deferred LEN parameters.
Definition BoxValue.h:392
Definition BoxValue.h:342
llvm::SmallVector< mlir::Value, 2 > deferredParams
Definition BoxValue.h:353
Polymorphic value associated with a dynamic type descriptor.
Definition BoxValue.h:102
Definition BoxValue.h:192
Definition BoxValue.h:445
llvm::SmallVector< mlir::Value > getTypeParams(mlir::Location loc, FirOpBuilder &builder, const ExtendedValue &exv)
Definition FIRBuilder.cpp:1180
mlir::Value getExtentAtDimension(mlir::Location loc, FirOpBuilder &builder, const ExtendedValue &exv, unsigned dim)
Definition BoxValue.cpp:226
llvm::SmallVector< mlir::Value > getExtents(mlir::Location loc, FirOpBuilder &builder, const ExtendedValue &box)
Definition FIRBuilder.cpp:1058
Definition AbstractConverter.h:34
bool isa_ref_type(mlir::Type t)
Is t a FIR dialect type that implies a memory (de)reference?
Definition FIRType.h:118
bool isa_volatile_type(mlir::Type t)
Definition FIRType.cpp:741
bool isUnlimitedPolymorphicType(mlir::Type ty)
Definition FIRType.cpp:399
mlir::Value getLen(const ExtendedValue &exv)
Definition BoxValue.cpp:26
bool isa_char(mlir::Type t)
Is t a CHARACTER type? Does not check the length.
Definition FIRType.h:210
llvm::SmallVector< mlir::Value > getTypeParams(const ExtendedValue &exv)
Get the type parameters for exv.
Definition BoxValue.cpp:47
bool isUnboxedValue(const ExtendedValue &exv)
Is the extended value exv unboxed and non-null?
Definition BoxValue.h:552
mlir::Value UnboxedValue
Definition BoxValue.h:58
mlir::Type dyn_cast_ptrEleTy(mlir::Type t)
Definition FIRType.cpp:247
mlir::Type getElementTypeOf(const ExtendedValue &exv)
Definition BoxValue.h:571
mlir::Value getBase(const ExtendedValue &exv)
Definition BoxValue.cpp:21
mlir::Type dyn_cast_ptrOrBoxEleTy(mlir::Type t)
Definition FIRType.cpp:254
bool isPolymorphicType(mlir::Type ty)
Definition FIRType.cpp:391
ExtendedValue substBase(const ExtendedValue &exv, mlir::Value base)
Definition BoxValue.cpp:39
bool isArray(const ExtendedValue &exv)
Definition BoxValue.cpp:72
bool isRecordWithTypeParameters(mlir::Type ty)
Return true iff ty is a RecordType with type parameters.
Definition FIRType.h:424
void emitFatalError(mlir::Location loc, const llvm::Twine &message, bool genCrashDiag=true)
Definition FatalError.h:25
mlir::Type getBaseTypeOf(const ExtendedValue &exv)
Definition BoxValue.h:560
mlir::Type unwrapSequenceType(mlir::Type t)
If t is a SequenceType return its element type, otherwise return t.
Definition FIRType.h:272
bool isDerivedWithLenParameters(const ExtendedValue &exv)
Is the extended value exv a derived type with LEN parameters?
Definition BoxValue.h:576