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"
37llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const CharBoxValue &);
38llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const ArrayBoxValue &);
40llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const ProcBoxValue &);
41llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const MutableBoxValue &);
42llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const BoxValue &);
62 AbstractBox() =
delete;
63 AbstractBox(mlir::Value addr) : addr{addr} {}
68 mlir::Value
getAddr()
const {
return addr; }
76class CharBoxValue :
public AbstractBox {
78 CharBoxValue(mlir::Value addr, mlir::Value len)
79 : AbstractBox{addr}, len{len} {
80 if (addr && mlir::isa<fir::BoxCharType>(addr.getType()))
82 "BoxChar should not be in CharBoxValue");
85 CharBoxValue clone(mlir::Value newBase)
const {
return {newBase, len}; }
90 mlir::Value
getLen()
const {
return len; }
92 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
93 const CharBoxValue &);
94 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
101class PolymorphicValue :
public AbstractBox {
103 PolymorphicValue(mlir::Value addr, mlir::Value sourceBox)
104 : AbstractBox{addr}, sourceBox{sourceBox} {}
106 PolymorphicValue clone(mlir::Value newBase)
const {
107 return {newBase, sourceBox};
110 mlir::Value getSourceBox()
const {
return sourceBox; }
112 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
113 const PolymorphicValue &);
114 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
117 mlir::Value sourceBox;
124class AbstractArrayBox {
126 AbstractArrayBox() =
default;
129 : extents{extents}, lbounds{lbounds} {}
132 const llvm::SmallVectorImpl<mlir::Value> &getExtents()
const {
138 const llvm::SmallVectorImpl<mlir::Value> &getLBounds()
const {
142 bool lboundsAllOne()
const {
return lbounds.empty(); }
143 std::size_t rank()
const {
return extents.size(); }
152class ArrayBoxValue :
public PolymorphicValue,
public AbstractArrayBox {
156 mlir::Value sourceBox = {})
157 : PolymorphicValue{addr, sourceBox}, AbstractArrayBox{extents, lbounds} {}
159 ArrayBoxValue clone(mlir::Value newBase)
const {
160 return {newBase, extents, lbounds};
163 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
164 const ArrayBoxValue &);
165 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
169class CharArrayBoxValue :
public CharBoxValue,
public AbstractArrayBox {
171 CharArrayBoxValue(mlir::Value addr, mlir::Value len,
174 : CharBoxValue{addr, len}, AbstractArrayBox{extents, lbounds} {}
176 CharArrayBoxValue clone(mlir::Value newBase)
const {
177 return {newBase, len, extents, lbounds};
180 CharBoxValue cloneElement(mlir::Value newBase)
const {
181 return {newBase, len};
184 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
185 const CharArrayBoxValue &);
186 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
191class ProcBoxValue :
public AbstractBox {
193 ProcBoxValue(mlir::Value addr, mlir::Value context)
194 : AbstractBox{addr}, hostContext{context} {}
196 ProcBoxValue clone(mlir::Value newBase)
const {
197 return {newBase, hostContext};
200 mlir::Value getHostContext()
const {
return hostContext; }
202 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
203 const ProcBoxValue &);
204 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
207 mlir::Value hostContext;
211class AbstractIrBox :
public AbstractBox,
public AbstractArrayBox {
213 AbstractIrBox(mlir::Value addr) : AbstractBox{addr} {}
216 : AbstractBox{addr}, AbstractArrayBox(extents, lbounds) {}
219 auto type =
getAddr().getType();
222 return mlir::cast<fir::BaseBoxType>(type);
244 if (
auto seqTy = mlir::dyn_cast<fir::SequenceType>(type))
245 return seqTy.getEleTy();
253 auto seqTy = mlir::dyn_cast<fir::SequenceType>(
getBaseTy());
254 return seqTy && seqTy.hasUnknownShape();
259 if (
auto seqTy = mlir::dyn_cast<fir::SequenceType>(
getBaseTy()))
260 return seqTy.getDimension();
292class BoxValue :
public AbstractIrBox {
294 BoxValue(mlir::Value addr) : AbstractIrBox{addr} { assert(
verify()); }
298 : AbstractIrBox{addr, lbounds, explicitExtents},
299 explicitParams{explicitParams} {
303 bool isContiguous()
const {
return false; }
306 BoxValue clone(mlir::Value newBox)
const {
307 return {newBox, lbounds, explicitParams, extents};
310 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const BoxValue &);
311 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
325 return explicitParams;
345 bool isEmpty()
const {
return !addr; }
369 : AbstractIrBox(addr),
lenParams{lenParameters.begin(),
370 lenParameters.end()},
376 "MutableBoxValue requires mem ref to fir.box<fir.[heap|ptr]<type>>");
394 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
396 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this; }
430llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const ExtendedValue &);
476 template <
typename A,
typename = std::enable_if_t<
477 !std::is_same_v<std::decay_t<A>, ExtendedValue>>>
478 constexpr ExtendedValue(A &&a) : box{std::forward<A>(a)} {
479 if (
const auto *b = getUnboxed()) {
481 auto type = b->getType();
482 if (mlir::isa<fir::BoxCharType>(type))
487 "character buffer should be in CharBoxValue");
492 template <
typename A>
493 constexpr const A *getBoxOf()
const {
494 return std::get_if<A>(&box);
498 return getBoxOf<CharBoxValue>();
502 return getBoxOf<UnboxedValue>();
505 unsigned rank()
const {
510 [](
const auto &box) ->
unsigned {
return box.rank(); });
513 bool isPolymorphic()
const {
516 return box.getSourceBox() ? true :
false;
518 [](
const auto &box) ->
bool {
return false; });
521 bool hasAssumedRank()
const {
523 [](
const fir::BoxValue &box) ->
bool {
return box.hasAssumedRank(); },
525 return box.hasAssumedRank();
527 [](
const auto &box) ->
bool {
return false; });
531 LLVM_DUMP_METHOD
void dump()
const { llvm::errs() << *
this <<
'\n'; }
534 const ExtendedValue &);
536 const VT &matchee()
const {
return box; }
546 [](
const auto &) {
return false; });
mlir::Value getAddr() const
Definition BoxValue.h:68
fir::BaseBoxType getBoxTy() const
Get the fir.box<type> part of the address type.
Definition BoxValue.h:218
bool isUnlimitedPolymorphic() const
Is this a CLASS(*)/TYPE(*)?
Definition BoxValue.h:278
bool isDerived() const
Is this a derived type entity ?
Definition BoxValue.h:268
mlir::Type getBaseTy() const
Definition BoxValue.h:226
mlir::Type getEleTy() const
Get the scalar type related to the described entity.
Definition BoxValue.h:242
bool isCharacter() const
Is this a character entity ?
Definition BoxValue.h:265
bool hasRank() const
Is the entity an array or an assumed rank ?
Definition BoxValue.h:250
bool hasAssumedRank() const
Is this an assumed rank ?
Definition BoxValue.h:252
unsigned rank() const
Definition BoxValue.h:258
mlir::Type getMemTy() const
Definition BoxValue.h:234
bool isPolymorphic() const
Is this a polymorphic entity?
Definition BoxValue.h:275
Definition BoxValue.h:152
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:1482
Definition BoxValue.h:292
bool verify() const
Definition BoxValue.cpp:212
Expressions of type CHARACTER and with rank > 0.
Definition BoxValue.h:169
mlir::Value getBuffer() const
Convenience alias to get the memory reference to the buffer.
Definition BoxValue.h:88
Definition BoxValue.h:469
LLVM_DUMP_METHOD void dump() const
LLVM style debugging of extended values.
Definition BoxValue.h:531
friend llvm::raw_ostream & operator<<(llvm::raw_ostream &, const ExtendedValue &)
Pretty-print an extended value.
Definition FIRBuilder.h:59
Definition BoxValue.h:361
MutableBoxValue(mlir::Value addr, mlir::ValueRange lenParameters, MutableProperties mutableProperties)
Definition BoxValue.h:367
bool hasNonDeferredLenParams() const
Does this entity has any non deferred LEN parameters?
Definition BoxValue.h:391
bool isAllocatable() const
Is this an allocatable ?
Definition BoxValue.h:383
llvm::SmallVector< mlir::Value, 2 > lenParams
Definition BoxValue.h:412
bool isDescribedByVariables() const
Definition BoxValue.h:400
bool isPointer() const
Is this a Fortran pointer ?
Definition BoxValue.h:379
MutableProperties mutableProperties
Definition BoxValue.h:416
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:393
Definition BoxValue.h:343
llvm::SmallVector< mlir::Value, 2 > deferredParams
Definition BoxValue.h:354
Polymorphic value associated with a dynamic type descriptor.
Definition BoxValue.h:101
Definition BoxValue.h:191
Definition BoxValue.h:446
llvm::SmallVector< mlir::Value > getTypeParams(mlir::Location loc, FirOpBuilder &builder, const ExtendedValue &exv)
Definition FIRBuilder.cpp:1155
llvm::SmallVector< mlir::Value > getExtents(mlir::Location loc, FirOpBuilder &builder, const ExtendedValue &box)
Definition FIRBuilder.cpp:1081
Definition AbstractConverter.h:37
bool isa_ref_type(mlir::Type t)
Is t a FIR dialect type that implies a memory (de)reference?
Definition FIRType.h:135
bool isa_volatile_type(mlir::Type t)
Definition FIRType.cpp:766
bool isUnlimitedPolymorphicType(mlir::Type ty)
Definition FIRType.cpp:418
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:228
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:543
mlir::Value UnboxedValue
Definition BoxValue.h:57
mlir::Type dyn_cast_ptrEleTy(mlir::Type t)
Definition FIRType.cpp:257
mlir::Type getElementTypeOf(const ExtendedValue &exv)
Definition BoxValue.h:562
mlir::Value getBase(const ExtendedValue &exv)
Definition BoxValue.cpp:21
mlir::Type dyn_cast_ptrOrBoxEleTy(mlir::Type t)
Definition FIRType.cpp:264
bool isPolymorphicType(mlir::Type ty)
Definition FIRType.cpp:410
unsigned getBoxCorank(mlir::Type boxTy)
Get the corank from a !fir.box type.
Definition FIRType.cpp:488
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:445
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:551
mlir::Type unwrapSequenceType(mlir::Type t)
If t is a SequenceType return its element type, otherwise return t.
Definition FIRType.h:290
bool isDerivedWithLenParameters(const ExtendedValue &exv)
Is the extended value exv a derived type with LEN parameters?
Definition BoxValue.h:567