Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorSlava Zakharin <szakharin@nvidia.com>2022-11-07 20:05:27 +0300
committerSlava Zakharin <szakharin@nvidia.com>2022-11-07 20:26:46 +0300
commit8f3f15c1a208932689a8bdef22d6ca3d4c3408c5 (patch)
tree9706a092f635c9966110478632557745ed163b0f /flang
parentfe2069284d10f78c6472f5934983c5740dea8039 (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.def25
-rw-r--r--flang/include/flang/Common/MathOptionsBase.h44
-rw-r--r--flang/include/flang/Lower/LoweringOptions.h12
-rw-r--r--flang/include/flang/Optimizer/Builder/FIRBuilder.h5
-rw-r--r--flang/lib/Frontend/CompilerInvocation.cpp12
-rw-r--r--flang/lib/Lower/Bridge.cpp3
-rw-r--r--flang/lib/Lower/LoweringOptions.cpp2
-rw-r--r--flang/lib/Optimizer/Builder/FIRBuilder.cpp12
-rw-r--r--flang/test/Lower/fast-math-arithmetic.f9013
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