-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[flang] Add HOSTNM runtime and lowering intrinsics implementation #131910
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
Changes from 9 commits
9760096
828cd76
b0a8798
f670146
a0b6f85
b190979
e9fa37e
7cc9756
843db5c
d3384ec
b9f2d8f
f316320
4b61502
378e57f
42f7bc1
f9e8a39
21c0723
d2068a8
e375cc9
773055e
cb02a8e
d10fb71
633d0ba
e81f7f7
719612a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -480,6 +480,10 @@ static constexpr IntrinsicHandler handlers[]{ | |
| {"getgid", &I::genGetGID}, | ||
| {"getpid", &I::genGetPID}, | ||
| {"getuid", &I::genGetUID}, | ||
| {"hostnm", | ||
| &I::genHostnm, | ||
| {{{"c", asBox}, {"status", asAddr, handleDynamicOptional}}}, | ||
| /*isElemental=*/false}, | ||
| {"iachar", &I::genIchar}, | ||
| {"iall", | ||
| &I::genIall, | ||
|
|
@@ -4317,6 +4321,37 @@ void IntrinsicLibrary::genGetEnvironmentVariable( | |
| } | ||
| } | ||
|
|
||
| // HOSTNM | ||
| fir::ExtendedValue | ||
| IntrinsicLibrary::genHostnm(std::optional<mlir::Type> resultType, | ||
| llvm::ArrayRef<fir::ExtendedValue> args) { | ||
| assert((args.size() == 1 && resultType.has_value()) || | ||
| (args.size() >= 1 && !resultType.has_value())); | ||
|
|
||
| mlir::Value res = fir::getBase(args[0]); | ||
| mlir::Value statusValue = fir::runtime::genHostnm(builder, loc, res); | ||
|
|
||
| if (resultType.has_value()) { | ||
| // Function form, return status. | ||
| return statusValue; | ||
|
||
| } else { | ||
|
||
| // Subroutine form, store status and return none. | ||
| const fir::ExtendedValue &status = args[1]; | ||
| if (!isStaticallyAbsent(status)) { | ||
| mlir::Value statusAddr = fir::getBase(status); | ||
| mlir::Value statusIsPresentAtRuntime = | ||
| builder.genIsNotNullAddr(loc, statusAddr); | ||
| builder.genIfThen(loc, statusIsPresentAtRuntime) | ||
| .genThen([&]() { | ||
| builder.createStoreWithConvert(loc, statusValue, statusAddr); | ||
| }) | ||
| .end(); | ||
| } | ||
| } | ||
|
|
||
| return {}; | ||
| } | ||
|
|
||
| /// Process calls to Maxval, Minval, Product, Sum intrinsic functions that | ||
| /// take a DIM argument. | ||
| template <typename FD> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| ! REQUIRES: system-linux | ||
|
|
||
| ! Verify that the hostname obtained by HOSTNM() intrinsic is the same | ||
| ! as the hostname obtained by directly calling C gethostname(). | ||
|
|
||
| ! RUN: %flang -L"%libdir" %s -o %t | ||
| ! RUN: env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:%libdir" %t | FileCheck %s | ||
|
|
||
|
||
| ! CHECK: PASS | ||
|
|
||
| program get_hostname_cinterop | ||
| use, intrinsic :: iso_c_binding, only: c_char, c_int, c_size_t, c_null_char | ||
| implicit none | ||
|
|
||
| interface | ||
| function gethostname(name, namelen) bind(C) | ||
| import :: c_char, c_int, c_size_t | ||
| integer(c_int) :: gethostname | ||
| character(kind=c_char), dimension(*) :: name | ||
| integer(c_size_t), value :: namelen | ||
| end function gethostname | ||
| end interface | ||
|
|
||
| integer, parameter :: HOST_NAME_MAX = 255 | ||
| character(kind=c_char), dimension(HOST_NAME_MAX + 1) :: c_hostname | ||
| character(HOST_NAME_MAX) :: hostname | ||
| character(HOST_NAME_MAX) :: hostnm_str | ||
| integer(c_int) :: status, i | ||
|
|
||
| status = gethostname(c_hostname, HOST_NAME_MAX) | ||
| if (status /= 0) then | ||
| print *, "Error in gethostname(), status code: ", status | ||
| error stop | ||
| end if | ||
|
|
||
| status = hostnm(hostnm_str) | ||
| if (status /= 0) then | ||
| print *, "Error in hostnm(), status code: ", status | ||
| error stop | ||
| end if | ||
|
|
||
| ! Find the position of the null terminator to convert C string to Fortran string | ||
| i = 1 | ||
| do while (i <= HOST_NAME_MAX .and. c_hostname(i) /= c_null_char) | ||
| i = i + 1 | ||
| end do | ||
|
|
||
| hostname = transfer(c_hostname(1:i-1), hostname) | ||
|
|
||
| print *, "Hostname from OS: ", hostname(1:i-1) | ||
| print *, "Hostname from hostnm(): ", hostnm_str(1:i-1) | ||
|
|
||
| if (hostname /= hostnm_str) then | ||
| print *, "FAIL" | ||
| else | ||
| print *, "PASS" | ||
| end if | ||
|
|
||
| end program get_hostname_cinterop | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| ! REQUIRES: system-linux | ||
|
|
||
| ! Verify that the hostname obtained by HOSTNM() intrinsic is the same | ||
| ! as the hostname obtained by directly calling C gethostname(). | ||
|
|
||
| ! RUN: %flang -L"%libdir" %s -o %t | ||
| ! RUN: env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:%libdir" %t | FileCheck %s | ||
|
|
||
| ! CHECK: PASS | ||
|
|
||
| program get_hostname_cinterop | ||
| use, intrinsic :: iso_c_binding, only: c_char, c_int, c_size_t, c_null_char | ||
| implicit none | ||
|
|
||
| interface | ||
| function gethostname(name, namelen) bind(C) | ||
| import :: c_char, c_int, c_size_t | ||
| integer(c_int) :: gethostname | ||
| character(kind=c_char), dimension(*) :: name | ||
| integer(c_size_t), value :: namelen | ||
| end function gethostname | ||
| end interface | ||
|
|
||
| integer, parameter :: HOST_NAME_MAX = 255 | ||
| character(kind=c_char), dimension(HOST_NAME_MAX + 1) :: c_hostname | ||
| character(HOST_NAME_MAX) :: hostname | ||
| character(HOST_NAME_MAX) :: hostnm_str | ||
| integer(c_int) :: status, i | ||
|
|
||
| status = gethostname(c_hostname, HOST_NAME_MAX) | ||
| if (status /= 0) then | ||
| print *, "Error in gethostname(), status code: ", status | ||
| error stop | ||
| end if | ||
|
|
||
| call hostnm(hostnm_str, status) | ||
| if (status /= 0) then | ||
| print *, "Error in hostnm(), status code: ", status | ||
| error stop | ||
| end if | ||
|
|
||
| ! Find the position of the null terminator to convert C string to Fortran string | ||
| i = 1 | ||
| do while (i <= HOST_NAME_MAX .and. c_hostname(i) /= c_null_char) | ||
| i = i + 1 | ||
| end do | ||
|
|
||
| hostname = transfer(c_hostname(1:i-1), hostname) | ||
|
|
||
| print *, "Hostname from OS: ", hostname(1:i-1) | ||
| print *, "Hostname from hostnm(): ", hostnm_str(1:i-1) | ||
|
|
||
| if (hostname /= hostnm_str) then | ||
| print *, "FAIL" | ||
| else | ||
| print *, "PASS" | ||
| end if | ||
|
|
||
| end program get_hostname_cinterop | ||
|
|
Uh oh!
There was an error while loading. Please reload this page.