13
13
14
14
using namespace Fortran ::runtime;
15
15
16
+ // Certain runtime intrinsics should only be run when select parameters of the
17
+ // intrisic are supplied. In certain cases one of these parameters may not be
18
+ // given, however the intrinsic needs to be run due to another required
19
+ // parameter being supplied. In this case the missing parameter is assigned to
20
+ // have an "absent" value. This typically happens in IntrinsicCall.cpp. For this
21
+ // reason the extra indirection with `isAbsent` is needed for testing whether a
22
+ // given parameter is actually present (so that parameters with "value" absent
23
+ // are not considered as present).
24
+ inline bool isAbsent (mlir::Value val) {
25
+ return mlir::isa_and_nonnull<fir::AbsentOp>(val.getDefiningOp ());
26
+ }
27
+
16
28
mlir::Value fir::runtime::genCommandArgumentCount (fir::FirOpBuilder &builder,
17
29
mlir::Location loc) {
18
30
auto argumentCountFunc =
@@ -30,33 +42,25 @@ void fir::runtime::genGetCommandArgument(fir::FirOpBuilder &builder,
30
42
auto argumentLengthFunc =
31
43
fir::runtime::getRuntimeFunc<mkRTKey (ArgumentLength)>(loc, builder);
32
44
33
- auto isPresent = [&](mlir::Value val) -> bool {
34
- return !mlir::isa_and_nonnull<fir::AbsentOp>(val.getDefiningOp ());
35
- };
36
-
37
45
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
+ // Run `ArgumentValue` intrinsic only if we have a "value" in either "VALUE",
47
+ // "STATUS" or "ERRMSG" parameters.
48
+ if (!isAbsent (value) || status || !isAbsent (errmsg)) {
46
49
llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments (
47
50
builder, loc, argumentValueFunc.getType (), number, value, errmsg);
48
51
valueResult =
49
52
builder.create <fir::CallOp>(loc, argumentValueFunc, args).getResult (0 );
50
53
}
51
54
52
- // Only save result of ArgumentValue if "status " parameter has been given
55
+ // Only save result of ` ArgumentValue` if "STATUS " parameter has been given
53
56
if (status) {
54
57
const mlir::Value statusLoaded = builder.create <fir::LoadOp>(loc, status);
55
58
mlir::Value resultCast =
56
59
builder.createConvert (loc, statusLoaded.getType (), valueResult);
57
60
builder.create <fir::StoreOp>(loc, resultCast, status);
58
61
}
59
62
63
+ // Only run `ArgumentLength` intrinsic if "LENGTH" parameter provided
60
64
if (length) {
61
65
llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments (
62
66
builder, loc, argumentLengthFunc.getType (), number);
@@ -68,3 +72,55 @@ void fir::runtime::genGetCommandArgument(fir::FirOpBuilder &builder,
68
72
builder.create <fir::StoreOp>(loc, resultCast, length);
69
73
}
70
74
}
75
+
76
+ void fir::runtime::genGetEnvironmentVariable (
77
+ fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value name,
78
+ mlir::Value value, mlir::Value length, mlir::Value status,
79
+ mlir::Value trimName, mlir::Value errmsg) {
80
+ auto valueFunc =
81
+ fir::runtime::getRuntimeFunc<mkRTKey (EnvVariableValue)>(loc, builder);
82
+ auto lengthFunc =
83
+ fir::runtime::getRuntimeFunc<mkRTKey (EnvVariableLength)>(loc, builder);
84
+
85
+ mlir::Value sourceFile;
86
+ mlir::Value sourceLine;
87
+ // We only need `sourceFile` and `sourceLine` variables when calling either
88
+ // `EnvVariableValue` or `EnvVariableLength` below.
89
+ if (!isAbsent (value) || status || !isAbsent (errmsg) || length) {
90
+ sourceFile = fir::factory::locationToFilename (builder, loc);
91
+ sourceLine = fir::factory::locationToLineNo (
92
+ builder, loc, valueFunc.getType ().getInput (5 ));
93
+ }
94
+
95
+ mlir::Value valueResult;
96
+ // Run `EnvVariableValue` intrinsic only if we have a "value" in either
97
+ // "VALUE", "STATUS" or "ERRMSG" parameters.
98
+ if (!isAbsent (value) || status || !isAbsent (errmsg)) {
99
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments (
100
+ builder, loc, valueFunc.getType (), name, value, trimName, errmsg,
101
+ sourceFile, sourceLine);
102
+ valueResult =
103
+ builder.create <fir::CallOp>(loc, valueFunc, args).getResult (0 );
104
+ }
105
+
106
+ // Only save result of `EnvVariableValue` if "STATUS" parameter provided
107
+ if (status) {
108
+ const mlir::Value statusLoaded = builder.create <fir::LoadOp>(loc, status);
109
+ mlir::Value resultCast =
110
+ builder.createConvert (loc, statusLoaded.getType (), valueResult);
111
+ builder.create <fir::StoreOp>(loc, resultCast, status);
112
+ }
113
+
114
+ // Only run `EnvVariableLength` intrinsic if "LENGTH" parameter provided
115
+ if (length) {
116
+ llvm::SmallVector<mlir::Value> args =
117
+ fir::runtime::createArguments (builder, loc, lengthFunc.getType (), name,
118
+ trimName, sourceFile, sourceLine);
119
+ mlir::Value result =
120
+ builder.create <fir::CallOp>(loc, lengthFunc, args).getResult (0 );
121
+ const mlir::Value lengthLoaded = builder.create <fir::LoadOp>(loc, length);
122
+ mlir::Value resultCast =
123
+ builder.createConvert (loc, lengthLoaded.getType (), result);
124
+ builder.create <fir::StoreOp>(loc, resultCast, length);
125
+ }
126
+ }
0 commit comments