Skip to content
1 change: 1 addition & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -6141,6 +6141,7 @@ def : Flag<["-"], "nogpulib">,
def : Flag<["-"], "nocudalib">, Alias<no_offloadlib>;
def gpulibc : Flag<["-"], "gpulibc">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Link the LLVM C Library for GPUs">;
def nogpuflangrt : Flag<["-"], "nogpuflangrt">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>;
def nogpulibc : Flag<["-"], "nogpulibc">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>;
def nodefaultlibs : Flag<["-"], "nodefaultlibs">,
Visibility<[ClangOption, FlangOption]>;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9422,7 +9422,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
Args.MakeArgString("--device-linker=" + TC.getTripleString() + "=" +
"-lclang_rt.builtins"));
bool HasFlangRT = HasCompilerRT && C.getDriver().IsFlangMode();
if (HasFlangRT)
if (HasFlangRT && !Args.hasArg(options::OPT_nogpuflangrt))
CmdArgs.push_back(
Args.MakeArgString("--device-linker=" + TC.getTripleString() + "=" +
"-lflang_rt.runtime"));
Expand Down
5 changes: 5 additions & 0 deletions flang-rt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ if (NOT "${FLANG_RT_LIBCXX_PROVIDER}" IN_LIST FLANG_RT_SUPPORTED_PROVIDERS)
endif ()

option(FLANG_RT_ENABLE_STATIC "Build Flang-RT as a static library." ON)
option(FLANG_RT_EMBED_GPU_LLVM_IR "Build Flang-RT as GPU LLVM IR library" ON)
if (FLANG_RT_EMBED_GPU_LLVM_IR)
add_compile_definitions(EMBED_FLANG_RT_GPU_LLVM_IR)
endif ()

if (WIN32)
# Windows DLL currently not implemented.
set(FLANG_RT_ENABLE_SHARED OFF)
Expand Down
13 changes: 13 additions & 0 deletions flang-rt/include/flang-rt/runtime/lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
#endif

#if USE_PTHREADS
#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
#include <pthread.h>
#endif
#elif defined(_WIN32)
#include "flang/Common/windows-include.h"
#else
Expand All @@ -45,6 +47,7 @@ class Lock {
RT_API_ATTRS void Drop() {}
RT_API_ATTRS bool TakeIfNoDeadlock() { return true; }
#elif USE_PTHREADS
#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
Lock() { pthread_mutex_init(&mutex_, nullptr); }
~Lock() { pthread_mutex_destroy(&mutex_); }
void Take() {
Expand All @@ -68,6 +71,14 @@ class Lock {
isBusy_ = false;
pthread_mutex_unlock(&mutex_);
}
#else
RT_API_ATTRS void Take(){}
RT_API_ATTRS bool TakeIfNoDeadlock() {return true;}
RT_API_ATTRS bool Try() {return true;}
RT_API_ATTRS void Drop() {}
Lock() {}
~Lock() {}
#endif
#elif defined(_WIN32)
Lock() { InitializeCriticalSection(&cs_); }
~Lock() { DeleteCriticalSection(&cs_); }
Expand All @@ -91,9 +102,11 @@ class Lock {
#if RT_USE_PSEUDO_FILE_UNIT
// No state.
#elif USE_PTHREADS
#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
pthread_mutex_t mutex_{};
volatile bool isBusy_{false};
volatile pthread_t holder_;
#endif
#elif defined(_WIN32)
CRITICAL_SECTION cs_;
#else
Expand Down
7 changes: 7 additions & 0 deletions flang-rt/include/flang-rt/runtime/tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@
#define RT_USE_PSEUDO_FILE_UNIT 1
#endif


#if (defined(__AMDGPU__) || defined(__NVPTX__)) && defined(EMBED_FLANG_RT_GPU_LLVM_IR)
// Use the pseudo lock and pseudo file unit implementations
// for the device.
#define RT_USE_PSEUDO_LOCK 1
#define RT_USE_PSEUDO_FILE_UNIT 1
#endif
namespace Fortran::runtime {

class Terminator;
Expand Down
6 changes: 5 additions & 1 deletion flang-rt/lib/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,11 @@ else ()
endif ()

if ("${LLVM_RUNTIMES_TARGET}" MATCHES "^amdgcn|^nvptx")
set(sources ${gpu_sources})
if (FLANG_RT_EMBED_GPU_LLVM_IR)
set(sources ${supported_sources} ${gpu_sources})
else ()
set(sources ${gpu_sources})
endif ()
elseif(FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA")
set(sources ${supported_sources})
else ()
Expand Down
13 changes: 2 additions & 11 deletions flang-rt/lib/runtime/assign.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
//===----------------------------------------------------------------------===//

#include "flang/Runtime/assign.h"
#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
#include "flang/Runtime/stop.h"
#endif
#include "flang-rt/runtime/assign-impl.h"
#include "flang-rt/runtime/derived.h"
#include "flang-rt/runtime/descriptor.h"
Expand Down Expand Up @@ -862,17 +864,6 @@ void RTDEF(AssignPolymorphic)(Descriptor &to, const Descriptor &from,
PolymorphicLHS);
}

#if defined(OMP_OFFLOAD_BUILD)
// To support a recently added use of variant in the OpenMP offload build,
// added an abort wrapper which calls the flang-rt FortranAAbort.
// Avoids the following linker error:
// ld.lld: error: undefined symbol: abort
// >>> referenced by /tmp/device_aassign.amdgcn.gfx90a-34a7ed.img.lto.o:(std::__throw_bad_variant_access(char const*))
extern "C" void abort(void) {
RTNAME(Abort)();
}
#endif

RT_EXT_API_GROUP_END
} // extern "C"
} // namespace Fortran::runtime
2 changes: 2 additions & 0 deletions flang-rt/lib/runtime/descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

#include "flang-rt/runtime/descriptor.h"
#include "ISO_Fortran_util.h"
#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
#include "memory.h"
#endif
#include "flang-rt/runtime/allocator-registry.h"
#include "flang-rt/runtime/derived.h"
#include "flang-rt/runtime/stat.h"
Expand Down
4 changes: 4 additions & 0 deletions flang-rt/lib/runtime/edit-input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,11 @@ static RT_API_ATTRS void RaiseFPExceptions(
#ifdef feraisexcept // a macro in some environments; omit std::
#define RAISE feraiseexcept
#else
#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined (EMBED_FLANG_RT_GPU_LLVM_IR)
#define RAISE std::feraiseexcept
#else
#define RAISE
#endif
#endif
#endif // !defined(RT_DEVICE_COMPILATION)

Expand Down
2 changes: 2 additions & 0 deletions flang-rt/lib/runtime/environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//

#if (not defined (__AMDGPU__) && not defined(__NVPTX__)) || not defined (EMBED_FLANG_RT_GPU_LLVM_IR)
#include "flang-rt/runtime/environment.h"
#include "environment-default-list.h"
#include "memory.h"
Expand Down Expand Up @@ -314,3 +315,4 @@ bool RTNAME(RegisterConfigureEnv)(
} // extern "C"

} // namespace Fortran::runtime
#endif
2 changes: 2 additions & 0 deletions flang-rt/lib/runtime/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//

#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
#include "flang-rt/runtime/file.h"
#include "flang-rt/runtime/memory.h"
#include "flang-rt/runtime/tools.h"
Expand Down Expand Up @@ -486,3 +487,4 @@ RT_API_ATTRS std::int64_t SizeInBytes(const char *path) {
#endif // defined(RT_DEVICE_COMPILATION)

} // namespace Fortran::runtime::io
#endif
8 changes: 8 additions & 0 deletions flang-rt/lib/runtime/io-api-minimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace Fortran::runtime::io {
RT_EXT_API_GROUP_BEGIN
#endif

#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
Cookie IODEF(BeginExternalListOutput)(
ExternalUnit unitNumber, const char *sourceFile, int sourceLine) {
return BeginExternalListIO<Direction::Output, ExternalListIoStatementState>(
Expand All @@ -33,6 +34,7 @@ enum Iostat IODEF(EndIoStatement)(Cookie cookie) {
IoStatementState &io{*cookie};
return static_cast<enum Iostat>(io.EndIoStatement());
}
#endif

template <int KIND, typename INT = CppTypeFor<TypeCategory::Integer, KIND>>
inline RT_API_ATTRS bool FormattedScalarIntegerOutput(
Expand All @@ -45,6 +47,7 @@ inline RT_API_ATTRS bool FormattedScalarIntegerOutput(
}
}

#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
bool IODEF(OutputInteger8)(Cookie cookie, std::int8_t n) {
return FormattedScalarIntegerOutput<1>(*cookie, n, "OutputInteger8");
}
Expand All @@ -60,6 +63,7 @@ bool IODEF(OutputInteger32)(Cookie cookie, std::int32_t n) {
bool IODEF(OutputInteger64)(Cookie cookie, std::int64_t n) {
return FormattedScalarIntegerOutput<8>(*cookie, n, "OutputInteger64");
}
#endif

#ifdef __SIZEOF_INT128__
bool IODEF(OutputInteger128)(Cookie cookie, common::int128_t n) {
Expand All @@ -79,13 +83,15 @@ inline RT_API_ATTRS bool FormattedScalarRealOutput(
}
}

#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
bool IODEF(OutputReal32)(Cookie cookie, float x) {
return FormattedScalarRealOutput<4>(*cookie, x, "OutputReal32");
}

bool IODEF(OutputReal64)(Cookie cookie, double x) {
return FormattedScalarRealOutput<8>(*cookie, x, "OutputReal64");
}
#endif

template <int KIND,
typename REAL = typename RealOutputEditing<KIND>::BinaryFloatingPoint>
Expand All @@ -110,6 +116,7 @@ inline RT_API_ATTRS bool FormattedScalarComplexOutput(
return false;
}

#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
bool IODEF(OutputComplex32)(Cookie cookie, float re, float im) {
return FormattedScalarComplexOutput<4>(*cookie, re, im, "OutputComplex32");
}
Expand Down Expand Up @@ -145,6 +152,7 @@ bool IODEF(OutputLogical)(Cookie cookie, bool truth) {
return false;
}
}
#endif

} // namespace Fortran::runtime::io

Expand Down
2 changes: 2 additions & 0 deletions flang-rt/lib/runtime/io-api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,14 @@ RT_API_ATTRS Cookie BeginExternalFormattedIO(const char *format,
}
}

#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
Cookie IODEF(BeginExternalFormattedOutput)(const char *format,
std::size_t formatLength, const Descriptor *formatDescriptor,
ExternalUnit unitNumber, const char *sourceFile, int sourceLine) {
return BeginExternalFormattedIO<Direction::Output>(format, formatLength,
formatDescriptor, unitNumber, sourceFile, sourceLine);
}
#endif

Cookie IODEF(BeginExternalFormattedInput)(const char *format,
std::size_t formatLength, const Descriptor *formatDescriptor,
Expand Down
13 changes: 12 additions & 1 deletion flang-rt/lib/runtime/stop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@
#include "flang-rt/runtime/file.h"
#include "flang-rt/runtime/io-error.h"
#include "flang-rt/runtime/terminator.h"
#if not defined(__AMDGPU__) && not defined(__NVPTX__)
#include "flang/Runtime/main.h"
#endif
#include <cfenv>
#include <cstdio>
#include <cstdlib>
#if not defined(__AMDGPU__) && not defined(__NVPTX__)
#include <thread>
#endif

#ifdef HAVE_BACKTRACE
#include BACKTRACE_HEADER
Expand All @@ -26,6 +30,7 @@
extern "C" {

[[maybe_unused]] static void DescribeIEEESignaledExceptions() {
#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
#ifdef fetestexcept // a macro in some environments; omit std::
auto excepts{fetestexcept(FE_ALL_EXCEPT)};
#else
Expand Down Expand Up @@ -60,13 +65,15 @@ extern "C" {
#endif
std::fputc('\n', stderr);
}
#endif
}

static void CloseAllExternalUnits(const char *why) {
Fortran::runtime::io::IoErrorHandler handler{why};
Fortran::runtime::io::ExternalFileUnit::CloseAll(handler);
}

#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
[[noreturn]] RT_API_ATTRS void RTNAME(StopStatement)(
int code, bool isErrorStop, bool quiet) {
#if defined(RT_DEVICE_COMPILATION)
Expand Down Expand Up @@ -103,7 +110,9 @@ static void CloseAllExternalUnits(const char *why) {
std::exit(code);
#endif
}
#endif

#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
[[noreturn]] RT_API_ATTRS void RTNAME(StopStatementText)(
const char *code, std::size_t length, bool isErrorStop, bool quiet) {
#if defined(RT_DEVICE_COMPILATION)
Expand Down Expand Up @@ -136,6 +145,7 @@ static void CloseAllExternalUnits(const char *why) {
}
#endif
}
#endif

static bool StartPause() {
if (Fortran::runtime::io::IsATerminal(0)) {
Expand Down Expand Up @@ -218,13 +228,14 @@ static RT_NOINLINE_ATTR void PrintBacktrace() {

#endif
}

#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
[[noreturn]] RT_OPTNONE_ATTR void RTNAME(Abort)() {
#ifdef HAVE_BACKTRACE
PrintBacktrace();
#endif
std::abort();
}
#endif

RT_OPTNONE_ATTR void FORTRAN_PROCEDURE_NAME(backtrace)() { PrintBacktrace(); }

Expand Down
5 changes: 4 additions & 1 deletion flang/include/flang/Runtime/extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@

#define FORTRAN_PROCEDURE_NAME(name) name##_

#ifdef _WIN32
#if defined (_WIN32)
// UID and GID don't exist on Windows, these exist to avoid errors.
typedef std::uint32_t uid_t;
typedef std::uint32_t gid_t;
#elif (defined(__AMDGPU__) || defined(__NVPTX__)) && defined (EMBED_FLANG_RT_GPU_LLVM_IR)
typedef std::uint32_t uid_t;
typedef std::uint32_t gid_t;
#else
#include "sys/types.h" //pid_t
#endif
Expand Down
4 changes: 4 additions & 0 deletions flang/include/flang/Runtime/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@

#include "flang/Runtime/c-or-cpp.h"
#include "flang/Runtime/entry-names.h"
#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
#include <thread>
#endif

struct EnvironmentDefaultList;

#if (not defined(__AMDGPU__) && not defined(__NVPTX__)) || not defined(EMBED_FLANG_RT_GPU_LLVM_IR)
std::thread::id RTNAME(GetMainThreadId)();
#endif

FORTRAN_EXTERN_C_BEGIN
void RTNAME(ProgramStart)(
Expand Down
1 change: 1 addition & 0 deletions libc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ if(NOT LIBC_NAMESPACE MATCHES "^__llvm_libc")
message(FATAL_ERROR "Invalid LIBC_NAMESPACE. Must start with '__llvm_libc' was '${LIBC_NAMESPACE}'")
endif()

string(REPLACE "." "_" LIBC_NAMESPACE "${LIBC_NAMESPACE}")
message(STATUS "Setting LIBC_NAMESPACE namespace to '${LIBC_NAMESPACE}'")
add_compile_definitions(LIBC_NAMESPACE=${LIBC_NAMESPACE})

Expand Down
2 changes: 2 additions & 0 deletions libcxx/src/string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +360,11 @@ wstring to_wstring(unsigned long val) { return i_to_string<wstring>(val); }
wstring to_wstring(unsigned long long val) { return i_to_string<wstring>(val); }
#endif

#if not defined(__AMDGPU__) && not defined(__NVPTX__)
string to_string(float val) { return as_string(snprintf, initial_string< string>()(), "%f", val); }
string to_string(double val) { return as_string(snprintf, initial_string< string>()(), "%f", val); }
string to_string(long double val) { return as_string(snprintf, initial_string< string>()(), "%Lf", val); }
#endif

#if _LIBCPP_HAS_WIDE_CHARACTERS
wstring to_wstring(float val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%f", val); }
Expand Down
1 change: 0 additions & 1 deletion offload/plugins-nextgen/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ if(OFFLOAD_ENABLE_EMISSARY_APIS AND LIBOMPTARGET_BUILD_DEVICE_FORTRT)
target_link_libraries(PluginCommon PRIVATE flang_rt.runtime
-L${CMAKE_BINARY_DIR}/../../lib -L${CMAKE_INSTALL_PREFIX}/lib)
endif()

if (OMPT_TARGET_DEFAULT AND LIBOMPTARGET_OMPT_SUPPORT)
add_library(PluginOmpt STATIC OMPT/OmptTracing.cpp OMPT/OmptProfiler.cpp)
target_include_directories(PluginOmpt PUBLIC
Expand Down