1aab4263aSValentin Clement //===-- Runtime.cpp -------------------------------------------------------===// 2aab4263aSValentin Clement // 3aab4263aSValentin Clement // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4aab4263aSValentin Clement // See https://llvm.org/LICENSE.txt for license information. 5aab4263aSValentin Clement // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6aab4263aSValentin Clement // 7aab4263aSValentin Clement //===----------------------------------------------------------------------===// 8aab4263aSValentin Clement 9aab4263aSValentin Clement #include "flang/Lower/Runtime.h" 10aab4263aSValentin Clement #include "flang/Lower/Bridge.h" 11d0b70a07SValentin Clement #include "flang/Lower/StatementContext.h" 12aab4263aSValentin Clement #include "flang/Lower/Todo.h" 13aab4263aSValentin Clement #include "flang/Optimizer/Builder/FIRBuilder.h" 14aab4263aSValentin Clement #include "flang/Optimizer/Builder/Runtime/RTBuilder.h" 15aab4263aSValentin Clement #include "flang/Parser/parse-tree.h" 16a16eddb2SValentin Clement #include "flang/Runtime/misc-intrinsic.h" 1772276bdaSValentin Clement #include "flang/Runtime/pointer.h" 18a1918fdfSValentin Clement #include "flang/Runtime/random.h" 19aab4263aSValentin Clement #include "flang/Runtime/stop.h" 209daf5765SValentin Clement #include "flang/Runtime/time-intrinsic.h" 21aab4263aSValentin Clement #include "flang/Semantics/tools.h" 22aab4263aSValentin Clement #include "llvm/Support/Debug.h" 23aab4263aSValentin Clement 24aab4263aSValentin Clement #define DEBUG_TYPE "flang-lower-runtime" 25aab4263aSValentin Clement 26aab4263aSValentin Clement using namespace Fortran::runtime; 27aab4263aSValentin Clement 28aab4263aSValentin Clement /// Runtime calls that do not return to the caller indicate this condition by 29aab4263aSValentin Clement /// terminating the current basic block with an unreachable op. 30aab4263aSValentin Clement static void genUnreachable(fir::FirOpBuilder &builder, mlir::Location loc) { 31aab4263aSValentin Clement builder.create<fir::UnreachableOp>(loc); 32aab4263aSValentin Clement mlir::Block *newBlock = 33aab4263aSValentin Clement builder.getBlock()->splitBlock(builder.getInsertionPoint()); 34aab4263aSValentin Clement builder.setInsertionPointToStart(newBlock); 35aab4263aSValentin Clement } 36aab4263aSValentin Clement 37aab4263aSValentin Clement //===----------------------------------------------------------------------===// 38aab4263aSValentin Clement // Misc. Fortran statements that lower to runtime calls 39aab4263aSValentin Clement //===----------------------------------------------------------------------===// 40aab4263aSValentin Clement 41aab4263aSValentin Clement void Fortran::lower::genStopStatement( 42aab4263aSValentin Clement Fortran::lower::AbstractConverter &converter, 43aab4263aSValentin Clement const Fortran::parser::StopStmt &stmt) { 44aab4263aSValentin Clement fir::FirOpBuilder &builder = converter.getFirOpBuilder(); 45aab4263aSValentin Clement mlir::Location loc = converter.getCurrentLocation(); 46d0b70a07SValentin Clement Fortran::lower::StatementContext stmtCtx; 47aab4263aSValentin Clement llvm::SmallVector<mlir::Value> operands; 48aab4263aSValentin Clement mlir::FuncOp callee; 49aab4263aSValentin Clement mlir::FunctionType calleeType; 50aab4263aSValentin Clement // First operand is stop code (zero if absent) 51ca53e049SValentin Clement if (const auto &code = 52ca53e049SValentin Clement std::get<std::optional<Fortran::parser::StopCode>>(stmt.t)) { 53d0b70a07SValentin Clement auto expr = 54d0b70a07SValentin Clement converter.genExprValue(*Fortran::semantics::GetExpr(*code), stmtCtx); 55ca53e049SValentin Clement LLVM_DEBUG(llvm::dbgs() << "stop expression: "; expr.dump(); 56ca53e049SValentin Clement llvm::dbgs() << '\n'); 57ca53e049SValentin Clement expr.match( 58ca53e049SValentin Clement [&](const fir::CharBoxValue &x) { 59a8d48fe0SValentin Clement callee = fir::runtime::getRuntimeFunc<mkRTKey(StopStatementText)>( 60a8d48fe0SValentin Clement loc, builder); 614a3460a7SRiver Riddle calleeType = callee.getFunctionType(); 62a8d48fe0SValentin Clement // Creates a pair of operands for the CHARACTER and its LEN. 63a8d48fe0SValentin Clement operands.push_back( 64a8d48fe0SValentin Clement builder.createConvert(loc, calleeType.getInput(0), x.getAddr())); 65a8d48fe0SValentin Clement operands.push_back( 66a8d48fe0SValentin Clement builder.createConvert(loc, calleeType.getInput(1), x.getLen())); 67ca53e049SValentin Clement }, 68ca53e049SValentin Clement [&](fir::UnboxedValue x) { 69ca53e049SValentin Clement callee = fir::runtime::getRuntimeFunc<mkRTKey(StopStatement)>( 70ca53e049SValentin Clement loc, builder); 714a3460a7SRiver Riddle calleeType = callee.getFunctionType(); 72ca53e049SValentin Clement mlir::Value cast = 73ca53e049SValentin Clement builder.createConvert(loc, calleeType.getInput(0), x); 74ca53e049SValentin Clement operands.push_back(cast); 75ca53e049SValentin Clement }, 76ca53e049SValentin Clement [&](auto) { 77ca53e049SValentin Clement mlir::emitError(loc, "unhandled expression in STOP"); 78ca53e049SValentin Clement std::exit(1); 79ca53e049SValentin Clement }); 80aab4263aSValentin Clement } else { 81aab4263aSValentin Clement callee = fir::runtime::getRuntimeFunc<mkRTKey(StopStatement)>(loc, builder); 824a3460a7SRiver Riddle calleeType = callee.getFunctionType(); 83aab4263aSValentin Clement operands.push_back( 84aab4263aSValentin Clement builder.createIntegerConstant(loc, calleeType.getInput(0), 0)); 85aab4263aSValentin Clement } 86aab4263aSValentin Clement 87aab4263aSValentin Clement // Second operand indicates ERROR STOP 88aab4263aSValentin Clement bool isError = std::get<Fortran::parser::StopStmt::Kind>(stmt.t) == 89aab4263aSValentin Clement Fortran::parser::StopStmt::Kind::ErrorStop; 90aab4263aSValentin Clement operands.push_back(builder.createIntegerConstant( 91aab4263aSValentin Clement loc, calleeType.getInput(operands.size()), isError)); 92aab4263aSValentin Clement 93aab4263aSValentin Clement // Third operand indicates QUIET (default to false). 94cc306740SValentin Clement if (const auto &quiet = 95cc306740SValentin Clement std::get<std::optional<Fortran::parser::ScalarLogicalExpr>>(stmt.t)) { 96cc306740SValentin Clement const SomeExpr *expr = Fortran::semantics::GetExpr(*quiet); 97cc306740SValentin Clement assert(expr && "failed getting typed expression"); 98d0b70a07SValentin Clement mlir::Value q = fir::getBase(converter.genExprValue(*expr, stmtCtx)); 99cc306740SValentin Clement operands.push_back( 100cc306740SValentin Clement builder.createConvert(loc, calleeType.getInput(operands.size()), q)); 101aab4263aSValentin Clement } else { 102aab4263aSValentin Clement operands.push_back(builder.createIntegerConstant( 103aab4263aSValentin Clement loc, calleeType.getInput(operands.size()), 0)); 104aab4263aSValentin Clement } 105aab4263aSValentin Clement 106aab4263aSValentin Clement builder.create<fir::CallOp>(loc, callee, operands); 107aab4263aSValentin Clement genUnreachable(builder, loc); 108aab4263aSValentin Clement } 109db01b123SValentin Clement 110*534b2283SValentin Clement void Fortran::lower::genFailImageStatement( 111*534b2283SValentin Clement Fortran::lower::AbstractConverter &converter) { 112*534b2283SValentin Clement fir::FirOpBuilder &builder = converter.getFirOpBuilder(); 113*534b2283SValentin Clement mlir::Location loc = converter.getCurrentLocation(); 114*534b2283SValentin Clement mlir::FuncOp callee = 115*534b2283SValentin Clement fir::runtime::getRuntimeFunc<mkRTKey(FailImageStatement)>(loc, builder); 116*534b2283SValentin Clement builder.create<fir::CallOp>(loc, callee, llvm::None); 117*534b2283SValentin Clement genUnreachable(builder, loc); 118*534b2283SValentin Clement } 119*534b2283SValentin Clement 120*534b2283SValentin Clement void Fortran::lower::genEventPostStatement( 121*534b2283SValentin Clement Fortran::lower::AbstractConverter &converter, 122*534b2283SValentin Clement const Fortran::parser::EventPostStmt &) { 123*534b2283SValentin Clement TODO(converter.getCurrentLocation(), "EVENT POST runtime"); 124*534b2283SValentin Clement } 125*534b2283SValentin Clement 126*534b2283SValentin Clement void Fortran::lower::genEventWaitStatement( 127*534b2283SValentin Clement Fortran::lower::AbstractConverter &converter, 128*534b2283SValentin Clement const Fortran::parser::EventWaitStmt &) { 129*534b2283SValentin Clement TODO(converter.getCurrentLocation(), "EVENT WAIT runtime"); 130*534b2283SValentin Clement } 131*534b2283SValentin Clement 132*534b2283SValentin Clement void Fortran::lower::genLockStatement( 133*534b2283SValentin Clement Fortran::lower::AbstractConverter &converter, 134*534b2283SValentin Clement const Fortran::parser::LockStmt &) { 135*534b2283SValentin Clement TODO(converter.getCurrentLocation(), "LOCK runtime"); 136*534b2283SValentin Clement } 137*534b2283SValentin Clement 138*534b2283SValentin Clement void Fortran::lower::genUnlockStatement( 139*534b2283SValentin Clement Fortran::lower::AbstractConverter &converter, 140*534b2283SValentin Clement const Fortran::parser::UnlockStmt &) { 141*534b2283SValentin Clement TODO(converter.getCurrentLocation(), "UNLOCK runtime"); 142*534b2283SValentin Clement } 143*534b2283SValentin Clement 144*534b2283SValentin Clement void Fortran::lower::genSyncAllStatement( 145*534b2283SValentin Clement Fortran::lower::AbstractConverter &converter, 146*534b2283SValentin Clement const Fortran::parser::SyncAllStmt &) { 147*534b2283SValentin Clement TODO(converter.getCurrentLocation(), "SYNC ALL runtime"); 148*534b2283SValentin Clement } 149*534b2283SValentin Clement 150*534b2283SValentin Clement void Fortran::lower::genSyncImagesStatement( 151*534b2283SValentin Clement Fortran::lower::AbstractConverter &converter, 152*534b2283SValentin Clement const Fortran::parser::SyncImagesStmt &) { 153*534b2283SValentin Clement TODO(converter.getCurrentLocation(), "SYNC IMAGES runtime"); 154*534b2283SValentin Clement } 155*534b2283SValentin Clement 156*534b2283SValentin Clement void Fortran::lower::genSyncMemoryStatement( 157*534b2283SValentin Clement Fortran::lower::AbstractConverter &converter, 158*534b2283SValentin Clement const Fortran::parser::SyncMemoryStmt &) { 159*534b2283SValentin Clement TODO(converter.getCurrentLocation(), "SYNC MEMORY runtime"); 160*534b2283SValentin Clement } 161*534b2283SValentin Clement 162*534b2283SValentin Clement void Fortran::lower::genSyncTeamStatement( 163*534b2283SValentin Clement Fortran::lower::AbstractConverter &converter, 164*534b2283SValentin Clement const Fortran::parser::SyncTeamStmt &) { 165*534b2283SValentin Clement TODO(converter.getCurrentLocation(), "SYNC TEAM runtime"); 166*534b2283SValentin Clement } 167*534b2283SValentin Clement 168db01b123SValentin Clement void Fortran::lower::genPauseStatement( 169db01b123SValentin Clement Fortran::lower::AbstractConverter &converter, 170db01b123SValentin Clement const Fortran::parser::PauseStmt &) { 171db01b123SValentin Clement fir::FirOpBuilder &builder = converter.getFirOpBuilder(); 172db01b123SValentin Clement mlir::Location loc = converter.getCurrentLocation(); 173db01b123SValentin Clement mlir::FuncOp callee = 174db01b123SValentin Clement fir::runtime::getRuntimeFunc<mkRTKey(PauseStatement)>(loc, builder); 175db01b123SValentin Clement builder.create<fir::CallOp>(loc, callee, llvm::None); 176db01b123SValentin Clement } 17772276bdaSValentin Clement 17872276bdaSValentin Clement mlir::Value Fortran::lower::genAssociated(fir::FirOpBuilder &builder, 17972276bdaSValentin Clement mlir::Location loc, 18072276bdaSValentin Clement mlir::Value pointer, 18172276bdaSValentin Clement mlir::Value target) { 18272276bdaSValentin Clement mlir::FuncOp func = 18372276bdaSValentin Clement fir::runtime::getRuntimeFunc<mkRTKey(PointerIsAssociatedWith)>(loc, 18472276bdaSValentin Clement builder); 18572276bdaSValentin Clement llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 1864a3460a7SRiver Riddle builder, loc, func.getFunctionType(), pointer, target); 18772276bdaSValentin Clement return builder.create<fir::CallOp>(loc, func, args).getResult(0); 18872276bdaSValentin Clement } 189a1918fdfSValentin Clement 1909daf5765SValentin Clement mlir::Value Fortran::lower::genCpuTime(fir::FirOpBuilder &builder, 1919daf5765SValentin Clement mlir::Location loc) { 1929daf5765SValentin Clement mlir::FuncOp func = 1939daf5765SValentin Clement fir::runtime::getRuntimeFunc<mkRTKey(CpuTime)>(loc, builder); 1949daf5765SValentin Clement return builder.create<fir::CallOp>(loc, func, llvm::None).getResult(0); 1959daf5765SValentin Clement } 1969daf5765SValentin Clement 1979daf5765SValentin Clement void Fortran::lower::genDateAndTime(fir::FirOpBuilder &builder, 1989daf5765SValentin Clement mlir::Location loc, 1999daf5765SValentin Clement llvm::Optional<fir::CharBoxValue> date, 2009daf5765SValentin Clement llvm::Optional<fir::CharBoxValue> time, 2019daf5765SValentin Clement llvm::Optional<fir::CharBoxValue> zone, 2029daf5765SValentin Clement mlir::Value values) { 2039daf5765SValentin Clement mlir::FuncOp callee = 2049daf5765SValentin Clement fir::runtime::getRuntimeFunc<mkRTKey(DateAndTime)>(loc, builder); 2054a3460a7SRiver Riddle mlir::FunctionType funcTy = callee.getFunctionType(); 2069daf5765SValentin Clement mlir::Type idxTy = builder.getIndexType(); 2079daf5765SValentin Clement mlir::Value zero; 2089daf5765SValentin Clement auto splitArg = [&](llvm::Optional<fir::CharBoxValue> arg, 2099daf5765SValentin Clement mlir::Value &buffer, mlir::Value &len) { 2109daf5765SValentin Clement if (arg) { 2119daf5765SValentin Clement buffer = arg->getBuffer(); 2129daf5765SValentin Clement len = arg->getLen(); 2139daf5765SValentin Clement } else { 2149daf5765SValentin Clement if (!zero) 2159daf5765SValentin Clement zero = builder.createIntegerConstant(loc, idxTy, 0); 2169daf5765SValentin Clement buffer = zero; 2179daf5765SValentin Clement len = zero; 2189daf5765SValentin Clement } 2199daf5765SValentin Clement }; 2209daf5765SValentin Clement mlir::Value dateBuffer; 2219daf5765SValentin Clement mlir::Value dateLen; 2229daf5765SValentin Clement splitArg(date, dateBuffer, dateLen); 2239daf5765SValentin Clement mlir::Value timeBuffer; 2249daf5765SValentin Clement mlir::Value timeLen; 2259daf5765SValentin Clement splitArg(time, timeBuffer, timeLen); 2269daf5765SValentin Clement mlir::Value zoneBuffer; 2279daf5765SValentin Clement mlir::Value zoneLen; 2289daf5765SValentin Clement splitArg(zone, zoneBuffer, zoneLen); 2299daf5765SValentin Clement 2309daf5765SValentin Clement mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc); 2319daf5765SValentin Clement mlir::Value sourceLine = 2329daf5765SValentin Clement fir::factory::locationToLineNo(builder, loc, funcTy.getInput(7)); 2339daf5765SValentin Clement 2349daf5765SValentin Clement llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 2359daf5765SValentin Clement builder, loc, funcTy, dateBuffer, dateLen, timeBuffer, timeLen, 2369daf5765SValentin Clement zoneBuffer, zoneLen, sourceFile, sourceLine, values); 2379daf5765SValentin Clement builder.create<fir::CallOp>(loc, callee, args); 2389daf5765SValentin Clement } 2399daf5765SValentin Clement 240a1918fdfSValentin Clement void Fortran::lower::genRandomInit(fir::FirOpBuilder &builder, 241a1918fdfSValentin Clement mlir::Location loc, mlir::Value repeatable, 242a1918fdfSValentin Clement mlir::Value imageDistinct) { 243a1918fdfSValentin Clement mlir::FuncOp func = 244a1918fdfSValentin Clement fir::runtime::getRuntimeFunc<mkRTKey(RandomInit)>(loc, builder); 245a1918fdfSValentin Clement llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 2464a3460a7SRiver Riddle builder, loc, func.getFunctionType(), repeatable, imageDistinct); 247a1918fdfSValentin Clement builder.create<fir::CallOp>(loc, func, args); 248a1918fdfSValentin Clement } 249a1918fdfSValentin Clement 250a1918fdfSValentin Clement void Fortran::lower::genRandomNumber(fir::FirOpBuilder &builder, 251a1918fdfSValentin Clement mlir::Location loc, mlir::Value harvest) { 252a1918fdfSValentin Clement mlir::FuncOp func = 253a1918fdfSValentin Clement fir::runtime::getRuntimeFunc<mkRTKey(RandomNumber)>(loc, builder); 2544a3460a7SRiver Riddle mlir::FunctionType funcTy = func.getFunctionType(); 255a1918fdfSValentin Clement mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc); 256a1918fdfSValentin Clement mlir::Value sourceLine = 257a1918fdfSValentin Clement fir::factory::locationToLineNo(builder, loc, funcTy.getInput(2)); 258a1918fdfSValentin Clement llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 259a1918fdfSValentin Clement builder, loc, funcTy, harvest, sourceFile, sourceLine); 260a1918fdfSValentin Clement builder.create<fir::CallOp>(loc, func, args); 261a1918fdfSValentin Clement } 262a1918fdfSValentin Clement 263a1918fdfSValentin Clement void Fortran::lower::genRandomSeed(fir::FirOpBuilder &builder, 264a1918fdfSValentin Clement mlir::Location loc, int argIndex, 265a1918fdfSValentin Clement mlir::Value argBox) { 266a1918fdfSValentin Clement mlir::FuncOp func; 267a1918fdfSValentin Clement // argIndex is the nth (0-origin) argument in declaration order, 268a1918fdfSValentin Clement // or -1 if no argument is present. 269a1918fdfSValentin Clement switch (argIndex) { 270a1918fdfSValentin Clement case -1: 271a1918fdfSValentin Clement func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedDefaultPut)>(loc, 272a1918fdfSValentin Clement builder); 273a1918fdfSValentin Clement builder.create<fir::CallOp>(loc, func); 274a1918fdfSValentin Clement return; 275a1918fdfSValentin Clement case 0: 276a1918fdfSValentin Clement func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedSize)>(loc, builder); 277a1918fdfSValentin Clement break; 278a1918fdfSValentin Clement case 1: 279a1918fdfSValentin Clement func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedPut)>(loc, builder); 280a1918fdfSValentin Clement break; 281a1918fdfSValentin Clement case 2: 282a1918fdfSValentin Clement func = fir::runtime::getRuntimeFunc<mkRTKey(RandomSeedGet)>(loc, builder); 283a1918fdfSValentin Clement break; 284a1918fdfSValentin Clement default: 285a1918fdfSValentin Clement llvm::report_fatal_error("invalid RANDOM_SEED argument index"); 286a1918fdfSValentin Clement } 2874a3460a7SRiver Riddle mlir::FunctionType funcTy = func.getFunctionType(); 288a1918fdfSValentin Clement mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc); 289a1918fdfSValentin Clement mlir::Value sourceLine = 290a1918fdfSValentin Clement fir::factory::locationToLineNo(builder, loc, funcTy.getInput(2)); 291a1918fdfSValentin Clement llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 292a1918fdfSValentin Clement builder, loc, funcTy, argBox, sourceFile, sourceLine); 293a1918fdfSValentin Clement builder.create<fir::CallOp>(loc, func, args); 294a1918fdfSValentin Clement } 295264d9662SValentin Clement 296a16eddb2SValentin Clement /// generate runtime call to transfer intrinsic with no size argument 297a16eddb2SValentin Clement void Fortran::lower::genTransfer(fir::FirOpBuilder &builder, mlir::Location loc, 298a16eddb2SValentin Clement mlir::Value resultBox, mlir::Value sourceBox, 299a16eddb2SValentin Clement mlir::Value moldBox) { 300a16eddb2SValentin Clement 301a16eddb2SValentin Clement mlir::FuncOp func = 302a16eddb2SValentin Clement fir::runtime::getRuntimeFunc<mkRTKey(Transfer)>(loc, builder); 3034a3460a7SRiver Riddle mlir::FunctionType fTy = func.getFunctionType(); 304a16eddb2SValentin Clement mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc); 305a16eddb2SValentin Clement mlir::Value sourceLine = 306a16eddb2SValentin Clement fir::factory::locationToLineNo(builder, loc, fTy.getInput(4)); 307a16eddb2SValentin Clement llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 308a16eddb2SValentin Clement builder, loc, fTy, resultBox, sourceBox, moldBox, sourceFile, sourceLine); 309a16eddb2SValentin Clement builder.create<fir::CallOp>(loc, func, args); 310a16eddb2SValentin Clement } 311a16eddb2SValentin Clement 312a16eddb2SValentin Clement /// generate runtime call to transfer intrinsic with size argument 313a16eddb2SValentin Clement void Fortran::lower::genTransferSize(fir::FirOpBuilder &builder, 314a16eddb2SValentin Clement mlir::Location loc, mlir::Value resultBox, 315a16eddb2SValentin Clement mlir::Value sourceBox, mlir::Value moldBox, 316a16eddb2SValentin Clement mlir::Value size) { 317a16eddb2SValentin Clement mlir::FuncOp func = 318a16eddb2SValentin Clement fir::runtime::getRuntimeFunc<mkRTKey(TransferSize)>(loc, builder); 3194a3460a7SRiver Riddle mlir::FunctionType fTy = func.getFunctionType(); 320a16eddb2SValentin Clement mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc); 321a16eddb2SValentin Clement mlir::Value sourceLine = 322a16eddb2SValentin Clement fir::factory::locationToLineNo(builder, loc, fTy.getInput(4)); 323a16eddb2SValentin Clement llvm::SmallVector<mlir::Value> args = 324a16eddb2SValentin Clement fir::runtime::createArguments(builder, loc, fTy, resultBox, sourceBox, 325a16eddb2SValentin Clement moldBox, sourceFile, sourceLine, size); 326a16eddb2SValentin Clement builder.create<fir::CallOp>(loc, func, args); 327a16eddb2SValentin Clement } 328a16eddb2SValentin Clement 329264d9662SValentin Clement /// generate system_clock runtime call/s 330264d9662SValentin Clement /// all intrinsic arguments are optional and may appear here as mlir::Value{} 331264d9662SValentin Clement void Fortran::lower::genSystemClock(fir::FirOpBuilder &builder, 332264d9662SValentin Clement mlir::Location loc, mlir::Value count, 333264d9662SValentin Clement mlir::Value rate, mlir::Value max) { 334264d9662SValentin Clement auto makeCall = [&](mlir::FuncOp func, mlir::Value arg) { 3354a3460a7SRiver Riddle mlir::Type kindTy = func.getFunctionType().getInput(0); 336264d9662SValentin Clement int integerKind = 8; 337264d9662SValentin Clement if (auto intType = 338264d9662SValentin Clement fir::unwrapRefType(arg.getType()).dyn_cast<mlir::IntegerType>()) 339264d9662SValentin Clement integerKind = intType.getWidth() / 8; 340264d9662SValentin Clement mlir::Value kind = builder.createIntegerConstant(loc, kindTy, integerKind); 341264d9662SValentin Clement mlir::Value res = 342264d9662SValentin Clement builder.create<fir::CallOp>(loc, func, mlir::ValueRange{kind}) 343264d9662SValentin Clement .getResult(0); 344264d9662SValentin Clement mlir::Value castRes = 345264d9662SValentin Clement builder.createConvert(loc, fir::dyn_cast_ptrEleTy(arg.getType()), res); 346264d9662SValentin Clement builder.create<fir::StoreOp>(loc, castRes, arg); 347264d9662SValentin Clement }; 348264d9662SValentin Clement using fir::runtime::getRuntimeFunc; 349264d9662SValentin Clement if (count) 350264d9662SValentin Clement makeCall(getRuntimeFunc<mkRTKey(SystemClockCount)>(loc, builder), count); 351264d9662SValentin Clement if (rate) 352264d9662SValentin Clement makeCall(getRuntimeFunc<mkRTKey(SystemClockCountRate)>(loc, builder), rate); 353264d9662SValentin Clement if (max) 354264d9662SValentin Clement makeCall(getRuntimeFunc<mkRTKey(SystemClockCountMax)>(loc, builder), max); 355264d9662SValentin Clement } 356