1 //===-- Command.cpp -- generate command line runtime API calls ------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "flang/Optimizer/Builder/Runtime/Command.h" 10 #include "flang/Optimizer/Builder/FIRBuilder.h" 11 #include "flang/Optimizer/Builder/Runtime/RTBuilder.h" 12 #include "flang/Runtime/command.h" 13 14 using namespace Fortran::runtime; 15 16 mlir::Value fir::runtime::genCommandArgumentCount(fir::FirOpBuilder &builder, 17 mlir::Location loc) { 18 auto argumentCountFunc = 19 fir::runtime::getRuntimeFunc<mkRTKey(ArgumentCount)>(loc, builder); 20 return builder.create<fir::CallOp>(loc, argumentCountFunc).getResult(0); 21 } 22 23 void fir::runtime::genGetCommandArgument(fir::FirOpBuilder &builder, 24 mlir::Location loc, mlir::Value number, 25 mlir::Value value, mlir::Value length, 26 mlir::Value status, 27 mlir::Value errmsg) { 28 auto argumentValueFunc = 29 fir::runtime::getRuntimeFunc<mkRTKey(ArgumentValue)>(loc, builder); 30 auto argumentLengthFunc = 31 fir::runtime::getRuntimeFunc<mkRTKey(ArgumentLength)>(loc, builder); 32 33 auto isPresent = [&](mlir::Value val) -> bool { 34 return !mlir::isa_and_nonnull<fir::AbsentOp>(val.getDefiningOp()); 35 }; 36 37 mlir::Value valueResult; 38 // Run `ArgumentValue` intrisc only if we have either "value", "status" or 39 // "errmsg" `ArgumentValue` "requires" existing values for its arguments 40 // "value" and "errmsg". So in the case they aren't given, but the user has 41 // requested "status", we have to assign "absent" values to them before 42 // calling `ArgumentValue`. This happens in IntrinsicCall.cpp. For this reason 43 // we need extra indirection with `isPresent` for testing whether "value" or 44 // "errmsg" is present. 45 if (isPresent(value) || status || isPresent(errmsg)) { 46 llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 47 builder, loc, argumentValueFunc.getType(), number, value, errmsg); 48 valueResult = 49 builder.create<fir::CallOp>(loc, argumentValueFunc, args).getResult(0); 50 } 51 52 // Only save result of ArgumentValue if "status" parameter has been given 53 if (status) { 54 const mlir::Value statusLoaded = builder.create<fir::LoadOp>(loc, status); 55 mlir::Value resultCast = 56 builder.createConvert(loc, statusLoaded.getType(), valueResult); 57 builder.create<fir::StoreOp>(loc, resultCast, status); 58 } 59 60 if (length) { 61 llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments( 62 builder, loc, argumentLengthFunc.getType(), number); 63 mlir::Value result = 64 builder.create<fir::CallOp>(loc, argumentLengthFunc, args).getResult(0); 65 const mlir::Value valueLoaded = builder.create<fir::LoadOp>(loc, length); 66 mlir::Value resultCast = 67 builder.createConvert(loc, valueLoaded.getType(), result); 68 builder.create<fir::StoreOp>(loc, resultCast, length); 69 } 70 } 71