diff options
author | peter klausler <pklausler@nvidia.com> | 2020-01-08 13:27:32 -0800 |
---|---|---|
committer | peter klausler <pklausler@nvidia.com> | 2020-01-09 10:01:59 -0800 |
commit | aeb07fbea6de56a96f5fc4443baea62d798c714f (patch) | |
tree | 70fa769aa630ce9d65392ff18f11563dd9188329 /flang/runtime | |
parent | 9744328fed40b2cd7017f3ec5a951a6cd8c35c4b (diff) | |
download | llvm-aeb07fbea6de56a96f5fc4443baea62d798c714f.tar.gz |
[flang] Runtime starting and stopping
Define ImageTerminator as a mixin-able class
Turn start.cc into main.cc
Original-commit: flang-compiler/f18@cbc6225213075a0bdd778fd25721aa8388908e07
Reviewed-on: https://github.com/flang-compiler/f18/pull/914
Diffstat (limited to 'flang/runtime')
-rw-r--r-- | flang/runtime/CMakeLists.txt | 3 | ||||
-rw-r--r-- | flang/runtime/c-or-cpp.h | 29 | ||||
-rw-r--r-- | flang/runtime/main.cc | 35 | ||||
-rw-r--r-- | flang/runtime/main.h | 18 | ||||
-rw-r--r-- | flang/runtime/stop.cc | 64 | ||||
-rw-r--r-- | flang/runtime/stop.h | 27 | ||||
-rw-r--r-- | flang/runtime/terminator.cc | 47 | ||||
-rw-r--r-- | flang/runtime/terminator.h | 42 |
8 files changed, 265 insertions, 0 deletions
diff --git a/flang/runtime/CMakeLists.txt b/flang/runtime/CMakeLists.txt index ed2ce1680625..d5ba1341c2e8 100644 --- a/flang/runtime/CMakeLists.txt +++ b/flang/runtime/CMakeLists.txt @@ -10,6 +10,9 @@ add_library(FortranRuntime ISO_Fortran_binding.cc derived-type.cc descriptor.cc + main.cc + stop.cc + terminator.cc transformational.cc type-code.cc ) diff --git a/flang/runtime/c-or-cpp.h b/flang/runtime/c-or-cpp.h new file mode 100644 index 000000000000..3b0179b2045e --- /dev/null +++ b/flang/runtime/c-or-cpp.h @@ -0,0 +1,29 @@ +//===-- runtime/c-or-cpp.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_C_OR_CPP_H_ +#define FORTRAN_RUNTIME_C_OR_CPP_H_ + +#ifdef __cplusplus +#define IF_CPLUSPLUS(x) x +#define IF_NOT_CPLUSPLUS(x) +#define DEFAULT_VALUE(x) = (x) +#else +#include <stdbool.h> +#define IF_CPLUSPLUS(x) +#define IF_NOT_CPLUSPLUS(x) x +#define DEFAULT_VALUE(x) +#endif + +#define EXTERN_C_BEGIN IF_CPLUSPLUS(extern "C" {) +#define EXTERN_C_END IF_CPLUSPLUS( \ + }) +#define NORETURN IF_CPLUSPLUS([[noreturn]]) +#define NO_ARGUMENTS IF_NOT_CPLUSPLUS(void) + +#endif // FORTRAN_RUNTIME_C_OR_CPP_H_ diff --git a/flang/runtime/main.cc b/flang/runtime/main.cc new file mode 100644 index 000000000000..dbfcd2b11d62 --- /dev/null +++ b/flang/runtime/main.cc @@ -0,0 +1,35 @@ +//===-- runtime/main.cc -----------------------------------------*- 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 +// +//----------------------------------------------------------------------------// + +#include "main.h" +#include "terminator.h" +#include <cfenv> +#include <cstdlib> + +namespace Fortran::runtime { +int argc; +const char **argv; +const char **envp; +} + +extern "C" { + +void __FortranProgram(); // PROGRAM statement + +int main(int argc, const char *argv[], const char *envp[]) { + Fortran::runtime::argc = argc; + Fortran::runtime::argv = argv; + Fortran::runtime::envp = envp; + std::feclearexcept(FE_ALL_EXCEPT); + std::fesetround(FE_TONEAREST); + std::atexit(Fortran::runtime::NotifyOtherImagesOfNormalEnd); + // TODO: Runtime configuration settings from environment + __FortranProgram(); + return EXIT_SUCCESS; +} +} diff --git a/flang/runtime/main.h b/flang/runtime/main.h new file mode 100644 index 000000000000..d93906b4f06f --- /dev/null +++ b/flang/runtime/main.h @@ -0,0 +1,18 @@ +//===-- runtime/main.cc -----------------------------------------*- 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_MAIN_H_ +#define FORTRAN_RUNTIME_MAIN_H_ + +namespace Fortran::runtime { +extern int argc; +extern const char **argv; +extern const char **envp; +} + +#endif // FORTRAN_RUNTIME_MAIN_H_ diff --git a/flang/runtime/stop.cc b/flang/runtime/stop.cc new file mode 100644 index 000000000000..250031e31809 --- /dev/null +++ b/flang/runtime/stop.cc @@ -0,0 +1,64 @@ +//===-- runtime/stop.cc -----------------------------------------*- 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 +// +//----------------------------------------------------------------------------// + +#include "stop.h" +#include "terminator.h" +#include <cfenv> +#include <cstdio> +#include <cstdlib> + +extern "C" { + +static void DescribeIEEESignaledExceptions() { + if (auto excepts{std::fetestexcept(FE_ALL_EXCEPT)}) { + std::fputs("IEEE arithmetic exceptions signaled:", stderr); + if (excepts & FE_DIVBYZERO) { + std::fputs(" DIVBYZERO", stderr); + } + if (excepts & FE_INEXACT) { + std::fputs(" INEXACT", stderr); + } + if (excepts & FE_INVALID) { + std::fputs(" INVALID", stderr); + } + if (excepts & FE_OVERFLOW) { + std::fputs(" OVERFLOW", stderr); + } + if (excepts & FE_UNDERFLOW) { + std::fputs(" UNDERFLOW", stderr); + } + } +} + +[[noreturn]] void RTNAME(StopStatement)( + int code, bool isErrorStop, bool quiet) { + if (!quiet) { + if (code != EXIT_SUCCESS) { + std::fprintf(stderr, "Fortran %s: code %d\n", + isErrorStop ? "ERROR STOP" : "STOP", code); + } + DescribeIEEESignaledExceptions(); + } + std::exit(code); +} + +[[noreturn]] void RTNAME(StopStatementText)( + const char *code, bool isErrorStop, bool quiet) { + if (!quiet) { + std::fprintf(stderr, "Fortran %s: %s\n", + isErrorStop ? "ERROR STOP" : "STOP", code); + DescribeIEEESignaledExceptions(); + } + std::exit(EXIT_FAILURE); +} + +[[noreturn]] void RTNAME(FailImageStatement)() { + Fortran::runtime::NotifyOtherImagesOfFailImageStatement(); + std::exit(EXIT_FAILURE); +} +} diff --git a/flang/runtime/stop.h b/flang/runtime/stop.h new file mode 100644 index 000000000000..5e8ea6ad26ff --- /dev/null +++ b/flang/runtime/stop.h @@ -0,0 +1,27 @@ +//===-- runtime/stop.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_STOP_H_ +#define FORTRAN_RUNTIME_STOP_H_ + +#include "c-or-cpp.h" +#include "entry-names.h" +#include <stdlib.h> + +EXTERN_C_BEGIN + +// Program-initiated image stop +NORETURN void RTNAME(StopStatement)(int code DEFAULT_VALUE(EXIT_SUCCESS), + bool isErrorStop DEFAULT_VALUE(false), bool quiet DEFAULT_VALUE(false)); +NORETURN void RTNAME(StopStatementText)(const char *, + bool isErrorStop DEFAULT_VALUE(false), bool quiet DEFAULT_VALUE(false)); +NORETURN void RTNAME(FailImageStatement)(NO_ARGUMENTS); + +EXTERN_C_END + +#endif // FORTRAN_RUNTIME_STOP_H_ diff --git a/flang/runtime/terminator.cc b/flang/runtime/terminator.cc new file mode 100644 index 000000000000..a9605d278179 --- /dev/null +++ b/flang/runtime/terminator.cc @@ -0,0 +1,47 @@ +//===-- runtime/terminate.cc ------------------------------------*- 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 +// +//----------------------------------------------------------------------------// + +#include "terminator.h" +#include <cstdio> +#include <cstdlib> + +namespace Fortran::runtime { + +[[noreturn]] void Terminator::Crash(const char *message, ...) { + va_list ap; + va_start(ap, message); + CrashArgs(message, ap); +} + +[[noreturn]] void Terminator::CrashArgs(const char *message, va_list &ap) { + std::fputs("\nfatal Fortran runtime error", stderr); + if (sourceFileName_) { + std::fprintf(stderr, "(%s", sourceFileName_); + if (sourceLine_) { + std::fprintf(stderr, ":%d", sourceLine_); + } + fputc(')', stderr); + } + std::fputs(": ", stderr); + std::vfprintf(stderr, message, ap); + fputc('\n', stderr); + va_end(ap); + NotifyOtherImagesOfErrorTermination(); + std::abort(); +} + +void NotifyOtherImagesOfNormalEnd() { + // TODO +} +void NotifyOtherImagesOfFailImageStatement() { + // TODO +} +void NotifyOtherImagesOfErrorTermination() { + // TODO +} +} diff --git a/flang/runtime/terminator.h b/flang/runtime/terminator.h new file mode 100644 index 000000000000..6d2ad201c3ad --- /dev/null +++ b/flang/runtime/terminator.h @@ -0,0 +1,42 @@ +//===-- runtime/terminator.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 +// +//----------------------------------------------------------------------------// + +// Termination of the image + +#ifndef FORTRAN_RUNTIME_TERMINATOR_H_ +#define FORTRAN_RUNTIME_TERMINATOR_H_ + +#include "entry-names.h" +#include <cstdarg> + +namespace Fortran::runtime { + +// A mixin class for statement-specific image error termination +// for errors detected in the runtime library +class Terminator { +public: + Terminator() {} + explicit Terminator(const char *sourceFileName, int sourceLine = 0) + : sourceFileName_{sourceFileName}, sourceLine_{sourceLine} {} + void SetLocation(const char *sourceFileName = nullptr, int sourceLine = 0) { + sourceFileName_ = sourceFileName; + sourceLine_ = sourceLine; + } + [[noreturn]] void Crash(const char *message, ...); + [[noreturn]] void CrashArgs(const char *message, va_list &); + +private: + const char *sourceFileName_{nullptr}; + int sourceLine_{0}; +}; + +void NotifyOtherImagesOfNormalEnd(); +void NotifyOtherImagesOfFailImageStatement(); +void NotifyOtherImagesOfErrorTermination(); +} +#endif // FORTRAN_RUNTIME_TERMINATOR_H_ |