[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