Skip to content

Commit cbb3d19

Browse files
SC llvm teamSC llvm team
SC llvm team
authored and
SC llvm team
committed
Merged main:fe2ff54590c313551e7968179b48988ff0916290 into amd-gfx:57c0f5e83155
Local branch amd-gfx 57c0f5e Merged main:df575be9d864886684e536cd76c5a96bb0d443a6 into amd-gfx:bd7b8d70663d Remote branch main fe2ff54 [flang][runtime] Decouple scalar output APIs from descriptors (llvm#92444)
2 parents 57c0f5e + fe2ff54 commit cbb3d19

File tree

25 files changed

+653
-283
lines changed

25 files changed

+653
-283
lines changed

clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_add_sub_za16.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -verify -emit-llvm %s
1+
// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -verify -emit-llvm-only %s
22

33
// REQUIRES: aarch64-registered-target
44

compiler-rt/test/tsan/signal_in_mutex_lock.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <signal.h>
66
#include <stdio.h>
77

8+
#include <atomic>
89
#include <cassert>
910
#include <condition_variable>
1011
#include <mutex>
@@ -13,9 +14,10 @@ std::mutex sampler_mutex; //dummy mutex to lock in the thread we spawn.
1314
std::mutex done_mutex; // guards the cv and done variables.
1415
std::condition_variable cv;
1516
bool done = false;
17+
std::atomic<bool> spin = true;
1618

1719
void *ThreadFunc(void *x) {
18-
while (true) {
20+
while (spin) {
1921
// Lock the mutex
2022
std::lock_guard<std::mutex> guard(sampler_mutex);
2123
// Mutex is released at the end
@@ -51,20 +53,26 @@ int main() {
5153
pthread_t thread;
5254
pthread_create(&thread, NULL, ThreadFunc, NULL);
5355

54-
// Lock the mutex before sending the signal
55-
std::lock_guard<std::mutex> guard(sampler_mutex);
56-
// From now on thread 1 will be waiting for the lock
56+
{
57+
// Lock the mutex before sending the signal
58+
std::lock_guard<std::mutex> guard(sampler_mutex);
59+
// From now on thread 1 will be waiting for the lock
5760

58-
// Send the SIGPROF signal to thread.
59-
int r = pthread_kill(thread, SIGPROF);
60-
assert(r == 0);
61+
// Send the SIGPROF signal to thread.
62+
int r = pthread_kill(thread, SIGPROF);
63+
assert(r == 0);
6164

62-
// Wait until signal handler sends the data.
63-
std::unique_lock lk(done_mutex);
64-
cv.wait(lk, [] { return done; });
65+
// Wait until signal handler sends the data.
66+
std::unique_lock lk(done_mutex);
67+
cv.wait(lk, [] { return done; });
68+
69+
// We got the done variable from the signal handler. Exiting successfully.
70+
fprintf(stderr, "PASS\n");
71+
}
6572

66-
// We got the done variable from the signal handler. Exiting successfully.
67-
fprintf(stderr, "PASS\n");
73+
// Wait for thread to prevent it from spinning on a released mutex.
74+
spin = false;
75+
pthread_join(thread, nullptr);
6876
}
6977

7078
// CHECK-NOT: WARNING: ThreadSanitizer:

flang/include/flang/Semantics/semantics.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,10 @@ class SemanticsContext {
215215
void UseFortranBuiltinsModule();
216216
const Scope *GetBuiltinsScope() const { return builtinsScope_; }
217217

218-
void UsePPCBuiltinTypesModule();
219218
const Scope &GetCUDABuiltinsScope();
219+
const Scope &GetCUDADeviceScope();
220+
221+
void UsePPCBuiltinTypesModule();
220222
void UsePPCBuiltinsModule();
221223
Scope *GetPPCBuiltinTypesScope() { return ppcBuiltinTypesScope_; }
222224
const Scope *GetPPCBuiltinsScope() const { return ppcBuiltinsScope_; }
@@ -292,6 +294,7 @@ class SemanticsContext {
292294
const Scope *builtinsScope_{nullptr}; // module __Fortran_builtins
293295
Scope *ppcBuiltinTypesScope_{nullptr}; // module __Fortran_PPC_types
294296
std::optional<const Scope *> cudaBuiltinsScope_; // module __CUDA_builtins
297+
std::optional<const Scope *> cudaDeviceScope_; // module cudadevice
295298
const Scope *ppcBuiltinsScope_{nullptr}; // module __ppc_intrinsics
296299
std::list<parser::Program> modFileParseTrees_;
297300
std::unique_ptr<CommonBlockMap> commonBlockMap_;

flang/lib/Semantics/resolve-names.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3797,6 +3797,26 @@ bool SubprogramVisitor::Pre(const parser::PrefixSpec::Attributes &attrs) {
37973797
subp->set_cudaSubprogramAttrs(attr);
37983798
}
37993799
}
3800+
if (auto attrs{subp->cudaSubprogramAttrs()}) {
3801+
if (*attrs == common::CUDASubprogramAttrs::Global ||
3802+
*attrs == common::CUDASubprogramAttrs::Device) {
3803+
const Scope &scope{currScope()};
3804+
const Scope *mod{FindModuleContaining(scope)};
3805+
if (mod && mod->GetName().value() == "cudadevice") {
3806+
return false;
3807+
}
3808+
// Implicitly USE the cudadevice module by copying its symbols in the
3809+
// current scope.
3810+
const Scope &cudaDeviceScope{context().GetCUDADeviceScope()};
3811+
for (auto sym : cudaDeviceScope.GetSymbols()) {
3812+
if (!currScope().FindSymbol(sym->name())) {
3813+
auto &localSymbol{MakeSymbol(
3814+
sym->name(), Attrs{}, UseDetails{sym->name(), *sym})};
3815+
localSymbol.flags() = sym->flags();
3816+
}
3817+
}
3818+
}
3819+
}
38003820
}
38013821
return false;
38023822
}

flang/lib/Semantics/semantics.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,14 @@ const Scope &SemanticsContext::GetCUDABuiltinsScope() {
543543
return **cudaBuiltinsScope_;
544544
}
545545

546+
const Scope &SemanticsContext::GetCUDADeviceScope() {
547+
if (!cudaDeviceScope_) {
548+
cudaDeviceScope_ = GetBuiltinModule("cudadevice");
549+
CHECK(cudaDeviceScope_.value() != nullptr);
550+
}
551+
return **cudaDeviceScope_;
552+
}
553+
546554
void SemanticsContext::UsePPCBuiltinsModule() {
547555
if (ppcBuiltinsScope_ == nullptr) {
548556
ppcBuiltinsScope_ = GetBuiltinModule("__ppc_intrinsics");

flang/module/cudadevice.f90

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
!===-- module/cudedevice.f90 -----------------------------------------------===!
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+
! CUDA Fortran procedures available in device subprogram
10+
11+
module cudadevice
12+
implicit none
13+
14+
! Set PRIVATE by default to explicitly only export what is meant
15+
! to be exported by this MODULE.
16+
private
17+
18+
! Synchronization Functions
19+
20+
interface
21+
attributes(device) subroutine syncthreads()
22+
end subroutine
23+
end interface
24+
public :: syncthreads
25+
26+
interface
27+
attributes(device) integer function syncthreads_and(value)
28+
integer :: value
29+
end function
30+
end interface
31+
public :: syncthreads_and
32+
33+
interface
34+
attributes(device) integer function syncthreads_count(value)
35+
integer :: value
36+
end function
37+
end interface
38+
public :: syncthreads_count
39+
40+
interface
41+
attributes(device) integer function syncthreads_or(value)
42+
integer :: value
43+
end function
44+
end interface
45+
public :: syncthreads_or
46+
47+
interface
48+
attributes(device) subroutine syncwarp(mask)
49+
integer :: mask
50+
end subroutine
51+
end interface
52+
public :: syncwarp
53+
54+
! Memory Fences
55+
56+
interface
57+
attributes(device) subroutine threadfence()
58+
end subroutine
59+
end interface
60+
public :: threadfence
61+
62+
interface
63+
attributes(device) subroutine threadfence_block()
64+
end subroutine
65+
end interface
66+
public :: threadfence_block
67+
68+
interface
69+
attributes(device) subroutine threadfence_system()
70+
end subroutine
71+
end interface
72+
public :: threadfence_system
73+
74+
end module

flang/runtime/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ set(sources
136136
inquiry.cpp
137137
internal-unit.cpp
138138
io-api.cpp
139+
io-api-minimal.cpp
139140
io-error.cpp
140141
io-stmt.cpp
141142
iostat.cpp

flang/runtime/descriptor-io.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,8 +499,7 @@ static RT_API_ATTRS bool DescriptorIO(IoStatementState &io,
499499
return false;
500500
}
501501
if (!io.get_if<IoDirectionState<DIR>>()) {
502-
io.GetIoErrorHandler().Crash(
503-
"DescriptorIO() called for wrong I/O direction");
502+
handler.Crash("DescriptorIO() called for wrong I/O direction");
504503
return false;
505504
}
506505
if constexpr (DIR == Direction::Input) {

flang/runtime/io-api-common.h

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//===-- runtime/io-api-common.h ---------------------------------*- C++ -*-===//
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+
#ifndef FLANG_RUNTIME_IO_API_COMMON_H_
10+
#define FLANG_RUNTIME_IO_API_COMMON_H_
11+
12+
#include "io-stmt.h"
13+
#include "terminator.h"
14+
#include "unit.h"
15+
#include "flang/Common/api-attrs.h"
16+
#include "flang/Common/optional.h"
17+
#include "flang/Runtime/io-api.h"
18+
19+
namespace Fortran::runtime::io {
20+
21+
static inline RT_API_ATTRS Cookie NoopUnit(const Terminator &terminator,
22+
int unitNumber, enum Iostat iostat = IostatOk) {
23+
Cookie cookie{&New<NoopStatementState>{terminator}(
24+
terminator.sourceFileName(), terminator.sourceLine(), unitNumber)
25+
.release()
26+
->ioStatementState()};
27+
if (iostat != IostatOk) {
28+
cookie->GetIoErrorHandler().SetPendingError(iostat);
29+
}
30+
return cookie;
31+
}
32+
33+
static inline RT_API_ATTRS ExternalFileUnit *GetOrCreateUnit(int unitNumber,
34+
Direction direction, Fortran::common::optional<bool> isUnformatted,
35+
const Terminator &terminator, Cookie &errorCookie) {
36+
if (ExternalFileUnit *
37+
unit{ExternalFileUnit::LookUpOrCreateAnonymous(
38+
unitNumber, direction, isUnformatted, terminator)}) {
39+
errorCookie = nullptr;
40+
return unit;
41+
} else {
42+
errorCookie = NoopUnit(terminator, unitNumber, IostatBadUnitNumber);
43+
return nullptr;
44+
}
45+
}
46+
47+
template <Direction DIR, template <Direction> class STATE, typename... A>
48+
RT_API_ATTRS Cookie BeginExternalListIO(
49+
int unitNumber, const char *sourceFile, int sourceLine, A &&...xs) {
50+
Terminator terminator{sourceFile, sourceLine};
51+
Cookie errorCookie{nullptr};
52+
ExternalFileUnit *unit{GetOrCreateUnit(
53+
unitNumber, DIR, false /*!unformatted*/, terminator, errorCookie)};
54+
if (!unit) {
55+
return errorCookie;
56+
}
57+
if (!unit->isUnformatted.has_value()) {
58+
unit->isUnformatted = false;
59+
}
60+
Iostat iostat{IostatOk};
61+
if (*unit->isUnformatted) {
62+
iostat = IostatFormattedIoOnUnformattedUnit;
63+
}
64+
if (ChildIo * child{unit->GetChildIo()}) {
65+
if (iostat == IostatOk) {
66+
iostat = child->CheckFormattingAndDirection(false, DIR);
67+
}
68+
if (iostat == IostatOk) {
69+
return &child->BeginIoStatement<ChildListIoStatementState<DIR>>(
70+
*child, sourceFile, sourceLine);
71+
} else {
72+
return &child->BeginIoStatement<ErroneousIoStatementState>(
73+
iostat, nullptr /* no unit */, sourceFile, sourceLine);
74+
}
75+
} else {
76+
if (iostat == IostatOk && unit->access == Access::Direct) {
77+
iostat = IostatListIoOnDirectAccessUnit;
78+
}
79+
if (iostat == IostatOk) {
80+
iostat = unit->SetDirection(DIR);
81+
}
82+
if (iostat == IostatOk) {
83+
return &unit->BeginIoStatement<STATE<DIR>>(
84+
terminator, std::forward<A>(xs)..., *unit, sourceFile, sourceLine);
85+
} else {
86+
return &unit->BeginIoStatement<ErroneousIoStatementState>(
87+
terminator, iostat, unit, sourceFile, sourceLine);
88+
}
89+
}
90+
}
91+
92+
} // namespace Fortran::runtime::io
93+
#endif // FLANG_RUNTIME_IO_API_COMMON_H_

0 commit comments

Comments
 (0)