return fir::UnboxedValue{};
}
-/// Test if an ExtendedValue is absent.
-static bool isAbsent(const fir::ExtendedValue &exv) {
+/// Test if an ExtendedValue is absent. This is used to test if an intrinsic
+/// argument are absent at compile time.
+static bool isStaticallyAbsent(const fir::ExtendedValue &exv) {
return !fir::getBase(exv);
}
-static bool isAbsent(llvm::ArrayRef<fir::ExtendedValue> args, size_t argIndex) {
- return args.size() <= argIndex || isAbsent(args[argIndex]);
+static bool isStaticallyAbsent(llvm::ArrayRef<fir::ExtendedValue> args,
+ size_t argIndex) {
+ return args.size() <= argIndex || isStaticallyAbsent(args[argIndex]);
}
-static bool isAbsent(llvm::ArrayRef<mlir::Value> args, size_t argIndex) {
+static bool isStaticallyAbsent(llvm::ArrayRef<mlir::Value> args,
+ size_t argIndex) {
return args.size() <= argIndex || !args[argIndex];
}
-/// Test if an ExtendedValue is present.
-static bool isPresent(const fir::ExtendedValue &exv) { return !isAbsent(exv); }
+/// Test if an ExtendedValue is present. This is used to test if an intrinsic
+/// argument is present at compile time. This does not imply that the related
+/// value may not be an absent dummy optional, disassociated pointer, or a
+/// deallocated allocatable. See `handleDynamicOptional` to deal with these
+/// cases when it makes sense.
+static bool isStaticallyPresent(const fir::ExtendedValue &exv) {
+ return !isStaticallyAbsent(exv);
+}
/// Process calls to Maxval, Minval, Product, Sum intrinsic functions that
/// take a DIM argument.
fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
mlir::Value dim =
- isAbsent(dimArg)
+ isStaticallyAbsent(dimArg)
? builder.createIntegerConstant(loc, builder.getIndexType(), 0)
: fir::getBase(dimArg);
funcDim(builder, loc, resultIrBox, array, dim, mask);
assert(rank >= 1);
// Handle optional mask argument
- auto mask = isAbsent(args[2])
+ auto mask = isStaticallyAbsent(args[2])
? builder.create<fir::AbsentOp>(
loc, fir::BoxType::get(builder.getI1Type()))
: builder.createBox(loc, args[2]);
- bool absentDim = isAbsent(args[1]);
+ bool absentDim = isStaticallyAbsent(args[1]);
// We call the type specific versions because the result is scalar
// in the case below.
bool hasCharacterResult = arryTmp.isCharacter();
// Handle optional mask argument
- auto mask = isAbsent(args[2])
+ auto mask = isStaticallyAbsent(args[2])
? builder.create<fir::AbsentOp>(
loc, fir::BoxType::get(builder.getI1Type()))
: builder.createBox(loc, args[2]);
- bool absentDim = isAbsent(args[1]);
+ bool absentDim = isStaticallyAbsent(args[1]);
// For Maxval/MinVal, we call the type specific versions of
// Maxval/Minval because the result is scalar in the case below.
assert(rank >= 1);
// Handle optional mask argument
- auto mask = isAbsent(args[2])
+ auto mask = isStaticallyAbsent(args[2])
? builder.create<fir::AbsentOp>(
loc, fir::BoxType::get(builder.getI1Type()))
: builder.createBox(loc, args[2]);
// Handle optional kind argument
- auto kind = isAbsent(args[3]) ? builder.createIntegerConstant(
- loc, builder.getIndexType(),
- builder.getKindMap().defaultIntegerKind())
- : fir::getBase(args[3]);
+ auto kind = isStaticallyAbsent(args[3])
+ ? builder.createIntegerConstant(
+ loc, builder.getIndexType(),
+ builder.getKindMap().defaultIntegerKind())
+ : fir::getBase(args[3]);
// Handle optional back argument
- auto back = isAbsent(args[4]) ? builder.createBool(loc, false)
- : fir::getBase(args[4]);
+ auto back = isStaticallyAbsent(args[4]) ? builder.createBool(loc, false)
+ : fir::getBase(args[4]);
- bool absentDim = isAbsent(args[1]);
+ bool absentDim = isStaticallyAbsent(args[1]);
if (!absentDim && rank == 1) {
// If dim argument is present and the array is rank 1, then the result is
assert(rank >= 1);
// Handle optional dim argument
- bool absentDim = isAbsent(args[1]);
+ bool absentDim = isStaticallyAbsent(args[1]);
mlir::Value dim =
absentDim ? builder.createIntegerConstant(loc, builder.getIndexType(), 1)
: fir::getBase(args[1]);
assert(rank >= 1);
// Handle optional dim argument
- bool absentDim = isAbsent(args[1]);
+ bool absentDim = isStaticallyAbsent(args[1]);
mlir::Value dim =
absentDim ? builder.createIntegerConstant(loc, builder.getIndexType(), 1)
: fir::getBase(args[1]);
fir::emitFatalError(loc, "pointer not a MutableBoxValue");
});
const fir::ExtendedValue &target = args[1];
- if (isAbsent(target))
+ if (isStaticallyAbsent(target))
return fir::factory::genIsAllocatedOrAssociatedTest(builder, loc, *pointer);
mlir::Value targetBox = builder.createBox(loc, target);
fir::factory::Complex complexHelper(builder, loc);
mlir::Type partType = complexHelper.getComplexPartType(resultType);
mlir::Value real = builder.createConvert(loc, partType, args[0]);
- mlir::Value imag = isAbsent(args, 1)
+ mlir::Value imag = isStaticallyAbsent(args, 1)
? builder.createRealZeroConstant(loc, partType)
: builder.createConvert(loc, partType, args[1]);
return fir::factory::Complex{builder, loc}.createComplex(resultType, real,
assert(maskRank > 0);
// Handle optional dim argument
- bool absentDim = isAbsent(args[1]);
+ bool absentDim = isStaticallyAbsent(args[1]);
mlir::Value dim =
absentDim ? builder.createIntegerConstant(loc, builder.getIndexType(), 0)
: fir::getBase(args[1]);
// Call general CountDim runtime routine.
// Handle optional kind argument
- bool absentKind = isAbsent(args[2]);
+ bool absentKind = isStaticallyAbsent(args[2]);
mlir::Value kind = absentKind ? builder.createIntegerConstant(
loc, builder.getIndexType(),
builder.getKindMap().defaultIntegerKind())
// Handle optional DIM argument
mlir::Value dim =
- isAbsent(args[2])
+ isStaticallyAbsent(args[2])
? builder.createIntegerConstant(loc, builder.getIndexType(), 1)
: fir::getBase(args[2]);
fir::runtime::genCshift(builder, loc, resultIrBox, array, shift, dim);
// Handle optional BOUNDARY argument
mlir::Value boundary =
- isAbsent(args[2]) ? builder.create<fir::AbsentOp>(
- loc, fir::BoxType::get(builder.getNoneType()))
- : builder.createBox(loc, args[2]);
+ isStaticallyAbsent(args[2])
+ ? builder.create<fir::AbsentOp>(
+ loc, fir::BoxType::get(builder.getNoneType()))
+ : builder.createBox(loc, args[2]);
if (arrayRank == 1) {
// Vector case
// Handle optional DIM argument
mlir::Value dim =
- isAbsent(args[3])
+ isStaticallyAbsent(args[3])
? builder.createIntegerConstant(loc, builder.getIndexType(), 1)
: fir::getBase(args[3]);
fir::runtime::genEoshift(builder, loc, resultIrBox, array, shift, boundary,
assert(args.size() == 1);
mlir::Value status =
- isAbsent(args[0])
+ isStaticallyAbsent(args[0])
? builder.createIntegerConstant(loc, builder.getDefaultIntegerType(),
EXIT_SUCCESS)
: fir::getBase(args[0]);
mlir::Value status = fir::getBase(args[3]);
// Handle optional TRIM_NAME argument
- mlir::Value trim_name =
- isAbsent(args[4]) ? builder.createBool(loc, true) : fir::getBase(args[4]);
+ mlir::Value trim_name = isStaticallyAbsent(args[4])
+ ? builder.createBool(loc, true)
+ : fir::getBase(args[4]);
// Handle optional ERRMSG argument
mlir::Value errmsg;
mlir::Value substringBase = fir::getBase(args[1]);
mlir::Value substringLen = fir::getLen(args[1]);
mlir::Value back =
- isAbsent(args, 2)
+ isStaticallyAbsent(args, 2)
? builder.createIntegerConstant(loc, builder.getI1Type(), 0)
: fir::getBase(args[2]);
- if (isAbsent(args, 3))
+ if (isStaticallyAbsent(args, 3))
return builder.createConvert(
loc, resultType,
fir::runtime::genIndex(builder, loc, kind, stringBase, stringLen,
builder.create<fir::StoreOp>(loc, castb, temp);
return builder.createBox(loc, temp);
};
- mlir::Value backOpt = isAbsent(args, 2)
+ mlir::Value backOpt = isStaticallyAbsent(args, 2)
? builder.create<fir::AbsentOp>(
loc, fir::BoxType::get(builder.getI1Type()))
: makeRefThenEmbox(fir::getBase(args[2]));
- mlir::Value kindVal = isAbsent(args, 3)
+ mlir::Value kindVal = isStaticallyAbsent(args, 3)
? builder.createIntegerConstant(
loc, builder.getIndexType(),
builder.getKindMap().defaultIntegerKind())
IntrinsicLibrary::genNull(mlir::Type, llvm::ArrayRef<fir::ExtendedValue> args) {
// NULL() without MOLD must be handled in the contexts where it can appear
// (see table 16.5 of Fortran 2018 standard).
- assert(args.size() == 1 && isPresent(args[0]) &&
+ assert(args.size() == 1 && isStaticallyPresent(args[0]) &&
"MOLD argument required to lower NULL outside of any context");
const auto *mold = args[0].getBoxOf<fir::MutableBoxValue>();
assert(mold && "MOLD must be a pointer or allocatable");
mlir::Value mask = builder.createBox(loc, args[1]);
// Handle optional vector argument
- mlir::Value vector = isAbsent(args, 2)
+ mlir::Value vector = isStaticallyAbsent(args, 2)
? builder.create<fir::AbsentOp>(
loc, fir::BoxType::get(builder.getI1Type()))
: builder.createBox(loc, args[2]);
void IntrinsicLibrary::genRandomSeed(llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() == 3);
for (int i = 0; i < 3; ++i)
- if (isPresent(args[i])) {
+ if (isStaticallyPresent(args[i])) {
Fortran::lower::genRandomSeed(builder, loc, i, fir::getBase(args[i]));
return;
}
"shape arg must have constant size");
// Handle optional pad argument
- mlir::Value pad = isAbsent(args[2])
+ mlir::Value pad = isStaticallyAbsent(args[2])
? builder.create<fir::AbsentOp>(
loc, fir::BoxType::get(builder.getI1Type()))
: builder.createBox(loc, args[2]);
// Handle optional order argument
- mlir::Value order = isAbsent(args[3])
+ mlir::Value order = isStaticallyAbsent(args[3])
? builder.create<fir::AbsentOp>(
loc, fir::BoxType::get(builder.getI1Type()))
: builder.createBox(loc, args[3]);
assert(args.size() == 4);
- if (isAbsent(args[3])) {
+ if (isStaticallyAbsent(args[3])) {
// Kind not specified, so call scan/verify runtime routine that is
// specialized on the kind of characters in string.
// Handle optional back argument
mlir::Value back =
- isAbsent(args[2])
+ isStaticallyAbsent(args[2])
? builder.createIntegerConstant(loc, builder.getI1Type(), 0)
: fir::getBase(args[2]);
// The front-end rewrites SIZE without the DIM argument to
// an array of SIZE with DIM in most cases, but it may not be
// possible in some cases like when in SIZE(function_call()).
- if (isAbsent(args, 1))
+ if (isStaticallyAbsent(args, 1))
return builder.createConvert(loc, resultType,
fir::runtime::genSize(builder, loc, array));
//===----------------------------------------------------------------------===//
mlir::Type indexType = builder.getIndexType();
- if (isAbsent(args, 1)) {
+ if (isStaticallyAbsent(args, 1)) {
mlir::Type lbType = fir::unwrapSequenceType(resultType);
unsigned rank = array.rank();
mlir::Type lbArrayType = fir::SequenceType::get(
return builder.create<mlir::arith::AddIOp>(loc, ubound, extent);
} else {
// Handle calls to UBOUND without the DIM argument, which return an array
- mlir::Value kind = isAbsent(args[1])
+ mlir::Value kind = isStaticallyAbsent(args[1])
? builder.createIntegerConstant(
loc, builder.getIndexType(),
builder.getKindMap().defaultIntegerKind())
assert(args.size() == 4);
- if (isAbsent(args[3])) {
+ if (isStaticallyAbsent(args[3])) {
// Kind not specified, so call scan/verify runtime routine that is
// specialized on the kind of characters in string.
// Handle optional back argument
mlir::Value back =
- isAbsent(args[2])
+ isStaticallyAbsent(args[2])
? builder.createIntegerConstant(loc, builder.getI1Type(), 0)
: fir::getBase(args[2]);