118ed49d2STom Eccles //===-- Intrinsics.cpp ----------------------------------------------------===// 218ed49d2STom Eccles // 318ed49d2STom Eccles // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 418ed49d2STom Eccles // See https://llvm.org/LICENSE.txt for license information. 518ed49d2STom Eccles // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 618ed49d2STom Eccles // 718ed49d2STom Eccles //===----------------------------------------------------------------------===// 818ed49d2STom Eccles 918ed49d2STom Eccles #include "flang/Optimizer/Builder/Runtime/Intrinsics.h" 1018ed49d2STom Eccles #include "flang/Optimizer/Builder/BoxValue.h" 1118ed49d2STom Eccles #include "flang/Optimizer/Builder/FIRBuilder.h" 1218ed49d2STom Eccles #include "flang/Optimizer/Builder/Runtime/RTBuilder.h" 1318ed49d2STom Eccles #include "flang/Optimizer/Dialect/FIROpsSupport.h" 1418ed49d2STom Eccles #include "flang/Parser/parse-tree.h" 15b64c26f3STom Eccles #include "flang/Runtime/extensions.h" 1618ed49d2STom Eccles #include "flang/Runtime/misc-intrinsic.h" 1718ed49d2STom Eccles #include "flang/Runtime/pointer.h" 1818ed49d2STom Eccles #include "flang/Runtime/random.h" 1918ed49d2STom Eccles #include "flang/Runtime/stop.h" 2018ed49d2STom Eccles #include "flang/Runtime/time-intrinsic.h" 2118ed49d2STom Eccles #include "flang/Semantics/tools.h" 2218ed49d2STom Eccles #include "llvm/Support/Debug.h" 2318ed49d2STom Eccles #include <optional> 24afa52de9STom Eccles #include <signal.h> 2518ed49d2STom Eccles 2618ed49d2STom Eccles #define DEBUG_TYPE "flang-lower-runtime" 2718ed49d2STom Eccles 2818ed49d2STom Eccles using namespace Fortran::runtime; 2918ed49d2STom Eccles 30e0738cc6SSlava Zakharin namespace { 31e0738cc6SSlava Zakharin /// Placeholder for real*16 version of RandomNumber Intrinsic 32e0738cc6SSlava Zakharin struct ForcedRandomNumberReal16 { 33e0738cc6SSlava Zakharin static constexpr const char *name = ExpandAndQuoteKey(RTNAME(RandomNumber16)); 34e0738cc6SSlava Zakharin static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { 35e0738cc6SSlava Zakharin return [](mlir::MLIRContext *ctx) { 36e0738cc6SSlava Zakharin auto boxTy = 37e0738cc6SSlava Zakharin fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx); 38e0738cc6SSlava Zakharin auto strTy = fir::runtime::getModel<const char *>()(ctx); 39e0738cc6SSlava Zakharin auto intTy = fir::runtime::getModel<int>()(ctx); 40e0738cc6SSlava Zakharin ; 4112ba74e1SValentin Clement (バレンタイン クレメン) return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy}, {}); 42e0738cc6SSlava Zakharin }; 43e0738cc6SSlava Zakharin } 44e0738cc6SSlava Zakharin }; 45e0738cc6SSlava Zakharin } // namespace 46e0738cc6SSlava Zakharin 4718ed49d2STom Eccles mlir::Value fir::runtime::genAssociated(fir::FirOpBuilder &builder, 4818ed49d2STom Eccles mlir::Location loc, mlir::Value pointer, 4918ed49d2STom Eccles mlir::Value target) { 5018ed49d2STom Eccles mlir::func::FuncOp func = 5118ed49d2STom Eccles fir::runtime::getRuntimeFunc<mkRTKey(PointerIsAssociatedWith)>(loc, 5218ed49d2STom Eccles builder); 5318ed49d2STom Eccles llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 5418ed49d2STom Eccles builder, loc, func.getFunctionType(), pointer, target); 5518ed49d2STom Eccles return builder.create<fir::CallOp>(loc, func, args).getResult(0); 5618ed49d2STom Eccles } 5718ed49d2STom Eccles 5818ed49d2STom Eccles mlir::Value fir::runtime::genCpuTime(fir::FirOpBuilder &builder, 5918ed49d2STom Eccles mlir::Location loc) { 6018ed49d2STom Eccles mlir::func::FuncOp func = 6118ed49d2STom Eccles fir::runtime::getRuntimeFunc<mkRTKey(CpuTime)>(loc, builder); 6218ed49d2STom Eccles return builder.create<fir::CallOp>(loc, func, std::nullopt).getResult(0); 6318ed49d2STom Eccles } 6418ed49d2STom Eccles 6518ed49d2STom Eccles void fir::runtime::genDateAndTime(fir::FirOpBuilder &builder, 6618ed49d2STom Eccles mlir::Location loc, 6718ed49d2STom Eccles std::optional<fir::CharBoxValue> date, 6818ed49d2STom Eccles std::optional<fir::CharBoxValue> time, 6918ed49d2STom Eccles std::optional<fir::CharBoxValue> zone, 7018ed49d2STom Eccles mlir::Value values) { 7118ed49d2STom Eccles mlir::func::FuncOp callee = 7218ed49d2STom Eccles fir::runtime::getRuntimeFunc<mkRTKey(DateAndTime)>(loc, builder); 7318ed49d2STom Eccles mlir::FunctionType funcTy = callee.getFunctionType(); 7418ed49d2STom Eccles mlir::Type idxTy = builder.getIndexType(); 7518ed49d2STom Eccles mlir::Value zero; 7618ed49d2STom Eccles auto splitArg = [&](std::optional<fir::CharBoxValue> arg, mlir::Value &buffer, 7718ed49d2STom Eccles mlir::Value &len) { 7818ed49d2STom Eccles if (arg) { 7918ed49d2STom Eccles buffer = arg->getBuffer(); 8018ed49d2STom Eccles len = arg->getLen(); 8118ed49d2STom Eccles } else { 8218ed49d2STom Eccles if (!zero) 8318ed49d2STom Eccles zero = builder.createIntegerConstant(loc, idxTy, 0); 8418ed49d2STom Eccles buffer = zero; 8518ed49d2STom Eccles len = zero; 8618ed49d2STom Eccles } 8718ed49d2STom Eccles }; 8818ed49d2STom Eccles mlir::Value dateBuffer; 8918ed49d2STom Eccles mlir::Value dateLen; 9018ed49d2STom Eccles splitArg(date, dateBuffer, dateLen); 9118ed49d2STom Eccles mlir::Value timeBuffer; 9218ed49d2STom Eccles mlir::Value timeLen; 9318ed49d2STom Eccles splitArg(time, timeBuffer, timeLen); 9418ed49d2STom Eccles mlir::Value zoneBuffer; 9518ed49d2STom Eccles mlir::Value zoneLen; 9618ed49d2STom Eccles splitArg(zone, zoneBuffer, zoneLen); 9718ed49d2STom Eccles 9818ed49d2STom Eccles mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc); 9918ed49d2STom Eccles mlir::Value sourceLine = 10018ed49d2STom Eccles fir::factory::locationToLineNo(builder, loc, funcTy.getInput(7)); 10118ed49d2STom Eccles 10218ed49d2STom Eccles llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 10318ed49d2STom Eccles builder, loc, funcTy, dateBuffer, dateLen, timeBuffer, timeLen, 10418ed49d2STom Eccles zoneBuffer, zoneLen, sourceFile, sourceLine, values); 10518ed49d2STom Eccles builder.create<fir::CallOp>(loc, callee, args); 10618ed49d2STom Eccles } 10718ed49d2STom Eccles 108dc8d70acSjiajie zhang void fir::runtime::genEtime(fir::FirOpBuilder &builder, mlir::Location loc, 109dc8d70acSjiajie zhang mlir::Value values, mlir::Value time) { 110dc8d70acSjiajie zhang auto runtimeFunc = fir::runtime::getRuntimeFunc<mkRTKey(Etime)>(loc, builder); 111dc8d70acSjiajie zhang mlir::FunctionType runtimeFuncTy = runtimeFunc.getFunctionType(); 112dc8d70acSjiajie zhang 113dc8d70acSjiajie zhang mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc); 114dc8d70acSjiajie zhang mlir::Value sourceLine = 115dc8d70acSjiajie zhang fir::factory::locationToLineNo(builder, loc, runtimeFuncTy.getInput(3)); 116dc8d70acSjiajie zhang 117dc8d70acSjiajie zhang llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 118dc8d70acSjiajie zhang builder, loc, runtimeFuncTy, values, time, sourceFile, sourceLine); 119dc8d70acSjiajie zhang builder.create<fir::CallOp>(loc, runtimeFunc, args); 120dc8d70acSjiajie zhang } 121dc8d70acSjiajie zhang 12278ccffc0SDavid Truby void fir::runtime::genFree(fir::FirOpBuilder &builder, mlir::Location loc, 12378ccffc0SDavid Truby mlir::Value ptr) { 12478ccffc0SDavid Truby auto runtimeFunc = fir::runtime::getRuntimeFunc<mkRTKey(Free)>(loc, builder); 12578ccffc0SDavid Truby mlir::Type intPtrTy = builder.getIntPtrType(); 12678ccffc0SDavid Truby 12778ccffc0SDavid Truby builder.create<fir::CallOp>(loc, runtimeFunc, 12878ccffc0SDavid Truby builder.createConvert(loc, intPtrTy, ptr)); 12978ccffc0SDavid Truby } 13078ccffc0SDavid Truby 131856c38d5SDavid Truby mlir::Value fir::runtime::genGetGID(fir::FirOpBuilder &builder, 132856c38d5SDavid Truby mlir::Location loc) { 133856c38d5SDavid Truby auto runtimeFunc = 134856c38d5SDavid Truby fir::runtime::getRuntimeFunc<mkRTKey(GetGID)>(loc, builder); 135856c38d5SDavid Truby 136856c38d5SDavid Truby return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0); 137856c38d5SDavid Truby } 138856c38d5SDavid Truby 139856c38d5SDavid Truby mlir::Value fir::runtime::genGetUID(fir::FirOpBuilder &builder, 140856c38d5SDavid Truby mlir::Location loc) { 141856c38d5SDavid Truby auto runtimeFunc = 142856c38d5SDavid Truby fir::runtime::getRuntimeFunc<mkRTKey(GetUID)>(loc, builder); 143856c38d5SDavid Truby 144856c38d5SDavid Truby return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0); 145856c38d5SDavid Truby } 146856c38d5SDavid Truby 14778ccffc0SDavid Truby mlir::Value fir::runtime::genMalloc(fir::FirOpBuilder &builder, 14878ccffc0SDavid Truby mlir::Location loc, mlir::Value size) { 14978ccffc0SDavid Truby auto runtimeFunc = 15078ccffc0SDavid Truby fir::runtime::getRuntimeFunc<mkRTKey(Malloc)>(loc, builder); 15178ccffc0SDavid Truby auto argTy = runtimeFunc.getArgumentTypes()[0]; 15278ccffc0SDavid Truby return builder 15378ccffc0SDavid Truby .create<fir::CallOp>(loc, runtimeFunc, 15478ccffc0SDavid Truby builder.createConvert(loc, argTy, size)) 15578ccffc0SDavid Truby .getResult(0); 15678ccffc0SDavid Truby } 15778ccffc0SDavid Truby 15818ed49d2STom Eccles void fir::runtime::genRandomInit(fir::FirOpBuilder &builder, mlir::Location loc, 15918ed49d2STom Eccles mlir::Value repeatable, 16018ed49d2STom Eccles mlir::Value imageDistinct) { 16118ed49d2STom Eccles mlir::func::FuncOp func = 16218ed49d2STom Eccles fir::runtime::getRuntimeFunc<mkRTKey(RandomInit)>(loc, builder); 16318ed49d2STom Eccles llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 16418ed49d2STom Eccles builder, loc, func.getFunctionType(), repeatable, imageDistinct); 16518ed49d2STom Eccles builder.create<fir::CallOp>(loc, func, args); 16618ed49d2STom Eccles } 16718ed49d2STom Eccles 16818ed49d2STom Eccles void fir::runtime::genRandomNumber(fir::FirOpBuilder &builder, 16918ed49d2STom Eccles mlir::Location loc, mlir::Value harvest) { 170e0738cc6SSlava Zakharin mlir::func::FuncOp func; 171e0738cc6SSlava Zakharin auto boxEleTy = fir::dyn_cast_ptrOrBoxEleTy(harvest.getType()); 172e0738cc6SSlava Zakharin auto eleTy = fir::unwrapSequenceType(boxEleTy); 173e0738cc6SSlava Zakharin if (eleTy.isF128()) { 174e0738cc6SSlava Zakharin func = fir::runtime::getRuntimeFunc<ForcedRandomNumberReal16>(loc, builder); 175e0738cc6SSlava Zakharin } else { 176e0738cc6SSlava Zakharin func = fir::runtime::getRuntimeFunc<mkRTKey(RandomNumber)>(loc, builder); 177e0738cc6SSlava Zakharin } 178e0738cc6SSlava Zakharin 17918ed49d2STom Eccles mlir::FunctionType funcTy = func.getFunctionType(); 18018ed49d2STom Eccles mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc); 18118ed49d2STom Eccles mlir::Value sourceLine = 18218ed49d2STom Eccles fir::factory::locationToLineNo(builder, loc, funcTy.getInput(2)); 18318ed49d2STom Eccles llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 18418ed49d2STom Eccles builder, loc, funcTy, harvest, sourceFile, sourceLine); 18518ed49d2STom Eccles builder.create<fir::CallOp>(loc, func, args); 18618ed49d2STom Eccles } 18718ed49d2STom Eccles 18818ed49d2STom Eccles void fir::runtime::genRandomSeed(fir::FirOpBuilder &builder, mlir::Location loc, 18918ed49d2STom Eccles mlir::Value size, mlir::Value put, 19018ed49d2STom Eccles mlir::Value get) { 19118ed49d2STom Eccles bool sizeIsPresent = 19218ed49d2STom Eccles !mlir::isa_and_nonnull<fir::AbsentOp>(size.getDefiningOp()); 19318ed49d2STom Eccles bool putIsPresent = 19418ed49d2STom Eccles !mlir::isa_and_nonnull<fir::AbsentOp>(put.getDefiningOp()); 19518ed49d2STom Eccles bool getIsPresent = 19618ed49d2STom Eccles !mlir::isa_and_nonnull<fir::AbsentOp>(get.getDefiningOp()); 19718ed49d2STom Eccles mlir::func::FuncOp func; 19818ed49d2STom Eccles int staticArgCount = sizeIsPresent + putIsPresent + getIsPresent; 19918ed49d2STom Eccles if (staticArgCount == 0) { 20018ed49d2STom Eccles func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedDefaultPut)>(loc, 20118ed49d2STom Eccles builder); 20218ed49d2STom Eccles builder.create<fir::CallOp>(loc, func); 20318ed49d2STom Eccles return; 20418ed49d2STom Eccles } 20518ed49d2STom Eccles mlir::FunctionType funcTy; 20618ed49d2STom Eccles mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc); 20718ed49d2STom Eccles mlir::Value sourceLine; 20818ed49d2STom Eccles mlir::Value argBox; 20918ed49d2STom Eccles llvm::SmallVector<mlir::Value> args; 21018ed49d2STom Eccles if (staticArgCount > 1) { 21118ed49d2STom Eccles func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeed)>(loc, builder); 21218ed49d2STom Eccles funcTy = func.getFunctionType(); 21318ed49d2STom Eccles sourceLine = 21418ed49d2STom Eccles fir::factory::locationToLineNo(builder, loc, funcTy.getInput(4)); 21518ed49d2STom Eccles args = fir::runtime::createArguments(builder, loc, funcTy, size, put, get, 21618ed49d2STom Eccles sourceFile, sourceLine); 21718ed49d2STom Eccles builder.create<fir::CallOp>(loc, func, args); 21818ed49d2STom Eccles return; 21918ed49d2STom Eccles } 22018ed49d2STom Eccles if (sizeIsPresent) { 22118ed49d2STom Eccles func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedSize)>(loc, builder); 22218ed49d2STom Eccles argBox = size; 22318ed49d2STom Eccles } else if (putIsPresent) { 22418ed49d2STom Eccles func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedPut)>(loc, builder); 22518ed49d2STom Eccles argBox = put; 22618ed49d2STom Eccles } else { 22718ed49d2STom Eccles func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedGet)>(loc, builder); 22818ed49d2STom Eccles argBox = get; 22918ed49d2STom Eccles } 23018ed49d2STom Eccles funcTy = func.getFunctionType(); 23118ed49d2STom Eccles sourceLine = fir::factory::locationToLineNo(builder, loc, funcTy.getInput(2)); 23218ed49d2STom Eccles args = fir::runtime::createArguments(builder, loc, funcTy, argBox, sourceFile, 23318ed49d2STom Eccles sourceLine); 23418ed49d2STom Eccles builder.create<fir::CallOp>(loc, func, args); 23518ed49d2STom Eccles } 23618ed49d2STom Eccles 237a5a29a26SMichael Klemm /// generate rename runtime call 238a5a29a26SMichael Klemm void fir::runtime::genRename(fir::FirOpBuilder &builder, mlir::Location loc, 239a5a29a26SMichael Klemm mlir::Value path1, mlir::Value path2, 240a5a29a26SMichael Klemm mlir::Value status) { 241a5a29a26SMichael Klemm auto runtimeFunc = 242a5a29a26SMichael Klemm fir::runtime::getRuntimeFunc<mkRTKey(Rename)>(loc, builder); 243a5a29a26SMichael Klemm mlir::FunctionType runtimeFuncTy = runtimeFunc.getFunctionType(); 244a5a29a26SMichael Klemm 245a5a29a26SMichael Klemm mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc); 246a5a29a26SMichael Klemm mlir::Value sourceLine = 247a5a29a26SMichael Klemm fir::factory::locationToLineNo(builder, loc, runtimeFuncTy.getInput(4)); 248a5a29a26SMichael Klemm 249a5a29a26SMichael Klemm llvm::SmallVector<mlir::Value> args = 250a5a29a26SMichael Klemm fir::runtime::createArguments(builder, loc, runtimeFuncTy, path1, path2, 251a5a29a26SMichael Klemm status, sourceFile, sourceLine); 252a5a29a26SMichael Klemm builder.create<fir::CallOp>(loc, runtimeFunc, args); 253a5a29a26SMichael Klemm } 254a5a29a26SMichael Klemm 25518ed49d2STom Eccles /// generate runtime call to transfer intrinsic with no size argument 25618ed49d2STom Eccles void fir::runtime::genTransfer(fir::FirOpBuilder &builder, mlir::Location loc, 25718ed49d2STom Eccles mlir::Value resultBox, mlir::Value sourceBox, 25818ed49d2STom Eccles mlir::Value moldBox) { 25918ed49d2STom Eccles 26018ed49d2STom Eccles mlir::func::FuncOp func = 26118ed49d2STom Eccles fir::runtime::getRuntimeFunc<mkRTKey(Transfer)>(loc, builder); 26218ed49d2STom Eccles mlir::FunctionType fTy = func.getFunctionType(); 26318ed49d2STom Eccles mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc); 26418ed49d2STom Eccles mlir::Value sourceLine = 26518ed49d2STom Eccles fir::factory::locationToLineNo(builder, loc, fTy.getInput(4)); 26618ed49d2STom Eccles llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 26718ed49d2STom Eccles builder, loc, fTy, resultBox, sourceBox, moldBox, sourceFile, sourceLine); 26818ed49d2STom Eccles builder.create<fir::CallOp>(loc, func, args); 26918ed49d2STom Eccles } 27018ed49d2STom Eccles 27118ed49d2STom Eccles /// generate runtime call to transfer intrinsic with size argument 27218ed49d2STom Eccles void fir::runtime::genTransferSize(fir::FirOpBuilder &builder, 27318ed49d2STom Eccles mlir::Location loc, mlir::Value resultBox, 27418ed49d2STom Eccles mlir::Value sourceBox, mlir::Value moldBox, 27518ed49d2STom Eccles mlir::Value size) { 27618ed49d2STom Eccles mlir::func::FuncOp func = 27718ed49d2STom Eccles fir::runtime::getRuntimeFunc<mkRTKey(TransferSize)>(loc, builder); 27818ed49d2STom Eccles mlir::FunctionType fTy = func.getFunctionType(); 27918ed49d2STom Eccles mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc); 28018ed49d2STom Eccles mlir::Value sourceLine = 28118ed49d2STom Eccles fir::factory::locationToLineNo(builder, loc, fTy.getInput(4)); 28218ed49d2STom Eccles llvm::SmallVector<mlir::Value> args = 28318ed49d2STom Eccles fir::runtime::createArguments(builder, loc, fTy, resultBox, sourceBox, 28418ed49d2STom Eccles moldBox, sourceFile, sourceLine, size); 28518ed49d2STom Eccles builder.create<fir::CallOp>(loc, func, args); 28618ed49d2STom Eccles } 28718ed49d2STom Eccles 28818ed49d2STom Eccles /// generate system_clock runtime call/s 28918ed49d2STom Eccles /// all intrinsic arguments are optional and may appear here as mlir::Value{} 29018ed49d2STom Eccles void fir::runtime::genSystemClock(fir::FirOpBuilder &builder, 29118ed49d2STom Eccles mlir::Location loc, mlir::Value count, 29218ed49d2STom Eccles mlir::Value rate, mlir::Value max) { 29318ed49d2STom Eccles auto makeCall = [&](mlir::func::FuncOp func, mlir::Value arg) { 29418ed49d2STom Eccles mlir::Type type = arg.getType(); 29518ed49d2STom Eccles fir::IfOp ifOp{}; 29618ed49d2STom Eccles const bool isOptionalArg = 29718ed49d2STom Eccles fir::valueHasFirAttribute(arg, fir::getOptionalAttrName()); 298fac349a1SChristian Sigg if (mlir::dyn_cast<fir::PointerType>(type) || 299fac349a1SChristian Sigg mlir::dyn_cast<fir::HeapType>(type)) { 30018ed49d2STom Eccles // Check for a disassociated pointer or an unallocated allocatable. 30118ed49d2STom Eccles assert(!isOptionalArg && "invalid optional argument"); 30218ed49d2STom Eccles ifOp = builder.create<fir::IfOp>(loc, builder.genIsNotNullAddr(loc, arg), 30318ed49d2STom Eccles /*withElseRegion=*/false); 30418ed49d2STom Eccles } else if (isOptionalArg) { 30518ed49d2STom Eccles ifOp = builder.create<fir::IfOp>( 30618ed49d2STom Eccles loc, builder.create<fir::IsPresentOp>(loc, builder.getI1Type(), arg), 30718ed49d2STom Eccles /*withElseRegion=*/false); 30818ed49d2STom Eccles } 30918ed49d2STom Eccles if (ifOp) 31018ed49d2STom Eccles builder.setInsertionPointToStart(&ifOp.getThenRegion().front()); 31118ed49d2STom Eccles mlir::Type kindTy = func.getFunctionType().getInput(0); 31218ed49d2STom Eccles int integerKind = 8; 313fac349a1SChristian Sigg if (auto intType = 314fac349a1SChristian Sigg mlir::dyn_cast<mlir::IntegerType>(fir::unwrapRefType(type))) 31518ed49d2STom Eccles integerKind = intType.getWidth() / 8; 31618ed49d2STom Eccles mlir::Value kind = builder.createIntegerConstant(loc, kindTy, integerKind); 31718ed49d2STom Eccles mlir::Value res = 31818ed49d2STom Eccles builder.create<fir::CallOp>(loc, func, mlir::ValueRange{kind}) 31918ed49d2STom Eccles .getResult(0); 32018ed49d2STom Eccles mlir::Value castRes = 32118ed49d2STom Eccles builder.createConvert(loc, fir::dyn_cast_ptrEleTy(type), res); 32218ed49d2STom Eccles builder.create<fir::StoreOp>(loc, castRes, arg); 32318ed49d2STom Eccles if (ifOp) 32418ed49d2STom Eccles builder.setInsertionPointAfter(ifOp); 32518ed49d2STom Eccles }; 32618ed49d2STom Eccles using fir::runtime::getRuntimeFunc; 32718ed49d2STom Eccles if (count) 32818ed49d2STom Eccles makeCall(getRuntimeFunc<mkRTKey(SystemClockCount)>(loc, builder), count); 32918ed49d2STom Eccles if (rate) 33018ed49d2STom Eccles makeCall(getRuntimeFunc<mkRTKey(SystemClockCountRate)>(loc, builder), rate); 33118ed49d2STom Eccles if (max) 33218ed49d2STom Eccles makeCall(getRuntimeFunc<mkRTKey(SystemClockCountMax)>(loc, builder), max); 33318ed49d2STom Eccles } 334b64c26f3STom Eccles 335afa52de9STom Eccles // CALL SIGNAL(NUMBER, HANDLER [, STATUS]) 336afa52de9STom Eccles // The definition of the SIGNAL intrinsic allows HANDLER to be a function 337afa52de9STom Eccles // pointer or an integer. STATUS can be dynamically optional 338afa52de9STom Eccles void fir::runtime::genSignal(fir::FirOpBuilder &builder, mlir::Location loc, 339afa52de9STom Eccles mlir::Value number, mlir::Value handler, 340afa52de9STom Eccles mlir::Value status) { 341afa52de9STom Eccles assert(mlir::isa<mlir::IntegerType>(number.getType())); 342afa52de9STom Eccles mlir::Type int64 = builder.getIntegerType(64); 343afa52de9STom Eccles number = builder.create<fir::ConvertOp>(loc, int64, number); 344afa52de9STom Eccles 345afa52de9STom Eccles mlir::Type handlerUnwrappedTy = fir::unwrapRefType(handler.getType()); 346afa52de9STom Eccles if (mlir::isa_and_nonnull<mlir::IntegerType>(handlerUnwrappedTy)) { 347afa52de9STom Eccles // pass the integer as a function pointer like one would to signal(2) 348afa52de9STom Eccles handler = builder.create<fir::LoadOp>(loc, handler); 349afa52de9STom Eccles mlir::Type fnPtrTy = fir::LLVMPointerType::get( 350afa52de9STom Eccles mlir::FunctionType::get(handler.getContext(), {}, {})); 351afa52de9STom Eccles handler = builder.create<fir::ConvertOp>(loc, fnPtrTy, handler); 352afa52de9STom Eccles } else { 353afa52de9STom Eccles assert(mlir::isa<fir::BoxProcType>(handler.getType())); 354afa52de9STom Eccles handler = builder.create<fir::BoxAddrOp>(loc, handler); 355afa52de9STom Eccles } 356afa52de9STom Eccles 357afa52de9STom Eccles mlir::func::FuncOp func{ 358afa52de9STom Eccles fir::runtime::getRuntimeFunc<mkRTKey(Signal)>(loc, builder)}; 359afa52de9STom Eccles mlir::Value stat = 360afa52de9STom Eccles builder.create<fir::CallOp>(loc, func, mlir::ValueRange{number, handler}) 361afa52de9STom Eccles ->getResult(0); 362afa52de9STom Eccles 363afa52de9STom Eccles // return status code via status argument (if present) 364afa52de9STom Eccles if (status) { 365afa52de9STom Eccles assert(mlir::isa<mlir::IntegerType>(fir::unwrapRefType(status.getType()))); 366afa52de9STom Eccles // status might be dynamically optional, so test if it is present 367afa52de9STom Eccles mlir::Value isPresent = 368afa52de9STom Eccles builder.create<IsPresentOp>(loc, builder.getI1Type(), status); 369afa52de9STom Eccles builder.genIfOp(loc, /*results=*/{}, isPresent, /*withElseRegion=*/false) 370afa52de9STom Eccles .genThen([&]() { 371afa52de9STom Eccles stat = builder.create<fir::ConvertOp>( 372afa52de9STom Eccles loc, fir::unwrapRefType(status.getType()), stat); 373afa52de9STom Eccles builder.create<fir::StoreOp>(loc, stat, status); 374afa52de9STom Eccles }) 375afa52de9STom Eccles .end(); 376afa52de9STom Eccles } 377afa52de9STom Eccles } 378afa52de9STom Eccles 379b64c26f3STom Eccles void fir::runtime::genSleep(fir::FirOpBuilder &builder, mlir::Location loc, 380b64c26f3STom Eccles mlir::Value seconds) { 381b64c26f3STom Eccles mlir::Type int64 = builder.getIntegerType(64); 382b64c26f3STom Eccles seconds = builder.create<fir::ConvertOp>(loc, int64, seconds); 383b64c26f3STom Eccles mlir::func::FuncOp func{ 384b64c26f3STom Eccles fir::runtime::getRuntimeFunc<mkRTKey(Sleep)>(loc, builder)}; 385b64c26f3STom Eccles builder.create<fir::CallOp>(loc, func, seconds); 386b64c26f3STom Eccles } 387*5a34e6fdSJean-Didier PAILLEUX 388*5a34e6fdSJean-Didier PAILLEUX /// generate chdir runtime call 389*5a34e6fdSJean-Didier PAILLEUX mlir::Value fir::runtime::genChdir(fir::FirOpBuilder &builder, 390*5a34e6fdSJean-Didier PAILLEUX mlir::Location loc, mlir::Value name) { 391*5a34e6fdSJean-Didier PAILLEUX mlir::func::FuncOp func{ 392*5a34e6fdSJean-Didier PAILLEUX fir::runtime::getRuntimeFunc<mkRTKey(Chdir)>(loc, builder)}; 393*5a34e6fdSJean-Didier PAILLEUX llvm::SmallVector<mlir::Value> args = 394*5a34e6fdSJean-Didier PAILLEUX fir::runtime::createArguments(builder, loc, func.getFunctionType(), name); 395*5a34e6fdSJean-Didier PAILLEUX return builder.create<fir::CallOp>(loc, func, args).getResult(0); 396*5a34e6fdSJean-Didier PAILLEUX } 397