Skip to content

[flang ]GETLOG runtime and extension implementation: get login username #70917

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
49da4a6
add execute_command_line
jeffhammond Oct 18, 2023
e31c6f3
this is definitely not completely correct
jeffhammond Oct 18, 2023
60a826e
definitely not right either
jeffhammond Oct 18, 2023
aa31e9b
definitely not right either
jeffhammond Oct 18, 2023
a417c5a
more correct
jeffhammond Oct 18, 2023
36811c7
more correct
jeffhammond Oct 18, 2023
6cc9e3f
remove trailing space
jeffhammond Oct 18, 2023
46664b7
5 args not 6
jeffhammond Oct 18, 2023
01d6167
i have no idea what i am doing
jeffhammond Oct 18, 2023
b6ea7a7
runtime part of this
jeffhammond Oct 18, 2023
7ffafe4
WIP
jeffhammond Oct 18, 2023
2e9685b
where is the pattern for IsValidLogicalDescriptor
jeffhammond Oct 18, 2023
02ab9c8
Merge remote-tracking branch 'jeffhammond/jeffhammond-execute_command…
yiwu0b11 Nov 20, 2023
df35e09
some small fixes to make it build
yiwu0b11 Nov 20, 2023
94ac475
Add simple support of async and sync execution, might not work on Win…
yiwu0b11 Nov 21, 2023
ecfd50d
some changes to match the standard 16.9.73
yiwu0b11 Nov 23, 2023
9f687f0
Fixing error termination Linux only
yiwu0b11 Nov 28, 2023
7ef735f
Added EXECL_ERR if exit==-1, update docs
Nov 28, 2023
1b17b28
Add runtime tests
yiwu0b11 Nov 30, 2023
521228c
Add lowering intrinsic tests
yiwu0b11 Nov 30, 2023
f7133e4
add more docs, format, and brace initialization
yiwu0b11 Dec 1, 2023
c8e2e00
add test fixes on Windows and remove `address_of` in testing
Dec 1, 2023
af9294c
terminated children do not become zombies on Linux
yiwu0b11 Dec 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions flang/docs/Intrinsics.md
Original file line number Diff line number Diff line change
Expand Up @@ -835,3 +835,48 @@ TRIM, UBOUND, UNPACK, VERIFY.

Coarray, non standard, IEEE and ISO_C_BINDINGS intrinsic functions that can be
used in constant expressions have currently no folding support at all.

### Standard Intrinsics: EXECUTE_COMMAND_LINE

#### Usage and Info

- **Standard:** Fortran 2008 and later, specified in 16.9.73
- **Class:** Subroutine
- **Syntax:** `CALL EXECUTE_COMMAND_LINE(COMMAND [, WAIT, EXITSTAT, CMDSTAT, CMDMSG ])`
- **Arguments:**

| Argument | Description |
|-----------|--------------------------------------------------------------|
| `COMMAND` | Shall be a default CHARACTER scalar. |
| `WAIT` | (Optional) Shall be a default LOGICAL scalar. |
| `EXITSTAT`| (Optional) Shall be an INTEGER of the default kind. |
| `CMDSTAT` | (Optional) Shall be an INTEGER of the default kind. |
| `CMDMSG` | (Optional) Shall be a CHARACTER scalar of the default kind. |

#### Implementation Specifics

- **`COMMAND`:**
- Must be preset.

- **`WAIT`:**
- If set to `false`, the command is executed asynchronously. If not preset or set to `false`, it is executed synchronously.
- Sync: achieved by passing command into `std::system` on all systems.
- Async: achieved by calling a `fork()` on POSIX-compatible systems, or `CreateProcess()` on Windows.

- **`CMDSTAT`:**
- -2: No error condition occurs, but `WAIT` is present with the value `false`, and the processor does not support asynchronous execution.
- -1: The processor does not support command line execution.
- \+ (positive value): An error condition occurs.
- 1: Fork Error, where `pid_t < 0`, would only occur on POSIX-compatible systems.
- 2: Execution Error, a command exits with status -1.
- 3: Invalid Command Error, determined by the exit code depending on the system.
- On Windows, if the exit code is 1.
- On POSIX-compatible systems, if the exit code is 127 or 126.
- 4: Signal error, either it is stopped or killed by signal, would only occur on POSIX-compatible systems.
- 0: Otherwise.

- **`CMDMSG`:**
- If an error condition occurs, it is assigned an explanatory message. Otherwise, it remains unchanged.
- If a condition occurs that would assign a nonzero value to `CMDSTAT` but the `CMDSTAT` variable is not present, error termination is initiated.
- On POSIX-compatible systems, this applies to both synchronous and asynchronous error termination. When the execution mode is set to async with error termination, the child process (async process) will be terminated with no effect on the parent process (continues).
- On Windows, this only applies to synchronous error termination.
1 change: 1 addition & 0 deletions flang/include/flang/Optimizer/Builder/IntrinsicCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ struct IntrinsicLibrary {
mlir::Value genDshiftr(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genEoshift(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
void genExit(llvm::ArrayRef<fir::ExtendedValue>);
void genExecuteCommandLine(mlir::ArrayRef<fir::ExtendedValue> args);
mlir::Value genExponent(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genExtendsTypeOf(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
Expand Down
34 changes: 34 additions & 0 deletions flang/include/flang/Optimizer/Builder/Runtime/Execute.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//===-- Command.cpp -- generate command line runtime API calls ------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef FORTRAN_OPTIMIZER_BUILDER_RUNTIME_EXECUTE_H
#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_EXECUTE_H

namespace mlir {
class Value;
class Location;
} // namespace mlir

namespace fir {
class FirOpBuilder;
} // namespace fir

namespace fir::runtime {

/// Generate a call to the ExecuteCommandLine runtime function which implements
/// the GET_EXECUTE_ARGUMENT intrinsic.
/// \p wait, \p exitstat, \p cmdstat and \p cmdmsg must be fir.box that can be
/// absent (but not null mlir values). The status exitstat and cmdstat are
/// returned, along with the message cmdmsg.
void genExecuteCommandLine(fir::FirOpBuilder &, mlir::Location,
mlir::Value command, mlir::Value wait,
mlir::Value exitstat, mlir::Value cmdstat,
mlir::Value cmdmsg);

} // namespace fir::runtime
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_EXECUTE_H
31 changes: 31 additions & 0 deletions flang/include/flang/Runtime/execute.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===-- include/flang/Runtime/command.h -------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef FORTRAN_RUNTIME_EXECUTE_H_
#define FORTRAN_RUNTIME_EXECUTE_H_

#include "flang/Runtime/entry-names.h"

#include <cstdint>

namespace Fortran::runtime {
class Descriptor;

extern "C" {

// 16.9.83 EXECUTE_COMMAND_LINE
// Execute a command line.
// Returns a EXITSTAT, CMDSTAT, and CMDMSG as described in the standard.
void RTNAME(ExecuteCommandLine)(const Descriptor *command = nullptr,
bool wait = true, const Descriptor *exitstat = nullptr,
const Descriptor *cmdstat = nullptr, const Descriptor *cmdmsg = nullptr,
const char *sourceFile = nullptr, int line = 0);
}
} // namespace Fortran::runtime

#endif // FORTRAN_RUNTIME_EXECUTE_H_
1 change: 1 addition & 0 deletions flang/lib/Optimizer/Builder/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ add_flang_library(FIRBuilder
Runtime/Command.cpp
Runtime/Derived.cpp
Runtime/EnvironmentDefaults.cpp
Runtime/Execute.cpp
Runtime/Inquiry.cpp
Runtime/Intrinsics.cpp
Runtime/Numeric.cpp
Expand Down
43 changes: 43 additions & 0 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "flang/Optimizer/Builder/Runtime/Character.h"
#include "flang/Optimizer/Builder/Runtime/Command.h"
#include "flang/Optimizer/Builder/Runtime/Derived.h"
#include "flang/Optimizer/Builder/Runtime/Execute.h"
#include "flang/Optimizer/Builder/Runtime/Inquiry.h"
#include "flang/Optimizer/Builder/Runtime/Intrinsics.h"
#include "flang/Optimizer/Builder/Runtime/Numeric.h"
Expand Down Expand Up @@ -209,6 +210,14 @@ static constexpr IntrinsicHandler handlers[]{
{"boundary", asBox, handleDynamicOptional},
{"dim", asValue}}},
/*isElemental=*/false},
{"execute_command_line",
&I::genExecuteCommandLine,
{{{"command", asBox},
{"wait", asValue, handleDynamicOptional},
{"exitstat", asBox, handleDynamicOptional},
{"cmdstat", asBox, handleDynamicOptional},
{"cmdmsg", asBox, handleDynamicOptional}}},
/*isElemental=*/false},
{"exit",
&I::genExit,
{{{"status", asValue, handleDynamicOptional}}},
Expand Down Expand Up @@ -2776,6 +2785,40 @@ IntrinsicLibrary::genEoshift(mlir::Type resultType,
return readAndAddCleanUp(resultMutableBox, resultType, "EOSHIFT");
}

// EXECUTE_COMMAND_LINE
void IntrinsicLibrary::genExecuteCommandLine(
llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() == 5);
mlir::Value command = fir::getBase(args[0]);
const fir::ExtendedValue &wait = args[1];
const fir::ExtendedValue &exitstat = args[2];
const fir::ExtendedValue &cmdstat = args[3];
const fir::ExtendedValue &cmdmsg = args[4];

if (!command)
fir::emitFatalError(loc, "expected COMMAND parameter");

mlir::Type boxNoneTy = fir::BoxType::get(builder.getNoneType());

mlir::Value waitBool = isStaticallyPresent(wait)
? fir::getBase(wait)
: builder.createBool(loc, true);
mlir::Value exitstatBox =
isStaticallyPresent(exitstat)
? fir::getBase(exitstat)
: builder.create<fir::AbsentOp>(loc, boxNoneTy).getResult();
mlir::Value cmdstatBox =
isStaticallyPresent(cmdstat)
? fir::getBase(cmdstat)
: builder.create<fir::AbsentOp>(loc, boxNoneTy).getResult();
mlir::Value cmdmsgBox =
isStaticallyPresent(cmdmsg)
? fir::getBase(cmdmsg)
: builder.create<fir::AbsentOp>(loc, boxNoneTy).getResult();
fir::runtime::genExecuteCommandLine(builder, loc, command, waitBool,
exitstatBox, cmdstatBox, cmdmsgBox);
}

// EXIT
void IntrinsicLibrary::genExit(llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() == 1);
Expand Down
44 changes: 44 additions & 0 deletions flang/lib/Optimizer/Builder/Runtime/Execute.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//===-- Execute.cpp -- generate command line runtime API calls ------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "flang/Optimizer/Builder/Runtime/Execute.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Runtime/execute.h"

using namespace Fortran::runtime;

// Certain runtime intrinsics should only be run when select parameters of the
// intrisic are supplied. In certain cases one of these parameters may not be
// given, however the intrinsic needs to be run due to another required
// parameter being supplied. In this case the missing parameter is assigned to
// have an "absent" value. This typically happens in IntrinsicCall.cpp. For this
// reason the extra indirection with `isAbsent` is needed for testing whether a
// given parameter is actually present (so that parameters with "value" absent
// are not considered as present).
inline bool isAbsent(mlir::Value val) {
return mlir::isa_and_nonnull<fir::AbsentOp>(val.getDefiningOp());
}

void fir::runtime::genExecuteCommandLine(fir::FirOpBuilder &builder,
mlir::Location loc,
mlir::Value command, mlir::Value wait,
mlir::Value exitstat,
mlir::Value cmdstat,
mlir::Value cmdmsg) {
auto runtimeFunc =
fir::runtime::getRuntimeFunc<mkRTKey(ExecuteCommandLine)>(loc, builder);
mlir::FunctionType runtimeFuncTy = runtimeFunc.getFunctionType();
mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
mlir::Value sourceLine =
fir::factory::locationToLineNo(builder, loc, runtimeFuncTy.getInput(6));
llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
builder, loc, runtimeFuncTy, command, wait, exitstat, cmdstat, cmdmsg,
sourceFile, sourceLine);
builder.create<fir::CallOp>(loc, runtimeFunc, args);
}
1 change: 1 addition & 0 deletions flang/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ set(sources
edit-input.cpp
edit-output.cpp
environment.cpp
execute.cpp
extensions.cpp
extrema.cpp
file.cpp
Expand Down
Loading