1ddac11aeSJosh Mottley //===-- Command.cpp -- generate command line runtime API calls ------------===//
2ddac11aeSJosh Mottley //
3ddac11aeSJosh Mottley // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ddac11aeSJosh Mottley // See https://llvm.org/LICENSE.txt for license information.
5ddac11aeSJosh Mottley // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ddac11aeSJosh Mottley //
7ddac11aeSJosh Mottley //===----------------------------------------------------------------------===//
8ddac11aeSJosh Mottley 
9ddac11aeSJosh Mottley #include "flang/Optimizer/Builder/Runtime/Command.h"
10ddac11aeSJosh Mottley #include "flang/Optimizer/Builder/FIRBuilder.h"
11ddac11aeSJosh Mottley #include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
12ddac11aeSJosh Mottley #include "flang/Runtime/command.h"
13ddac11aeSJosh Mottley 
14ddac11aeSJosh Mottley using namespace Fortran::runtime;
15ddac11aeSJosh Mottley 
165ebbcfa0SJosh Mottley // Certain runtime intrinsics should only be run when select parameters of the
175ebbcfa0SJosh Mottley // intrisic are supplied. In certain cases one of these parameters may not be
185ebbcfa0SJosh Mottley // given, however the intrinsic needs to be run due to another required
195ebbcfa0SJosh Mottley // parameter being supplied. In this case the missing parameter is assigned to
205ebbcfa0SJosh Mottley // have an "absent" value. This typically happens in IntrinsicCall.cpp. For this
215ebbcfa0SJosh Mottley // reason the extra indirection with `isAbsent` is needed for testing whether a
225ebbcfa0SJosh Mottley // given parameter is actually present (so that parameters with "value" absent
235ebbcfa0SJosh Mottley // are not considered as present).
isAbsent(mlir::Value val)245ebbcfa0SJosh Mottley inline bool isAbsent(mlir::Value val) {
255ebbcfa0SJosh Mottley   return mlir::isa_and_nonnull<fir::AbsentOp>(val.getDefiningOp());
265ebbcfa0SJosh Mottley }
275ebbcfa0SJosh Mottley 
genCommandArgumentCount(fir::FirOpBuilder & builder,mlir::Location loc)28ddac11aeSJosh Mottley mlir::Value fir::runtime::genCommandArgumentCount(fir::FirOpBuilder &builder,
29ddac11aeSJosh Mottley                                                   mlir::Location loc) {
30ddac11aeSJosh Mottley   auto argumentCountFunc =
31ddac11aeSJosh Mottley       fir::runtime::getRuntimeFunc<mkRTKey(ArgumentCount)>(loc, builder);
32ddac11aeSJosh Mottley   return builder.create<fir::CallOp>(loc, argumentCountFunc).getResult(0);
33ddac11aeSJosh Mottley }
3438073b06SJosh Mottley 
genArgumentValue(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value number,mlir::Value value,mlir::Value errmsg)35*189cb7dfSjeanPerier mlir::Value fir::runtime::genArgumentValue(fir::FirOpBuilder &builder,
36*189cb7dfSjeanPerier                                            mlir::Location loc,
37*189cb7dfSjeanPerier                                            mlir::Value number,
38*189cb7dfSjeanPerier                                            mlir::Value value,
3938073b06SJosh Mottley                                            mlir::Value errmsg) {
4038073b06SJosh Mottley   auto argumentValueFunc =
4138073b06SJosh Mottley       fir::runtime::getRuntimeFunc<mkRTKey(ArgumentValue)>(loc, builder);
42*189cb7dfSjeanPerier   llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
43*189cb7dfSjeanPerier       builder, loc, argumentValueFunc.getFunctionType(), number, value, errmsg);
44*189cb7dfSjeanPerier   return builder.create<fir::CallOp>(loc, argumentValueFunc, args).getResult(0);
45*189cb7dfSjeanPerier }
46*189cb7dfSjeanPerier 
genArgumentLength(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value number)47*189cb7dfSjeanPerier mlir::Value fir::runtime::genArgumentLength(fir::FirOpBuilder &builder,
48*189cb7dfSjeanPerier                                             mlir::Location loc,
49*189cb7dfSjeanPerier                                             mlir::Value number) {
5038073b06SJosh Mottley   auto argumentLengthFunc =
5138073b06SJosh Mottley       fir::runtime::getRuntimeFunc<mkRTKey(ArgumentLength)>(loc, builder);
5238073b06SJosh Mottley   llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
534a3460a7SRiver Riddle       builder, loc, argumentLengthFunc.getFunctionType(), number);
54*189cb7dfSjeanPerier   return builder.create<fir::CallOp>(loc, argumentLengthFunc, args)
55*189cb7dfSjeanPerier       .getResult(0);
5638073b06SJosh Mottley }
575ebbcfa0SJosh Mottley 
genEnvVariableValue(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value name,mlir::Value value,mlir::Value trimName,mlir::Value errmsg)58*189cb7dfSjeanPerier mlir::Value fir::runtime::genEnvVariableValue(
595ebbcfa0SJosh Mottley     fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value name,
60*189cb7dfSjeanPerier     mlir::Value value, mlir::Value trimName, mlir::Value errmsg) {
615ebbcfa0SJosh Mottley   auto valueFunc =
625ebbcfa0SJosh Mottley       fir::runtime::getRuntimeFunc<mkRTKey(EnvVariableValue)>(loc, builder);
63*189cb7dfSjeanPerier   mlir::FunctionType valueFuncTy = valueFunc.getFunctionType();
64*189cb7dfSjeanPerier   mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
65*189cb7dfSjeanPerier   mlir::Value sourceLine =
66*189cb7dfSjeanPerier       fir::factory::locationToLineNo(builder, loc, valueFuncTy.getInput(5));
67*189cb7dfSjeanPerier   llvm::SmallVector<mlir::Value> args =
68*189cb7dfSjeanPerier       fir::runtime::createArguments(builder, loc, valueFuncTy, name, value,
69*189cb7dfSjeanPerier                                     trimName, errmsg, sourceFile, sourceLine);
70*189cb7dfSjeanPerier   return builder.create<fir::CallOp>(loc, valueFunc, args).getResult(0);
71*189cb7dfSjeanPerier }
72*189cb7dfSjeanPerier 
genEnvVariableLength(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value name,mlir::Value trimName)73*189cb7dfSjeanPerier mlir::Value fir::runtime::genEnvVariableLength(fir::FirOpBuilder &builder,
74*189cb7dfSjeanPerier                                                mlir::Location loc,
75*189cb7dfSjeanPerier                                                mlir::Value name,
76*189cb7dfSjeanPerier                                                mlir::Value trimName) {
775ebbcfa0SJosh Mottley   auto lengthFunc =
785ebbcfa0SJosh Mottley       fir::runtime::getRuntimeFunc<mkRTKey(EnvVariableLength)>(loc, builder);
79*189cb7dfSjeanPerier   mlir::FunctionType lengthFuncTy = lengthFunc.getFunctionType();
80*189cb7dfSjeanPerier   mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
81*189cb7dfSjeanPerier   mlir::Value sourceLine =
82*189cb7dfSjeanPerier       fir::factory::locationToLineNo(builder, loc, lengthFuncTy.getInput(3));
835ebbcfa0SJosh Mottley   llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
84*189cb7dfSjeanPerier       builder, loc, lengthFuncTy, name, trimName, sourceFile, sourceLine);
85*189cb7dfSjeanPerier   return builder.create<fir::CallOp>(loc, lengthFunc, args).getResult(0);
865ebbcfa0SJosh Mottley }
87