diff options
author | Slava Zakharin <szakharin@nvidia.com> | 2022-11-07 20:05:27 +0300 |
---|---|---|
committer | Slava Zakharin <szakharin@nvidia.com> | 2022-11-07 20:26:46 +0300 |
commit | 8f3f15c1a208932689a8bdef22d6ca3d4c3408c5 (patch) | |
tree | 9706a092f635c9966110478632557745ed163b0f /flang | |
parent | fe2069284d10f78c6472f5934983c5740dea8039 (diff) |
[flang] Configure FirOpBuilder based on math driver options.
Added MathOptionsBase to share fastmath config between different
components. Frontend driver translates LangOptions into MathOptionsBase.
FirConverter configures FirOpBuilder using MathOptionsBase
config passed to it via LoweringOptions.
Depends on D137390
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D137391
Diffstat (limited to 'flang')
-rw-r--r-- | flang/include/flang/Common/MathOptionsBase.def | 25 | ||||
-rw-r--r-- | flang/include/flang/Common/MathOptionsBase.h | 44 | ||||
-rw-r--r-- | flang/include/flang/Lower/LoweringOptions.h | 12 | ||||
-rw-r--r-- | flang/include/flang/Optimizer/Builder/FIRBuilder.h | 5 | ||||
-rw-r--r-- | flang/lib/Frontend/CompilerInvocation.cpp | 12 | ||||
-rw-r--r-- | flang/lib/Lower/Bridge.cpp | 3 | ||||
-rw-r--r-- | flang/lib/Lower/LoweringOptions.cpp | 2 | ||||
-rw-r--r-- | flang/lib/Optimizer/Builder/FIRBuilder.cpp | 12 | ||||
-rw-r--r-- | flang/test/Lower/fast-math-arithmetic.f90 | 13 |
9 files changed, 126 insertions, 2 deletions
diff --git a/flang/include/flang/Common/MathOptionsBase.def b/flang/include/flang/Common/MathOptionsBase.def new file mode 100644 index 000000000000..64b3959a1c53 --- /dev/null +++ b/flang/include/flang/Common/MathOptionsBase.def @@ -0,0 +1,25 @@ +//===--- MathOptionsBase.def - Math options config ---------------- 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file defines math options. Users of this file must define +/// ENUM_MATHOPT macro to make use of this information. +/// +//===----------------------------------------------------------------------===// + +#ifndef ENUM_MATHOPT +# error Define the ENUM_MATHOPT macro to handle lowering options +#endif + +/// Allow fusing FP operations (e.g. create FMAs from mul/add). +ENUM_MATHOPT(FPContractEnabled, unsigned, 1, 0) + +/// Permit floating point optimizations without regard to infinities. +ENUM_MATHOPT(NoHonorInfs, unsigned, 1, 0) + +#undef ENUM_MATHOPT diff --git a/flang/include/flang/Common/MathOptionsBase.h b/flang/include/flang/Common/MathOptionsBase.h new file mode 100644 index 000000000000..7f8ebdbee198 --- /dev/null +++ b/flang/include/flang/Common/MathOptionsBase.h @@ -0,0 +1,44 @@ +//===- MathOptionsBase.h - Math options config ------------------*- 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Options controlling mathematical computations generated in FIR. +/// This is intended to be header-only implementation without extra +/// dependencies so that multiple components can use it to exchange +/// math configuration. +/// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_COMMON_MATHOPTIONSBASE_H +#define FORTRAN_COMMON_MATHOPTIONSBASE_H + +namespace Fortran::common { + +class MathOptionsBase { +public: +#define ENUM_MATHOPT(Name, Type, Bits, Default) \ + Type get##Name() const { return static_cast<Type>(Name); } \ + MathOptionsBase &set##Name(Type Value) { \ + Name = static_cast<unsigned>(Value); \ + return *this; \ + } +#include "flang/Common/MathOptionsBase.def" + + MathOptionsBase() { +#define ENUM_MATHOPT(Name, Type, Bits, Default) set##Name(Default); +#include "flang/Common/MathOptionsBase.def" + } + +private: +#define ENUM_MATHOPT(Name, Type, Bits, Default) unsigned Name : Bits; +#include "flang/Common/MathOptionsBase.def" +}; + +} // namespace Fortran::common + +#endif // FORTRAN_COMMON_MATHOPTIONSBASE_H diff --git a/flang/include/flang/Lower/LoweringOptions.h b/flang/include/flang/Lower/LoweringOptions.h index dd297e41bded..8105ccd7ef6b 100644 --- a/flang/include/flang/Lower/LoweringOptions.h +++ b/flang/include/flang/Lower/LoweringOptions.h @@ -15,6 +15,8 @@ #ifndef FLANG_LOWER_LOWERINGOPTIONS_H #define FLANG_LOWER_LOWERINGOPTIONS_H +#include "flang/Common/MathOptionsBase.h" + namespace Fortran::lower { class LoweringOptionsBase { @@ -42,6 +44,16 @@ public: #include "flang/Lower/LoweringOptions.def" LoweringOptions(); + + const Fortran::common::MathOptionsBase &getMathOptions() const { + return MathOptions; + } + + Fortran::common::MathOptionsBase &getMathOptions() { return MathOptions; } + +private: + /// Options for handling/optimizing mathematical computations. + Fortran::common::MathOptionsBase MathOptions; }; } // namespace Fortran::lower diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h index 5a43b1705c74..a28ada96ecf7 100644 --- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h +++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h @@ -16,6 +16,7 @@ #ifndef FORTRAN_OPTIMIZER_BUILDER_FIRBUILDER_H #define FORTRAN_OPTIMIZER_BUILDER_FIRBUILDER_H +#include "flang/Common/MathOptionsBase.h" #include "flang/Optimizer/Dialect/FIROps.h" #include "flang/Optimizer/Dialect/FIRType.h" #include "flang/Optimizer/Support/KindMapping.h" @@ -409,6 +410,10 @@ public: fastMathFlags = flags; } + /// Set default FastMathFlags value from the passed MathOptionsBase + /// config. + void setFastMathFlags(Fortran::common::MathOptionsBase options); + /// Dump the current function. (debug) LLVM_DUMP_METHOD void dumpFunc(); diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index bb87ea285a26..f2180145af71 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -944,8 +944,18 @@ void CompilerInvocation::setSemanticsOpts( /// Set \p loweringOptions controlling lowering behavior based /// on the \p optimizationLevel. void CompilerInvocation::setLoweringOptions() { - const auto &codegenOpts = getCodeGenOpts(); + const CodeGenOptions &codegenOpts = getCodeGenOpts(); // Lower TRANSPOSE as a runtime call under -O0. loweringOpts.setOptimizeTranspose(codegenOpts.OptimizationLevel > 0); + + const LangOptions &langOptions = getLangOpts(); + Fortran::common::MathOptionsBase &mathOpts = loweringOpts.getMathOptions(); + // TODO: when LangOptions are finalized, we can represent + // the math related options using Fortran::commmon::MathOptionsBase, + // so that we can just copy it into LoweringOptions. + mathOpts + .setFPContractEnabled(langOptions.getFPContractMode() == + LangOptions::FPM_Fast) + .setNoHonorInfs(langOptions.NoHonorInfs); } diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index e9490b80566f..6ab001b850fd 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -2884,6 +2884,7 @@ private: mlir::func::FuncOp func = callee.addEntryBlockAndMapArguments(); builder = new fir::FirOpBuilder(func, bridge.getKindMap()); assert(builder && "FirOpBuilder did not instantiate"); + builder->setFastMathFlags(bridge.getLoweringOptions().getMathOptions()); builder->setInsertionPointToStart(&func.front()); func.setVisibility(mlir::SymbolTable::Visibility::Public); @@ -3087,6 +3088,8 @@ private: mlir::FunctionType::get(context, llvm::None, llvm::None)); func.addEntryBlock(); builder = new fir::FirOpBuilder(func, bridge.getKindMap()); + assert(builder && "FirOpBuilder did not instantiate"); + builder->setFastMathFlags(bridge.getLoweringOptions().getMathOptions()); createGlobals(); if (mlir::Region *region = func.getCallableRegion()) region->dropAllReferences(); diff --git a/flang/lib/Lower/LoweringOptions.cpp b/flang/lib/Lower/LoweringOptions.cpp index 22247faa4cab..9456abf0e8de 100644 --- a/flang/lib/Lower/LoweringOptions.cpp +++ b/flang/lib/Lower/LoweringOptions.cpp @@ -14,7 +14,7 @@ namespace Fortran::lower { -LoweringOptions::LoweringOptions() { +LoweringOptions::LoweringOptions() : MathOptions{} { #define LOWERINGOPT(Name, Bits, Default) Name = Default; #define ENUM_LOWERINGOPT(Name, Type, Bits, Default) set##Name(Default); #include "flang/Lower/LoweringOptions.def" diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp index 59cc0583c24c..50fc21b0f256 100644 --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -583,6 +583,18 @@ void fir::FirOpBuilder::setCommonAttributes(mlir::Operation *op) const { op->getContext(), fastMathFlags)); } +void fir::FirOpBuilder::setFastMathFlags( + Fortran::common::MathOptionsBase options) { + mlir::arith::FastMathFlags arithFMF{}; + if (options.getFPContractEnabled()) { + arithFMF = arithFMF | mlir::arith::FastMathFlags::contract; + } + if (options.getNoHonorInfs()) { + arithFMF = arithFMF | mlir::arith::FastMathFlags::ninf; + } + setFastMathFlags(arithFMF); +} + //===--------------------------------------------------------------------===// // ExtendedValue inquiry helper implementation //===--------------------------------------------------------------------===// diff --git a/flang/test/Lower/fast-math-arithmetic.f90 b/flang/test/Lower/fast-math-arithmetic.f90 new file mode 100644 index 000000000000..cc7a7dcf210e --- /dev/null +++ b/flang/test/Lower/fast-math-arithmetic.f90 @@ -0,0 +1,13 @@ +! RUN: %flang_fc1 -emit-fir -ffp-contract=fast %s -o - 2>&1 | FileCheck --check-prefixes=CONTRACT,ALL %s +! RUN: %flang_fc1 -emit-fir -menable-no-infs %s -o - 2>&1 | FileCheck --check-prefixes=NINF,ALL %s + +! ALL-LABEL: func.func @_QPtest +subroutine test(x) + real x +! CONTRACT: arith.mulf{{.*}}, {{.*}} fastmath<[[ATTRS:contract]]> : f32 +! NINF: arith.mulf{{.*}}, {{.*}} fastmath<[[ATTRS:ninf]]> : f32 +! ALL: arith.divf{{.*}}, {{.*}} fastmath<[[ATTRS]]> : f32 +! ALL: arith.addf{{.*}}, {{.*}} fastmath<[[ATTRS]]> : f32 +! ALL: arith.subf{{.*}}, {{.*}} fastmath<[[ATTRS]]> : f32 + x = x * x + x / x - x +end subroutine test |