[flang-commits] [flang] f1eb945 - [flang] Propagate lowering options from driver.

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Fri Aug 5 11:32:23 PDT 2022


Author: Slava Zakharin
Date: 2022-08-05T11:29:45-07:00
New Revision: f1eb945f9a5037b1fac6da02405047b24c0c2de5

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

LOG: [flang] Propagate lowering options from driver.

This commit addresses concerns raised in D129497.

Propagate lowering options from driver to expressions lowering
via AbstractConverter instance. A single use case so far is
using optimized TRANSPOSE lowering with O1/O2/O3.

bbc does not support optimization level switches, so it uses
default LoweringOptions (e.g. optimized TRANSPOSE lowering
is enabled by default, but an engineering -opt-transpose=false
option can still override this).

Differential Revision: https://reviews.llvm.org/D130204

Added: 
    flang/include/flang/Lower/LoweringOptions.h

Modified: 
    flang/include/flang/Frontend/CompilerInvocation.h
    flang/include/flang/Lower/AbstractConverter.h
    flang/include/flang/Lower/Bridge.h
    flang/lib/Frontend/CompilerInstance.cpp
    flang/lib/Frontend/CompilerInvocation.cpp
    flang/lib/Frontend/FrontendActions.cpp
    flang/lib/Lower/Bridge.cpp
    flang/lib/Lower/ConvertExpr.cpp
    flang/test/Lower/Intrinsics/transpose.f90
    flang/test/Lower/Intrinsics/transpose_opt.f90
    flang/tools/bbc/bbc.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Frontend/CompilerInvocation.h b/flang/include/flang/Frontend/CompilerInvocation.h
index cdc7878e93c31..3a6dafa301d38 100644
--- a/flang/include/flang/Frontend/CompilerInvocation.h
+++ b/flang/include/flang/Frontend/CompilerInvocation.h
@@ -17,6 +17,7 @@
 #include "flang/Frontend/FrontendOptions.h"
 #include "flang/Frontend/PreprocessorOptions.h"
 #include "flang/Frontend/TargetOptions.h"
+#include "flang/Lower/LoweringOptions.h"
 #include "flang/Parser/parsing.h"
 #include "flang/Semantics/semantics.h"
 #include "clang/Basic/Diagnostic.h"
@@ -68,6 +69,9 @@ class CompilerInvocation : public CompilerInvocationBase {
   // of options.
   Fortran::parser::Options parserOpts;
 
+  /// Options controlling lowering.
+  Fortran::lower::LoweringOptions loweringOpts;
+
   /// Options controlling the target.
   Fortran::frontend::TargetOptions targetOpts;
 
@@ -136,6 +140,11 @@ class CompilerInvocation : public CompilerInvocationBase {
   CodeGenOptions &getCodeGenOpts() { return codeGenOpts; }
   const CodeGenOptions &getCodeGenOpts() const { return codeGenOpts; }
 
+  Fortran::lower::LoweringOptions &getLoweringOpts() { return loweringOpts; }
+  const Fortran::lower::LoweringOptions &getLoweringOpts() const {
+    return loweringOpts;
+  }
+
   Fortran::semantics::SemanticsContext &getSemanticsContext() {
     return *semanticsContext;
   }
@@ -226,6 +235,10 @@ class CompilerInvocation : public CompilerInvocationBase {
 
   /// Set the Semantic Options
   void setSemanticsOpts(Fortran::parser::AllCookedSources &);
+
+  /// Set \p loweringOptions controlling lowering behavior based
+  /// on the \p optimizationLevel.
+  void setLoweringOptions();
 };
 
 } // end namespace Fortran::frontend

diff  --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h
index 4ee4504608bc1..0329e74979433 100644
--- a/flang/include/flang/Lower/AbstractConverter.h
+++ b/flang/include/flang/Lower/AbstractConverter.h
@@ -14,6 +14,7 @@
 #define FORTRAN_LOWER_ABSTRACTCONVERTER_H
 
 #include "flang/Common/Fortran.h"
+#include "flang/Lower/LoweringOptions.h"
 #include "flang/Lower/PFTDefs.h"
 #include "flang/Optimizer/Builder/BoxValue.h"
 #include "flang/Semantics/symbol.h"
@@ -225,7 +226,22 @@ class AbstractConverter {
   /// Get the KindMap.
   virtual const fir::KindMapping &getKindMap() = 0;
 
+  AbstractConverter(const Fortran::lower::LoweringOptions &loweringOptions)
+      : loweringOptions(loweringOptions) {}
   virtual ~AbstractConverter() = default;
+
+  //===--------------------------------------------------------------------===//
+  // Miscellaneous
+  //===--------------------------------------------------------------------===//
+
+  /// Return options controlling lowering behavior.
+  const Fortran::lower::LoweringOptions &getLoweringOptions() const {
+    return loweringOptions;
+  }
+
+private:
+  /// Options controlling lowering behavior.
+  const Fortran::lower::LoweringOptions &loweringOptions;
 };
 
 } // namespace lower

diff  --git a/flang/include/flang/Lower/Bridge.h b/flang/include/flang/Lower/Bridge.h
index 9b445e2177b40..70a171e598d3e 100644
--- a/flang/include/flang/Lower/Bridge.h
+++ b/flang/include/flang/Lower/Bridge.h
@@ -15,6 +15,7 @@
 
 #include "flang/Common/Fortran.h"
 #include "flang/Lower/AbstractConverter.h"
+#include "flang/Lower/LoweringOptions.h"
 #include "flang/Optimizer/Builder/FIRBuilder.h"
 #include "flang/Optimizer/Support/KindMapping.h"
 #include "mlir/IR/BuiltinOps.h"
@@ -52,9 +53,10 @@ class LoweringBridge {
          const Fortran::evaluate::IntrinsicProcTable &intrinsics,
          const Fortran::evaluate::TargetCharacteristics &targetCharacteristics,
          const Fortran::parser::AllCookedSources &allCooked,
-         llvm::StringRef triple, fir::KindMapping &kindMap) {
+         llvm::StringRef triple, fir::KindMapping &kindMap,
+         const Fortran::lower::LoweringOptions &loweringOptions) {
     return LoweringBridge(ctx, defaultKinds, intrinsics, targetCharacteristics,
-                          allCooked, triple, kindMap);
+                          allCooked, triple, kindMap, loweringOptions);
   }
 
   //===--------------------------------------------------------------------===//
@@ -83,6 +85,10 @@ class LoweringBridge {
   /// Get the kind map.
   const fir::KindMapping &getKindMap() const { return kindMap; }
 
+  const Fortran::lower::LoweringOptions &getLoweringOptions() const {
+    return loweringOptions;
+  }
+
   /// Create a folding context. Careful: this is very expensive.
   Fortran::evaluate::FoldingContext createFoldingContext() const;
 
@@ -107,7 +113,8 @@ class LoweringBridge {
       const Fortran::evaluate::IntrinsicProcTable &intrinsics,
       const Fortran::evaluate::TargetCharacteristics &targetCharacteristics,
       const Fortran::parser::AllCookedSources &cooked, llvm::StringRef triple,
-      fir::KindMapping &kindMap);
+      fir::KindMapping &kindMap,
+      const Fortran::lower::LoweringOptions &loweringOptions);
   LoweringBridge() = delete;
   LoweringBridge(const LoweringBridge &) = delete;
 
@@ -118,6 +125,7 @@ class LoweringBridge {
   mlir::MLIRContext &context;
   std::unique_ptr<mlir::ModuleOp> module;
   fir::KindMapping &kindMap;
+  const Fortran::lower::LoweringOptions &loweringOptions;
 };
 
 } // namespace lower

diff  --git a/flang/include/flang/Lower/LoweringOptions.h b/flang/include/flang/Lower/LoweringOptions.h
new file mode 100644
index 0000000000000..5b70e9eabc18a
--- /dev/null
+++ b/flang/include/flang/Lower/LoweringOptions.h
@@ -0,0 +1,36 @@
+//===- LoweringOptions.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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Options controlling lowering of front-end fragments to the FIR dialect
+/// of MLIR
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef FLANG_LOWER_LOWERINGOPTIONS_H
+#define FLANG_LOWER_LOWERINGOPTIONS_H
+
+namespace Fortran::lower {
+
+class LoweringOptions {
+  /// If true, lower transpose without a runtime call.
+  unsigned optimizeTranspose : 1;
+
+public:
+  LoweringOptions() : optimizeTranspose(true) {}
+
+  bool getOptimizeTranspose() const { return optimizeTranspose; }
+  LoweringOptions &setOptimizeTranspose(bool v) {
+    optimizeTranspose = v;
+    return *this;
+  }
+};
+
+} // namespace Fortran::lower
+
+#endif // FLANG_LOWER_LOWERINGOPTIONS_H

diff  --git a/flang/lib/Frontend/CompilerInstance.cpp b/flang/lib/Frontend/CompilerInstance.cpp
index 418c83cfd844c..5a33f5b26c9fb 100644
--- a/flang/lib/Frontend/CompilerInstance.cpp
+++ b/flang/lib/Frontend/CompilerInstance.cpp
@@ -151,6 +151,8 @@ bool CompilerInstance::executeAction(FrontendAction &act) {
   allSources->set_encoding(invoc.getFortranOpts().encoding);
   // Create the semantics context and set semantic options.
   invoc.setSemanticsOpts(*this->allCookedSources);
+  // Set options controlling lowering to FIR.
+  invoc.setLoweringOptions();
 
   // Run the frontend action `act` for every input file.
   for (const FrontendInputFile &fif : getFrontendOpts().inputs) {

diff  --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index f794eb7d0c445..a75c04d5962e2 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -794,3 +794,12 @@ void CompilerInvocation::setSemanticsOpts(
       .set_warningsAreErrors(getWarnAsErr())
       .set_moduleFileSuffix(getModuleFileSuffix());
 }
+
+/// Set \p loweringOptions controlling lowering behavior based
+/// on the \p optimizationLevel.
+void CompilerInvocation::setLoweringOptions() {
+  const auto &codegenOpts = getCodeGenOpts();
+
+  // Lower TRANSPOSE as a runtime call under -O0.
+  loweringOpts.setOptimizeTranspose(codegenOpts.OptimizationLevel > 0);
+}

diff  --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 7591e1a866227..4ebe2eaa2e9e4 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -148,7 +148,7 @@ bool CodeGenAction::beginSourceFileAction() {
       *mlirCtx, defKinds, ci.getInvocation().getSemanticsContext().intrinsics(),
       ci.getInvocation().getSemanticsContext().targetCharacteristics(),
       ci.getParsing().allCooked(), ci.getInvocation().getTargetOpts().triple,
-      kindMap);
+      kindMap, ci.getInvocation().getLoweringOpts());
 
   // Create a parse tree and lower it to FIR
   Fortran::parser::Program &parseTree{*ci.getParsing().parseTree()};

diff  --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 5d88d20f931aa..5dec92d90864e 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -179,7 +179,8 @@ namespace {
 class FirConverter : public Fortran::lower::AbstractConverter {
 public:
   explicit FirConverter(Fortran::lower::LoweringBridge &bridge)
-      : bridge{bridge}, foldingContext{bridge.createFoldingContext()} {}
+      : Fortran::lower::AbstractConverter(bridge.getLoweringOptions()),
+        bridge{bridge}, foldingContext{bridge.createFoldingContext()} {}
   virtual ~FirConverter() = default;
 
   /// Convert the PFT to FIR.
@@ -3243,10 +3244,11 @@ Fortran::lower::LoweringBridge::LoweringBridge(
     const Fortran::evaluate::IntrinsicProcTable &intrinsics,
     const Fortran::evaluate::TargetCharacteristics &targetCharacteristics,
     const Fortran::parser::AllCookedSources &cooked, llvm::StringRef triple,
-    fir::KindMapping &kindMap)
+    fir::KindMapping &kindMap,
+    const Fortran::lower::LoweringOptions &loweringOptions)
     : defaultKinds{defaultKinds}, intrinsics{intrinsics},
       targetCharacteristics{targetCharacteristics}, cooked{&cooked},
-      context{context}, kindMap{kindMap} {
+      context{context}, kindMap{kindMap}, loweringOptions{loweringOptions} {
   // Register the diagnostic handler.
   context.getDiagEngine().registerHandler([](mlir::Diagnostic &diag) {
     llvm::raw_ostream &os = llvm::errs();

diff  --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp
index 309fd4042f233..5929b4bfa28d8 100644
--- a/flang/lib/Lower/ConvertExpr.cpp
+++ b/flang/lib/Lower/ConvertExpr.cpp
@@ -88,8 +88,12 @@ static llvm::cl::opt<unsigned> clInitialBufferSize(
 // from the "inline" FIR, e.g. it may diagnose out-of-memory conditions
 // during the temporary allocation whereas the inline implementation
 // relies on AllocMemOp that will silently return null in case
-// there is not enough memory. So it may be a good idea to set
-// this option to false for -O0.
+// there is not enough memory.
+//
+// If it is set to false, then TRANSPOSE will be lowered using
+// a runtime call. If it is set to true, then the lowering is controlled
+// by LoweringOptions::optimizeTranspose bit (see isTransposeOptEnabled
+// function in this file).
 static llvm::cl::opt<bool> optimizeTranspose(
     "opt-transpose",
     llvm::cl::desc("lower transpose without using a runtime call"),
@@ -595,36 +599,50 @@ isIntrinsicModuleProcRef(const Fortran::evaluate::ProcedureRef &procRef) {
          module->name().ToString().find("omp_lib") == std::string::npos;
 }
 
+// Return true if TRANSPOSE should be lowered without a runtime call.
+static bool
+isTransposeOptEnabled(const Fortran::lower::AbstractConverter &converter) {
+  return optimizeTranspose &&
+         converter.getLoweringOptions().getOptimizeTranspose();
+}
+
 // A set of visitors to detect if the given expression
 // is a TRANSPOSE call that should be lowered without using
 // runtime TRANSPOSE implementation.
 template <typename T>
-static bool isOptimizableTranspose(const T &) {
+static bool isOptimizableTranspose(const T &,
+                                   const Fortran::lower::AbstractConverter &) {
   return false;
 }
 
 static bool
-isOptimizableTranspose(const Fortran::evaluate::ProcedureRef &procRef) {
+isOptimizableTranspose(const Fortran::evaluate::ProcedureRef &procRef,
+                       const Fortran::lower::AbstractConverter &converter) {
   const Fortran::evaluate::SpecificIntrinsic *intrin =
       procRef.proc().GetSpecificIntrinsic();
-  return optimizeTranspose && intrin && intrin->name == "transpose";
+  return isTransposeOptEnabled(converter) && intrin &&
+         intrin->name == "transpose";
 }
 
 template <typename T>
 static bool
-isOptimizableTranspose(const Fortran::evaluate::FunctionRef<T> &funcRef) {
+isOptimizableTranspose(const Fortran::evaluate::FunctionRef<T> &funcRef,
+                       const Fortran::lower::AbstractConverter &converter) {
   return isOptimizableTranspose(
-      static_cast<const Fortran::evaluate::ProcedureRef &>(funcRef));
+      static_cast<const Fortran::evaluate::ProcedureRef &>(funcRef), converter);
 }
 
 template <typename T>
-static bool isOptimizableTranspose(Fortran::evaluate::Expr<T> expr) {
+static bool
+isOptimizableTranspose(Fortran::evaluate::Expr<T> expr,
+                       const Fortran::lower::AbstractConverter &converter) {
   // If optimizeTranspose is not enabled, return false right away.
-  if (!optimizeTranspose)
+  if (!isTransposeOptEnabled(converter))
     return false;
 
-  return std::visit([&](const auto &e) { return isOptimizableTranspose(e); },
-                    expr.u);
+  return std::visit(
+      [&](const auto &e) { return isOptimizableTranspose(e, converter); },
+      expr.u);
 }
 
 namespace {
@@ -3289,7 +3307,7 @@ class ScalarExprLowering {
     // is used to not create a new temporary storage.
     if (isScalar(x) ||
         Fortran::evaluate::UnwrapWholeSymbolOrComponentDataRef(x) ||
-        (isTransformationalRef(x) && !isOptimizableTranspose(x)))
+        (isTransformationalRef(x) && !isOptimizableTranspose(x, converter)))
       return std::visit([&](const auto &e) { return genref(e); }, x.u);
     if (useBoxArg)
       return asArrayArg(x);
@@ -5139,7 +5157,7 @@ class ArrayExprLowering {
                 llvm::Optional<mlir::Type> retTy) {
     mlir::Location loc = getLoc();
 
-    if (isOptimizableTranspose(procRef))
+    if (isOptimizableTranspose(procRef, converter))
       return genTransposeProcRef(procRef);
 
     if (procRef.IsElemental()) {

diff  --git a/flang/test/Lower/Intrinsics/transpose.f90 b/flang/test/Lower/Intrinsics/transpose.f90
index a69613af5e567..cfd1fcd911d3e 100644
--- a/flang/test/Lower/Intrinsics/transpose.f90
+++ b/flang/test/Lower/Intrinsics/transpose.f90
@@ -1,4 +1,5 @@
 ! RUN: bbc -emit-fir %s -opt-transpose=false -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir -O0 %s -o - | FileCheck %s
 
 ! CHECK-LABEL: func @_QPtranspose_test(
 ! CHECK-SAME: %[[source:.*]]: !fir.ref<!fir.array<2x3xf32>>{{.*}}) {

diff  --git a/flang/test/Lower/Intrinsics/transpose_opt.f90 b/flang/test/Lower/Intrinsics/transpose_opt.f90
index d2807e15d9cbe..0a314a8a3ce32 100644
--- a/flang/test/Lower/Intrinsics/transpose_opt.f90
+++ b/flang/test/Lower/Intrinsics/transpose_opt.f90
@@ -1,4 +1,8 @@
 ! RUN: bbc -emit-fir %s -opt-transpose=true -o - | FileCheck %s
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir -O1 %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir -O2 %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir -O3 %s -o - | FileCheck %s
 
 ! CHECK-LABEL: func.func @_QPtranspose_test(
 ! CHECK-SAME:                               %[[VAL_0:.*]]: !fir.ref<!fir.array<2x3xf32>> {fir.bindc_name = "mat"}) {

diff  --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp
index 2ad437aa6150a..4fb3bc3ca8437 100644
--- a/flang/tools/bbc/bbc.cpp
+++ b/flang/tools/bbc/bbc.cpp
@@ -217,10 +217,12 @@ static mlir::LogicalResult convertFortranSourceToMLIR(
   auto &defKinds = semanticsContext.defaultKinds();
   fir::KindMapping kindMap(
       &ctx, llvm::ArrayRef<fir::KindTy>{fir::fromDefaultKinds(defKinds)});
+  // Use default lowering options for bbc.
+  Fortran::lower::LoweringOptions loweringOptions{};
   auto burnside = Fortran::lower::LoweringBridge::create(
       ctx, defKinds, semanticsContext.intrinsics(),
       semanticsContext.targetCharacteristics(), parsing.allCooked(), "",
-      kindMap);
+      kindMap, loweringOptions);
   burnside.lower(parseTree, semanticsContext);
   mlir::ModuleOp mlirModule = burnside.getModule();
   std::error_code ec;


        


More information about the flang-commits mailing list