[flang-commits] [flang] 8f3f15c - [flang] Configure FirOpBuilder based on math driver options.

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Mon Nov 7 09:27:00 PST 2022


Author: Slava Zakharin
Date: 2022-11-07T09:26:46-08:00
New Revision: 8f3f15c1a208932689a8bdef22d6ca3d4c3408c5

URL: https://github.com/llvm/llvm-project/commit/8f3f15c1a208932689a8bdef22d6ca3d4c3408c5
DIFF: https://github.com/llvm/llvm-project/commit/8f3f15c1a208932689a8bdef22d6ca3d4c3408c5.diff

LOG: [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

Added: 
    flang/include/flang/Common/MathOptionsBase.def
    flang/include/flang/Common/MathOptionsBase.h
    flang/test/Lower/fast-math-arithmetic.f90

Modified: 
    flang/include/flang/Lower/LoweringOptions.h
    flang/include/flang/Optimizer/Builder/FIRBuilder.h
    flang/lib/Frontend/CompilerInvocation.cpp
    flang/lib/Lower/Bridge.cpp
    flang/lib/Lower/LoweringOptions.cpp
    flang/lib/Optimizer/Builder/FIRBuilder.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Common/MathOptionsBase.def b/flang/include/flang/Common/MathOptionsBase.def
new file mode 100644
index 0000000000000..64b3959a1c53e
--- /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 0000000000000..7f8ebdbee1987
--- /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 dd297e41bded2..8105ccd7ef6b1 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 @@ class LoweringOptions : public LoweringOptionsBase {
 #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 5a43b1705c749..a28ada96ecf7a 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 @@ class FirOpBuilder : public mlir::OpBuilder, public mlir::OpBuilder::Listener {
     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 bb87ea285a265..f2180145af714 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 e9490b80566fe..6ab001b850fd2 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -2884,6 +2884,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
     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 @@ class FirConverter : public Fortran::lower::AbstractConverter {
         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 22247faa4cab9..9456abf0e8dea 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 59cc0583c24c5..50fc21b0f256b 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 0000000000000..cc7a7dcf210e3
--- /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


        


More information about the flang-commits mailing list