diff options
author | Tom Eccles <Tom.Eccles@arm.com> | 2022-10-31 14:30:32 +0300 |
---|---|---|
committer | Kiran Chandramohan <kiran.chandramohan@arm.com> | 2022-10-31 14:32:31 +0300 |
commit | a784de783af5096e593c5e214c2c78215fe303f5 (patch) | |
tree | 2a28ce1db23ec96938387b793fb90b0fa1efc785 /flang | |
parent | 0fe945300524ab0d92842f236cfee867204aed14 (diff) |
[flang] Add -ffp-contract option processing
Only add the option processing and store the result. No attributes are
added to FIR yet.
Only the "off" and "fast" options are supported. "fast-honor-pragmas" is not applicable because we do not implement `#pragma clang fp contract()` in Fortran [1]. "on" is not supported because it is unclear how to fuse only within individual statements. gfortran also does not implement "on": treating it as an "off".
Currently the default value is "off" to preserve existing behavior. gfortran uses "fast" by default and that may be the right thing for flang-new after further discussion in the future, but that can be changed separately. gfortran's documentation is available [[ https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html | here ]].
[1] https://clang.llvm.org/docs/LanguageExtensions.html#extensions-to-specify-floating-point-flags
Reviewed By: vzakhari, awarzynski
Differential Revision: https://reviews.llvm.org/D136080
Diffstat (limited to 'flang')
-rw-r--r-- | flang/include/flang/Frontend/CompilerInvocation.h | 7 | ||||
-rw-r--r-- | flang/include/flang/Frontend/LangOptions.def | 25 | ||||
-rw-r--r-- | flang/include/flang/Frontend/LangOptions.h | 60 | ||||
-rw-r--r-- | flang/lib/Frontend/CMakeLists.txt | 1 | ||||
-rw-r--r-- | flang/lib/Frontend/CompilerInvocation.cpp | 38 | ||||
-rw-r--r-- | flang/lib/Frontend/LangOptions.cpp | 24 | ||||
-rw-r--r-- | flang/test/Driver/driver-help-hidden.f90 | 1 | ||||
-rw-r--r-- | flang/test/Driver/driver-help.f90 | 2 | ||||
-rw-r--r-- | flang/test/Driver/flang_f_opts.f90 | 4 | ||||
-rw-r--r-- | flang/test/Driver/flang_fp_opts.f90 | 4 | ||||
-rw-r--r-- | flang/test/Driver/frontend-forwarding.f90 | 2 |
11 files changed, 167 insertions, 1 deletions
diff --git a/flang/include/flang/Frontend/CompilerInvocation.h b/flang/include/flang/Frontend/CompilerInvocation.h index 3a6dafa301d3..a5895451bb74 100644 --- a/flang/include/flang/Frontend/CompilerInvocation.h +++ b/flang/include/flang/Frontend/CompilerInvocation.h @@ -15,6 +15,7 @@ #include "flang/Frontend/CodeGenOptions.h" #include "flang/Frontend/FrontendOptions.h" +#include "flang/Frontend/LangOptions.h" #include "flang/Frontend/PreprocessorOptions.h" #include "flang/Frontend/TargetOptions.h" #include "flang/Lower/LoweringOptions.h" @@ -78,6 +79,9 @@ class CompilerInvocation : public CompilerInvocationBase { /// Options controlling IRgen and the backend. Fortran::frontend::CodeGenOptions codeGenOpts; + /// Options controlling language dialect. + Fortran::frontend::LangOptions langOpts; + // Semantics context std::unique_ptr<Fortran::semantics::SemanticsContext> semanticsContext; @@ -140,6 +144,9 @@ public: CodeGenOptions &getCodeGenOpts() { return codeGenOpts; } const CodeGenOptions &getCodeGenOpts() const { return codeGenOpts; } + LangOptions &getLangOpts() { return langOpts; } + const LangOptions &getLangOpts() const { return langOpts; } + Fortran::lower::LoweringOptions &getLoweringOpts() { return loweringOpts; } const Fortran::lower::LoweringOptions &getLoweringOpts() const { return loweringOpts; diff --git a/flang/include/flang/Frontend/LangOptions.def b/flang/include/flang/Frontend/LangOptions.def new file mode 100644 index 000000000000..c4d0ec5329b2 --- /dev/null +++ b/flang/include/flang/Frontend/LangOptions.def @@ -0,0 +1,25 @@ +//===------ LangOptions.def - Code generation option database ----- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines the language dialect options. Users of this file +// must define the LANGOPT macro to make use of this information. +// +//===----------------------------------------------------------------------===// +#ifndef LANGOPT +# error Define the LANGOPT macro to handle language options +#endif + +#ifndef ENUM_LANGOPT +# define ENUM_LANGOPT(Name, Type, Bits, Default) \ +LANGOPT(Name, Bits, Default) +#endif + +ENUM_LANGOPT(FPContractMode, FPModeKind, 2, FPM_Off) ///< FP Contract Mode (off/fast) + +#undef LANGOPT +#undef ENUM_LANGOPT diff --git a/flang/include/flang/Frontend/LangOptions.h b/flang/include/flang/Frontend/LangOptions.h new file mode 100644 index 000000000000..c8edbfdbc8d1 --- /dev/null +++ b/flang/include/flang/Frontend/LangOptions.h @@ -0,0 +1,60 @@ +//===------ LangOptions.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 +// +//===----------------------------------------------------------------------===// +// +// This file defines the LangOptions interface, which holds the +// configuration for LLVM's middle-end and back-end. It controls LLVM's code +// generation into assembly or machine code. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_FLANG_FRONTEND_LANGOPTIONS_H +#define LLVM_FLANG_FRONTEND_LANGOPTIONS_H + +namespace Fortran::frontend { + +/// Bitfields of LangOptions, split out from LangOptions to ensure +/// that this large collection of bitfields is a trivial class type. +class LangOptionsBase { + +public: + enum FPModeKind { + // Do not fuse FP ops + FPM_Off, + + // Aggressively fuse FP ops (E.g. FMA). + FPM_Fast, + }; + +#define LANGOPT(Name, Bits, Default) unsigned Name : Bits; +#define ENUM_LANGOPT(Name, Type, Bits, Default) +#include "flang/Frontend/LangOptions.def" + +protected: +#define LANGOPT(Name, Bits, Default) +#define ENUM_LANGOPT(Name, Type, Bits, Default) unsigned Name : Bits; +#include "flang/Frontend/LangOptions.def" +}; + +/// Tracks various options which control the dialect of Fortran that is +/// accepted. Based on clang::LangOptions +class LangOptions : public LangOptionsBase { + +public: + // Define accessors/mutators for code generation options of enumeration type. +#define LANGOPT(Name, Bits, Default) +#define ENUM_LANGOPT(Name, Type, Bits, Default) \ + Type get##Name() const { return static_cast<Type>(Name); } \ + void set##Name(Type Value) { Name = static_cast<unsigned>(Value); } +#include "flang/Frontend/LangOptions.def" + + LangOptions(); +}; + +} // end namespace Fortran::frontend + +#endif diff --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt index 45fc97867e18..4abca70acaba 100644 --- a/flang/lib/Frontend/CMakeLists.txt +++ b/flang/lib/Frontend/CMakeLists.txt @@ -7,6 +7,7 @@ add_flang_library(flangFrontend FrontendAction.cpp FrontendActions.cpp FrontendOptions.cpp + LangOptions.cpp TextDiagnosticPrinter.cpp TextDiagnosticBuffer.cpp TextDiagnostic.cpp diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 761300b807cc..3a64086be33d 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -658,6 +658,42 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args, return diags.getNumErrors() == numErrorsBefore; } +/// Parses all floating point related arguments and populates the +/// CompilerInvocation accordingly. +/// Returns false if new errors are generated. +/// +/// \param [out] invoc Stores the processed arguments +/// \param [in] args The compiler invocation arguments to parse +/// \param [out] diags DiagnosticsEngine to report erros with +static bool parseFloatingPointArgs(CompilerInvocation &invoc, + llvm::opt::ArgList &args, + clang::DiagnosticsEngine &diags) { + LangOptions &opts = invoc.getLangOpts(); + const unsigned diagUnimplemented = diags.getCustomDiagID( + clang::DiagnosticsEngine::Warning, "%0 is not currently implemented"); + + if (const llvm::opt::Arg *a = + args.getLastArg(clang::driver::options::OPT_ffp_contract)) { + const llvm::StringRef val = a->getValue(); + enum LangOptions::FPModeKind fpContractMode; + + if (val == "off") + fpContractMode = LangOptions::FPM_Off; + else if (val == "fast") + fpContractMode = LangOptions::FPM_Fast; + else { + diags.Report(clang::diag::err_drv_unsupported_option_argument) + << a->getOption().getName() << val; + return false; + } + + diags.Report(diagUnimplemented) << a->getOption().getName(); + opts.setFPContractMode(fpContractMode); + } + + return true; +} + bool CompilerInvocation::createFromArgs( CompilerInvocation &res, llvm::ArrayRef<const char *> commandLineArgs, clang::DiagnosticsEngine &diags) { @@ -712,6 +748,8 @@ bool CompilerInvocation::createFromArgs( res.frontendOpts.mlirArgs = args.getAllArgValues(clang::driver::options::OPT_mmlir); + success &= parseFloatingPointArgs(res, args, diags); + return success; } diff --git a/flang/lib/Frontend/LangOptions.cpp b/flang/lib/Frontend/LangOptions.cpp new file mode 100644 index 000000000000..a08cb363384c --- /dev/null +++ b/flang/lib/Frontend/LangOptions.cpp @@ -0,0 +1,24 @@ +//===------ LangOptions.cpp -----------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ +// +//===----------------------------------------------------------------------===// + +#include "flang/Frontend/LangOptions.h" +#include <string.h> + +namespace Fortran::frontend { + +LangOptions::LangOptions() { +#define LANGOPT(Name, Bits, Default) Name = Default; +#define ENUM_LANGOPT(Name, Type, Bits, Default) set##Name(Default); +#include "flang/Frontend/LangOptions.def" +} + +} // end namespace Fortran::frontend diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90 index e6309bb9fd6d..d2dc82ea1b52 100644 --- a/flang/test/Driver/driver-help-hidden.f90 +++ b/flang/test/Driver/driver-help-hidden.f90 @@ -31,6 +31,7 @@ ! CHECK-NEXT: -ffixed-form Process source files in fixed form ! CHECK-NEXT: -ffixed-line-length=<value> ! CHECK-NEXT: Use <value> as character line width in fixed mode +! CHECK-NEXT: -ffp-contract=<value> Form fused FP ops (e.g. FMAs) ! CHECK-NEXT: -ffree-form Process source files in free form ! CHECK-NEXT: -fimplicit-none No implicit typing allowed unless overridden by IMPLICIT statements ! CHECK-NEXT: -finput-charset=<value> Specify the default character set for source files diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 index daddd254b618..3ab509c7129e 100644 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -31,6 +31,7 @@ ! HELP-NEXT: -ffixed-form Process source files in fixed form ! HELP-NEXT: -ffixed-line-length=<value> ! HELP-NEXT: Use <value> as character line width in fixed mode +! HELP-NEXT: -ffp-contract=<value> Form fused FP ops (e.g. FMAs) ! HELP-NEXT: -ffree-form Process source files in free form ! HELP-NEXT: -fimplicit-none No implicit typing allowed unless overridden by IMPLICIT statements ! HELP-NEXT: -finput-charset=<value> Specify the default character set for source files @@ -105,6 +106,7 @@ ! HELP-FC1-NEXT: -ffixed-form Process source files in fixed form ! HELP-FC1-NEXT: -ffixed-line-length=<value> ! HELP-FC1-NEXT: Use <value> as character line width in fixed mode +! HELP-FC1-NEXT: -ffp-contract=<value> Form fused FP ops (e.g. FMAs) ! HELP-FC1-NEXT: -ffree-form Process source files in free form ! HELP-FC1-NEXT: -fget-definition <value> <value> <value> ! HELP-FC1-NEXT: Get the symbol definition from <line> <start-column> <end-column> diff --git a/flang/test/Driver/flang_f_opts.f90 b/flang/test/Driver/flang_f_opts.f90 index a0544d653104..4493a519e201 100644 --- a/flang/test/Driver/flang_f_opts.f90 +++ b/flang/test/Driver/flang_f_opts.f90 @@ -1,8 +1,10 @@ ! Test for warnings generated when parsing driver options. You can use this file for relatively small tests and to avoid creating ! new test files. -! RUN: %flang -### -S -O4 %s 2>&1 | FileCheck %s +! RUN: %flang -### -S -O4 -ffp-contract=on %s 2>&1 | FileCheck %s +! CHECK: warning: the argument 'on' is not supported for option 'ffp-contract='. Mapping to 'ffp-contract=off' ! CHECK: warning: -O4 is equivalent to -O3 ! CHECK-LABEL: "-fc1" +! CHECK: -ffp-contract=off ! CHECK: -O3 diff --git a/flang/test/Driver/flang_fp_opts.f90 b/flang/test/Driver/flang_fp_opts.f90 new file mode 100644 index 000000000000..34987f4b0c43 --- /dev/null +++ b/flang/test/Driver/flang_fp_opts.f90 @@ -0,0 +1,4 @@ +! Test for handling of floating point options within the frontend driver + +! RUN: %flang_fc1 -ffp-contract=fast %s 2>&1 | FileCheck %s +! CHECK: ffp-contract= is not currently implemented diff --git a/flang/test/Driver/frontend-forwarding.f90 b/flang/test/Driver/frontend-forwarding.f90 index 7d8243d84a15..b956940fd7d2 100644 --- a/flang/test/Driver/frontend-forwarding.f90 +++ b/flang/test/Driver/frontend-forwarding.f90 @@ -8,6 +8,7 @@ ! RUN: -fdefault-real-8 \ ! RUN: -flarge-sizes \ ! RUN: -fconvert=little-endian \ +! RUN: -ffp-contract=fast \ ! RUN: -mllvm -print-before-all\ ! RUN: -P \ ! RUN: | FileCheck %s @@ -18,5 +19,6 @@ ! CHECK: "-fdefault-integer-8" ! CHECK: "-fdefault-real-8" ! CHECK: "-flarge-sizes" +! CHECK: "-ffp-contract=fast" ! CHECK: "-fconvert=little-endian" ! CHECK: "-mllvm" "-print-before-all" |