This will allow IntrinsicCall to be moved into lib/Optimizer later.
Differential Revision: https://reviews.llvm.org/D143081
void genUnlockStatement(AbstractConverter &, const parser::UnlockStmt &);
void genPauseStatement(AbstractConverter &, const parser::PauseStmt &);
-mlir::Value genAssociated(fir::FirOpBuilder &, mlir::Location,
- mlir::Value pointer, mlir::Value target);
-
void genPointerAssociate(fir::FirOpBuilder &, mlir::Location,
mlir::Value pointer, mlir::Value target);
void genPointerAssociateRemapping(fir::FirOpBuilder &, mlir::Location,
mlir::Value pointer, mlir::Value target,
mlir::Value bounds);
-
-mlir::Value genCpuTime(fir::FirOpBuilder &, mlir::Location);
-void genDateAndTime(fir::FirOpBuilder &, mlir::Location,
- std::optional<fir::CharBoxValue> date,
- std::optional<fir::CharBoxValue> time,
- std::optional<fir::CharBoxValue> zone, mlir::Value values);
-
-void genRandomInit(fir::FirOpBuilder &, mlir::Location, mlir::Value repeatable,
- mlir::Value imageDistinct);
-void genRandomNumber(fir::FirOpBuilder &, mlir::Location, mlir::Value harvest);
-void genRandomSeed(fir::FirOpBuilder &, mlir::Location, mlir::Value size,
- mlir::Value put, mlir::Value get);
-
-/// generate runtime call to transfer intrinsic with no size argument
-void genTransfer(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value resultBox, mlir::Value sourceBox,
- mlir::Value moldBox);
-
-/// generate runtime call to transfer intrinsic with size argument
-void genTransferSize(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value resultBox, mlir::Value sourceBox,
- mlir::Value moldBox, mlir::Value size);
-
-/// generate system_clock runtime call/s
-/// all intrinsic arguments are optional and may appear here as mlir::Value{}
-void genSystemClock(fir::FirOpBuilder &, mlir::Location, mlir::Value count,
- mlir::Value rate, mlir::Value max);
-
} // namespace lower
} // namespace Fortran
--- /dev/null
+// Builder/Runtime/Intrinsics.h Fortran runtime codegen interface -*- C++ -*-//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Builder routines for constructing the FIR dialect of MLIR. As FIR is a
+// dialect of MLIR, it makes extensive use of MLIR interfaces and MLIR's coding
+// style (https://mlir.llvm.org/getting_started/DeveloperGuide/) is used in this
+// module.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_LOWER_RUNTIME_H
+#define FORTRAN_LOWER_RUNTIME_H
+
+#include <optional>
+
+namespace mlir {
+class Location;
+class Value;
+} // namespace mlir
+
+namespace fir {
+class CharBoxValue;
+class FirOpBuilder;
+
+namespace runtime {
+
+mlir::Value genAssociated(fir::FirOpBuilder &, mlir::Location,
+ mlir::Value pointer, mlir::Value target);
+
+void genPointerAssociate(fir::FirOpBuilder &, mlir::Location,
+ mlir::Value pointer, mlir::Value target);
+void genPointerAssociateRemapping(fir::FirOpBuilder &, mlir::Location,
+ mlir::Value pointer, mlir::Value target,
+ mlir::Value bounds);
+
+mlir::Value genCpuTime(fir::FirOpBuilder &, mlir::Location);
+void genDateAndTime(fir::FirOpBuilder &, mlir::Location,
+ std::optional<fir::CharBoxValue> date,
+ std::optional<fir::CharBoxValue> time,
+ std::optional<fir::CharBoxValue> zone, mlir::Value values);
+
+void genRandomInit(fir::FirOpBuilder &, mlir::Location, mlir::Value repeatable,
+ mlir::Value imageDistinct);
+void genRandomNumber(fir::FirOpBuilder &, mlir::Location, mlir::Value harvest);
+void genRandomSeed(fir::FirOpBuilder &, mlir::Location, mlir::Value size,
+ mlir::Value put, mlir::Value get);
+
+/// generate runtime call to transfer intrinsic with no size argument
+void genTransfer(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value sourceBox,
+ mlir::Value moldBox);
+
+/// generate runtime call to transfer intrinsic with size argument
+void genTransferSize(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value sourceBox,
+ mlir::Value moldBox, mlir::Value size);
+
+/// generate system_clock runtime call/s
+/// all intrinsic arguments are optional and may appear here as mlir::Value{}
+void genSystemClock(fir::FirOpBuilder &, mlir::Location, mlir::Value count,
+ mlir::Value rate, mlir::Value max);
+} // namespace runtime
+} // namespace fir
+
+#endif // FORTRAN_LOWER_RUNTIME_H
#include "flang/Lower/IntrinsicCall.h"
#include "flang/Common/static-multimap-view.h"
#include "flang/Lower/Mangler.h"
-#include "flang/Lower/Runtime.h"
#include "flang/Lower/Support/Utils.h"
#include "flang/Optimizer/Builder/BoxValue.h"
#include "flang/Optimizer/Builder/Character.h"
#include "flang/Optimizer/Builder/Runtime/Command.h"
#include "flang/Optimizer/Builder/Runtime/Derived.h"
#include "flang/Optimizer/Builder/Runtime/Inquiry.h"
+#include "flang/Optimizer/Builder/Runtime/Intrinsics.h"
#include "flang/Optimizer/Builder/Runtime/Numeric.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Optimizer/Builder/Runtime/Reduction.h"
mlir::Value pointerBoxRef =
fir::factory::getMutableIRBox(builder, loc, *pointer);
auto pointerBox = builder.create<fir::LoadOp>(loc, pointerBoxRef);
- return Fortran::lower::genAssociated(builder, loc, pointerBox, targetBox);
+ return fir::runtime::genAssociated(builder, loc, pointerBox, targetBox);
}
// BESSEL_JN
assert(args.size() == 1);
const mlir::Value *arg = args[0].getUnboxed();
assert(arg && "nonscalar cpu_time argument");
- mlir::Value res1 = Fortran::lower::genCpuTime(builder, loc);
+ mlir::Value res1 = fir::runtime::genCpuTime(builder, loc);
mlir::Value res2 =
builder.createConvert(loc, fir::dyn_cast_ptrEleTy(arg->getType()), res1);
builder.create<fir::StoreOp>(loc, res2, *arg);
values = builder.create<fir::AbsentOp>(
loc, fir::BoxType::get(builder.getNoneType()));
- Fortran::lower::genDateAndTime(builder, loc, charArgs[0], charArgs[1],
- charArgs[2], values);
+ fir::runtime::genDateAndTime(builder, loc, charArgs[0], charArgs[1],
+ charArgs[2], values);
}
// DIM
// RANDOM_INIT
void IntrinsicLibrary::genRandomInit(llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() == 2);
- Fortran::lower::genRandomInit(builder, loc, fir::getBase(args[0]),
- fir::getBase(args[1]));
+ fir::runtime::genRandomInit(builder, loc, fir::getBase(args[0]),
+ fir::getBase(args[1]));
}
// RANDOM_NUMBER
void IntrinsicLibrary::genRandomNumber(
llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() == 1);
- Fortran::lower::genRandomNumber(builder, loc, fir::getBase(args[0]));
+ fir::runtime::genRandomNumber(builder, loc, fir::getBase(args[0]));
}
// RANDOM_SEED
mlir::Value size = getDesc(0);
mlir::Value put = getDesc(1);
mlir::Value get = getDesc(2);
- Fortran::lower::genRandomSeed(builder, loc, size, put, get);
+ fir::runtime::genRandomSeed(builder, loc, size, put, get);
}
// REDUCE
// SYSTEM_CLOCK
void IntrinsicLibrary::genSystemClock(llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() == 3);
- Fortran::lower::genSystemClock(builder, loc, fir::getBase(args[0]),
- fir::getBase(args[1]), fir::getBase(args[2]));
+ fir::runtime::genSystemClock(builder, loc, fir::getBase(args[0]),
+ fir::getBase(args[1]), fir::getBase(args[2]));
}
// TRANSFER
mlir::Value resultIrBox =
fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
- Fortran::lower::genTransfer(builder, loc, resultIrBox, source, mold);
+ fir::runtime::genTransfer(builder, loc, resultIrBox, source, mold);
} else {
// The result is a rank one array in this case.
mlir::Value resultIrBox =
fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
if (absentSize) {
- Fortran::lower::genTransfer(builder, loc, resultIrBox, source, mold);
+ fir::runtime::genTransfer(builder, loc, resultIrBox, source, mold);
} else {
mlir::Value sizeArg = fir::getBase(args[2]);
- Fortran::lower::genTransferSize(builder, loc, resultIrBox, source, mold,
- sizeArg);
+ fir::runtime::genTransferSize(builder, loc, resultIrBox, source, mold,
+ sizeArg);
}
}
return readAndAddCleanUp(resultMutableBox, resultType, "TRANSFER");
builder.create<fir::CallOp>(loc, callee, std::nullopt);
}
-mlir::Value Fortran::lower::genAssociated(fir::FirOpBuilder &builder,
- mlir::Location loc,
- mlir::Value pointer,
- mlir::Value target) {
- mlir::func::FuncOp func =
- fir::runtime::getRuntimeFunc<mkRTKey(PointerIsAssociatedWith)>(loc,
- builder);
- llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
- builder, loc, func.getFunctionType(), pointer, target);
- return builder.create<fir::CallOp>(loc, func, args).getResult(0);
-}
-
void Fortran::lower::genPointerAssociate(fir::FirOpBuilder &builder,
mlir::Location loc,
mlir::Value pointer,
sourceLine);
builder.create<fir::CallOp>(loc, func, args).getResult(0);
}
-
-mlir::Value Fortran::lower::genCpuTime(fir::FirOpBuilder &builder,
- mlir::Location loc) {
- mlir::func::FuncOp func =
- fir::runtime::getRuntimeFunc<mkRTKey(CpuTime)>(loc, builder);
- return builder.create<fir::CallOp>(loc, func, std::nullopt).getResult(0);
-}
-
-void Fortran::lower::genDateAndTime(fir::FirOpBuilder &builder,
- mlir::Location loc,
- std::optional<fir::CharBoxValue> date,
- std::optional<fir::CharBoxValue> time,
- std::optional<fir::CharBoxValue> zone,
- mlir::Value values) {
- mlir::func::FuncOp callee =
- fir::runtime::getRuntimeFunc<mkRTKey(DateAndTime)>(loc, builder);
- mlir::FunctionType funcTy = callee.getFunctionType();
- mlir::Type idxTy = builder.getIndexType();
- mlir::Value zero;
- auto splitArg = [&](std::optional<fir::CharBoxValue> arg, mlir::Value &buffer,
- mlir::Value &len) {
- if (arg) {
- buffer = arg->getBuffer();
- len = arg->getLen();
- } else {
- if (!zero)
- zero = builder.createIntegerConstant(loc, idxTy, 0);
- buffer = zero;
- len = zero;
- }
- };
- mlir::Value dateBuffer;
- mlir::Value dateLen;
- splitArg(date, dateBuffer, dateLen);
- mlir::Value timeBuffer;
- mlir::Value timeLen;
- splitArg(time, timeBuffer, timeLen);
- mlir::Value zoneBuffer;
- mlir::Value zoneLen;
- splitArg(zone, zoneBuffer, zoneLen);
-
- mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
- mlir::Value sourceLine =
- fir::factory::locationToLineNo(builder, loc, funcTy.getInput(7));
-
- llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
- builder, loc, funcTy, dateBuffer, dateLen, timeBuffer, timeLen,
- zoneBuffer, zoneLen, sourceFile, sourceLine, values);
- builder.create<fir::CallOp>(loc, callee, args);
-}
-
-void Fortran::lower::genRandomInit(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value repeatable,
- mlir::Value imageDistinct) {
- mlir::func::FuncOp func =
- fir::runtime::getRuntimeFunc<mkRTKey(RandomInit)>(loc, builder);
- llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
- builder, loc, func.getFunctionType(), repeatable, imageDistinct);
- builder.create<fir::CallOp>(loc, func, args);
-}
-
-void Fortran::lower::genRandomNumber(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value harvest) {
- mlir::func::FuncOp func =
- fir::runtime::getRuntimeFunc<mkRTKey(RandomNumber)>(loc, builder);
- mlir::FunctionType funcTy = func.getFunctionType();
- mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
- mlir::Value sourceLine =
- fir::factory::locationToLineNo(builder, loc, funcTy.getInput(2));
- llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
- builder, loc, funcTy, harvest, sourceFile, sourceLine);
- builder.create<fir::CallOp>(loc, func, args);
-}
-
-void Fortran::lower::genRandomSeed(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value size,
- mlir::Value put, mlir::Value get) {
- bool sizeIsPresent =
- !mlir::isa_and_nonnull<fir::AbsentOp>(size.getDefiningOp());
- bool putIsPresent =
- !mlir::isa_and_nonnull<fir::AbsentOp>(put.getDefiningOp());
- bool getIsPresent =
- !mlir::isa_and_nonnull<fir::AbsentOp>(get.getDefiningOp());
- mlir::func::FuncOp func;
- int staticArgCount = sizeIsPresent + putIsPresent + getIsPresent;
- if (staticArgCount == 0) {
- func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedDefaultPut)>(loc,
- builder);
- builder.create<fir::CallOp>(loc, func);
- return;
- }
- mlir::FunctionType funcTy;
- mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
- mlir::Value sourceLine;
- mlir::Value argBox;
- llvm::SmallVector<mlir::Value> args;
- if (staticArgCount > 1) {
- func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeed)>(loc, builder);
- funcTy = func.getFunctionType();
- sourceLine =
- fir::factory::locationToLineNo(builder, loc, funcTy.getInput(4));
- args = fir::runtime::createArguments(builder, loc, funcTy, size, put, get,
- sourceFile, sourceLine);
- builder.create<fir::CallOp>(loc, func, args);
- return;
- }
- if (sizeIsPresent) {
- func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedSize)>(loc, builder);
- argBox = size;
- } else if (putIsPresent) {
- func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedPut)>(loc, builder);
- argBox = put;
- } else {
- func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedGet)>(loc, builder);
- argBox = get;
- }
- funcTy = func.getFunctionType();
- sourceLine = fir::factory::locationToLineNo(builder, loc, funcTy.getInput(2));
- args = fir::runtime::createArguments(builder, loc, funcTy, argBox, sourceFile,
- sourceLine);
- builder.create<fir::CallOp>(loc, func, args);
-}
-
-/// generate runtime call to transfer intrinsic with no size argument
-void Fortran::lower::genTransfer(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value resultBox, mlir::Value sourceBox,
- mlir::Value moldBox) {
-
- mlir::func::FuncOp func =
- fir::runtime::getRuntimeFunc<mkRTKey(Transfer)>(loc, builder);
- mlir::FunctionType fTy = func.getFunctionType();
- mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
- mlir::Value sourceLine =
- fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
- llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
- builder, loc, fTy, resultBox, sourceBox, moldBox, sourceFile, sourceLine);
- builder.create<fir::CallOp>(loc, func, args);
-}
-
-/// generate runtime call to transfer intrinsic with size argument
-void Fortran::lower::genTransferSize(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value resultBox,
- mlir::Value sourceBox, mlir::Value moldBox,
- mlir::Value size) {
- mlir::func::FuncOp func =
- fir::runtime::getRuntimeFunc<mkRTKey(TransferSize)>(loc, builder);
- mlir::FunctionType fTy = func.getFunctionType();
- mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
- mlir::Value sourceLine =
- fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
- llvm::SmallVector<mlir::Value> args =
- fir::runtime::createArguments(builder, loc, fTy, resultBox, sourceBox,
- moldBox, sourceFile, sourceLine, size);
- builder.create<fir::CallOp>(loc, func, args);
-}
-
-/// generate system_clock runtime call/s
-/// all intrinsic arguments are optional and may appear here as mlir::Value{}
-void Fortran::lower::genSystemClock(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value count,
- mlir::Value rate, mlir::Value max) {
- auto makeCall = [&](mlir::func::FuncOp func, mlir::Value arg) {
- mlir::Type type = arg.getType();
- fir::IfOp ifOp{};
- const bool isOptionalArg =
- fir::valueHasFirAttribute(arg, fir::getOptionalAttrName());
- if (type.dyn_cast<fir::PointerType>() || type.dyn_cast<fir::HeapType>()) {
- // Check for a disassociated pointer or an unallocated allocatable.
- assert(!isOptionalArg && "invalid optional argument");
- ifOp = builder.create<fir::IfOp>(loc, builder.genIsNotNullAddr(loc, arg),
- /*withElseRegion=*/false);
- } else if (isOptionalArg) {
- ifOp = builder.create<fir::IfOp>(
- loc, builder.create<fir::IsPresentOp>(loc, builder.getI1Type(), arg),
- /*withElseRegion=*/false);
- }
- if (ifOp)
- builder.setInsertionPointToStart(&ifOp.getThenRegion().front());
- mlir::Type kindTy = func.getFunctionType().getInput(0);
- int integerKind = 8;
- if (auto intType = fir::unwrapRefType(type).dyn_cast<mlir::IntegerType>())
- integerKind = intType.getWidth() / 8;
- mlir::Value kind = builder.createIntegerConstant(loc, kindTy, integerKind);
- mlir::Value res =
- builder.create<fir::CallOp>(loc, func, mlir::ValueRange{kind})
- .getResult(0);
- mlir::Value castRes =
- builder.createConvert(loc, fir::dyn_cast_ptrEleTy(type), res);
- builder.create<fir::StoreOp>(loc, castRes, arg);
- if (ifOp)
- builder.setInsertionPointAfter(ifOp);
- };
- using fir::runtime::getRuntimeFunc;
- if (count)
- makeCall(getRuntimeFunc<mkRTKey(SystemClockCount)>(loc, builder), count);
- if (rate)
- makeCall(getRuntimeFunc<mkRTKey(SystemClockCountRate)>(loc, builder), rate);
- if (max)
- makeCall(getRuntimeFunc<mkRTKey(SystemClockCountMax)>(loc, builder), max);
-}
Runtime/Derived.cpp
Runtime/EnvironmentDefaults.cpp
Runtime/Inquiry.cpp
+ Runtime/Intrinsics.cpp
Runtime/Numeric.cpp
Runtime/Ragged.cpp
Runtime/Reduction.cpp
--- /dev/null
+//===-- Intrinsics.cpp ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Builder/Runtime/Intrinsics.h"
+#include "flang/Optimizer/Builder/BoxValue.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
+#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/Dialect/FIROpsSupport.h"
+#include "flang/Parser/parse-tree.h"
+#include "flang/Runtime/misc-intrinsic.h"
+#include "flang/Runtime/pointer.h"
+#include "flang/Runtime/random.h"
+#include "flang/Runtime/stop.h"
+#include "flang/Runtime/time-intrinsic.h"
+#include "flang/Semantics/tools.h"
+#include "llvm/Support/Debug.h"
+#include <optional>
+
+#define DEBUG_TYPE "flang-lower-runtime"
+
+using namespace Fortran::runtime;
+
+mlir::Value fir::runtime::genAssociated(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value pointer,
+ mlir::Value target) {
+ mlir::func::FuncOp func =
+ fir::runtime::getRuntimeFunc<mkRTKey(PointerIsAssociatedWith)>(loc,
+ builder);
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, func.getFunctionType(), pointer, target);
+ return builder.create<fir::CallOp>(loc, func, args).getResult(0);
+}
+
+mlir::Value fir::runtime::genCpuTime(fir::FirOpBuilder &builder,
+ mlir::Location loc) {
+ mlir::func::FuncOp func =
+ fir::runtime::getRuntimeFunc<mkRTKey(CpuTime)>(loc, builder);
+ return builder.create<fir::CallOp>(loc, func, std::nullopt).getResult(0);
+}
+
+void fir::runtime::genDateAndTime(fir::FirOpBuilder &builder,
+ mlir::Location loc,
+ std::optional<fir::CharBoxValue> date,
+ std::optional<fir::CharBoxValue> time,
+ std::optional<fir::CharBoxValue> zone,
+ mlir::Value values) {
+ mlir::func::FuncOp callee =
+ fir::runtime::getRuntimeFunc<mkRTKey(DateAndTime)>(loc, builder);
+ mlir::FunctionType funcTy = callee.getFunctionType();
+ mlir::Type idxTy = builder.getIndexType();
+ mlir::Value zero;
+ auto splitArg = [&](std::optional<fir::CharBoxValue> arg, mlir::Value &buffer,
+ mlir::Value &len) {
+ if (arg) {
+ buffer = arg->getBuffer();
+ len = arg->getLen();
+ } else {
+ if (!zero)
+ zero = builder.createIntegerConstant(loc, idxTy, 0);
+ buffer = zero;
+ len = zero;
+ }
+ };
+ mlir::Value dateBuffer;
+ mlir::Value dateLen;
+ splitArg(date, dateBuffer, dateLen);
+ mlir::Value timeBuffer;
+ mlir::Value timeLen;
+ splitArg(time, timeBuffer, timeLen);
+ mlir::Value zoneBuffer;
+ mlir::Value zoneLen;
+ splitArg(zone, zoneBuffer, zoneLen);
+
+ mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
+ mlir::Value sourceLine =
+ fir::factory::locationToLineNo(builder, loc, funcTy.getInput(7));
+
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, funcTy, dateBuffer, dateLen, timeBuffer, timeLen,
+ zoneBuffer, zoneLen, sourceFile, sourceLine, values);
+ builder.create<fir::CallOp>(loc, callee, args);
+}
+
+void fir::runtime::genRandomInit(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value repeatable,
+ mlir::Value imageDistinct) {
+ mlir::func::FuncOp func =
+ fir::runtime::getRuntimeFunc<mkRTKey(RandomInit)>(loc, builder);
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, func.getFunctionType(), repeatable, imageDistinct);
+ builder.create<fir::CallOp>(loc, func, args);
+}
+
+void fir::runtime::genRandomNumber(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value harvest) {
+ mlir::func::FuncOp func =
+ fir::runtime::getRuntimeFunc<mkRTKey(RandomNumber)>(loc, builder);
+ mlir::FunctionType funcTy = func.getFunctionType();
+ mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
+ mlir::Value sourceLine =
+ fir::factory::locationToLineNo(builder, loc, funcTy.getInput(2));
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, funcTy, harvest, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, func, args);
+}
+
+void fir::runtime::genRandomSeed(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value size, mlir::Value put,
+ mlir::Value get) {
+ bool sizeIsPresent =
+ !mlir::isa_and_nonnull<fir::AbsentOp>(size.getDefiningOp());
+ bool putIsPresent =
+ !mlir::isa_and_nonnull<fir::AbsentOp>(put.getDefiningOp());
+ bool getIsPresent =
+ !mlir::isa_and_nonnull<fir::AbsentOp>(get.getDefiningOp());
+ mlir::func::FuncOp func;
+ int staticArgCount = sizeIsPresent + putIsPresent + getIsPresent;
+ if (staticArgCount == 0) {
+ func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedDefaultPut)>(loc,
+ builder);
+ builder.create<fir::CallOp>(loc, func);
+ return;
+ }
+ mlir::FunctionType funcTy;
+ mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
+ mlir::Value sourceLine;
+ mlir::Value argBox;
+ llvm::SmallVector<mlir::Value> args;
+ if (staticArgCount > 1) {
+ func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeed)>(loc, builder);
+ funcTy = func.getFunctionType();
+ sourceLine =
+ fir::factory::locationToLineNo(builder, loc, funcTy.getInput(4));
+ args = fir::runtime::createArguments(builder, loc, funcTy, size, put, get,
+ sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, func, args);
+ return;
+ }
+ if (sizeIsPresent) {
+ func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedSize)>(loc, builder);
+ argBox = size;
+ } else if (putIsPresent) {
+ func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedPut)>(loc, builder);
+ argBox = put;
+ } else {
+ func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedGet)>(loc, builder);
+ argBox = get;
+ }
+ funcTy = func.getFunctionType();
+ sourceLine = fir::factory::locationToLineNo(builder, loc, funcTy.getInput(2));
+ args = fir::runtime::createArguments(builder, loc, funcTy, argBox, sourceFile,
+ sourceLine);
+ builder.create<fir::CallOp>(loc, func, args);
+}
+
+/// generate runtime call to transfer intrinsic with no size argument
+void fir::runtime::genTransfer(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value sourceBox,
+ mlir::Value moldBox) {
+
+ mlir::func::FuncOp func =
+ fir::runtime::getRuntimeFunc<mkRTKey(Transfer)>(loc, builder);
+ mlir::FunctionType fTy = func.getFunctionType();
+ mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
+ mlir::Value sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, fTy, resultBox, sourceBox, moldBox, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, func, args);
+}
+
+/// generate runtime call to transfer intrinsic with size argument
+void fir::runtime::genTransferSize(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value resultBox,
+ mlir::Value sourceBox, mlir::Value moldBox,
+ mlir::Value size) {
+ mlir::func::FuncOp func =
+ fir::runtime::getRuntimeFunc<mkRTKey(TransferSize)>(loc, builder);
+ mlir::FunctionType fTy = func.getFunctionType();
+ mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
+ mlir::Value sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
+ llvm::SmallVector<mlir::Value> args =
+ fir::runtime::createArguments(builder, loc, fTy, resultBox, sourceBox,
+ moldBox, sourceFile, sourceLine, size);
+ builder.create<fir::CallOp>(loc, func, args);
+}
+
+/// generate system_clock runtime call/s
+/// all intrinsic arguments are optional and may appear here as mlir::Value{}
+void fir::runtime::genSystemClock(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value count,
+ mlir::Value rate, mlir::Value max) {
+ auto makeCall = [&](mlir::func::FuncOp func, mlir::Value arg) {
+ mlir::Type type = arg.getType();
+ fir::IfOp ifOp{};
+ const bool isOptionalArg =
+ fir::valueHasFirAttribute(arg, fir::getOptionalAttrName());
+ if (type.dyn_cast<fir::PointerType>() || type.dyn_cast<fir::HeapType>()) {
+ // Check for a disassociated pointer or an unallocated allocatable.
+ assert(!isOptionalArg && "invalid optional argument");
+ ifOp = builder.create<fir::IfOp>(loc, builder.genIsNotNullAddr(loc, arg),
+ /*withElseRegion=*/false);
+ } else if (isOptionalArg) {
+ ifOp = builder.create<fir::IfOp>(
+ loc, builder.create<fir::IsPresentOp>(loc, builder.getI1Type(), arg),
+ /*withElseRegion=*/false);
+ }
+ if (ifOp)
+ builder.setInsertionPointToStart(&ifOp.getThenRegion().front());
+ mlir::Type kindTy = func.getFunctionType().getInput(0);
+ int integerKind = 8;
+ if (auto intType = fir::unwrapRefType(type).dyn_cast<mlir::IntegerType>())
+ integerKind = intType.getWidth() / 8;
+ mlir::Value kind = builder.createIntegerConstant(loc, kindTy, integerKind);
+ mlir::Value res =
+ builder.create<fir::CallOp>(loc, func, mlir::ValueRange{kind})
+ .getResult(0);
+ mlir::Value castRes =
+ builder.createConvert(loc, fir::dyn_cast_ptrEleTy(type), res);
+ builder.create<fir::StoreOp>(loc, castRes, arg);
+ if (ifOp)
+ builder.setInsertionPointAfter(ifOp);
+ };
+ using fir::runtime::getRuntimeFunc;
+ if (count)
+ makeCall(getRuntimeFunc<mkRTKey(SystemClockCount)>(loc, builder), count);
+ if (rate)
+ makeCall(getRuntimeFunc<mkRTKey(SystemClockCountRate)>(loc, builder), rate);
+ if (max)
+ makeCall(getRuntimeFunc<mkRTKey(SystemClockCountMax)>(loc, builder), max);
+}