[flang-commits] [flang] [flang][OpenMP][OpenACC] remove libEvaluate dependency in passes (PR #123784)
via flang-commits
flang-commits at lists.llvm.org
Tue Jan 21 09:20:34 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: None (jeanPerier)
<details>
<summary>Changes</summary>
Move OpenACC/OpenMP helpers from Lower/DirectivesCommon.h that are also used in OpenACC and OpenMP mlir passes into a new Optimizer/Builder/DirectivesCommon.h so that parser and evaluate headers are not included in Optimizer libraries (this both introduce compile-time and link-time pointless overheads).
This should fix https://github.com/llvm/llvm-project/issues/123377
---
Patch is 36.43 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/123784.diff
9 Files Affected:
- (modified) flang/include/flang/Lower/DirectivesCommon.h (+14-242)
- (added) flang/include/flang/Optimizer/Builder/DirectivesCommon.h (+256)
- (modified) flang/lib/Lower/OpenACC.cpp (+4-4)
- (modified) flang/lib/Lower/OpenMP/ClauseProcessor.cpp (+1-1)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+10-8)
- (modified) flang/lib/Lower/OpenMP/Utils.cpp (+4-3)
- (modified) flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp (+7-7)
- (modified) flang/lib/Optimizer/OpenMP/CMakeLists.txt (-1)
- (modified) flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp (+5-5)
``````````diff
diff --git a/flang/include/flang/Lower/DirectivesCommon.h b/flang/include/flang/Lower/DirectivesCommon.h
index 6e2c6ee4b1bcdb..c7cac1357b2277 100644
--- a/flang/include/flang/Lower/DirectivesCommon.h
+++ b/flang/include/flang/Lower/DirectivesCommon.h
@@ -29,12 +29,9 @@
#include "flang/Lower/PFTBuilder.h"
#include "flang/Lower/StatementContext.h"
#include "flang/Lower/Support/Utils.h"
-#include "flang/Optimizer/Builder/BoxValue.h"
-#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/DirectivesCommon.h"
#include "flang/Optimizer/Builder/HLFIRTools.h"
-#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/Dialect/FIRType.h"
-#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/openmp-directive-sets.h"
#include "flang/Semantics/tools.h"
@@ -49,31 +46,6 @@
namespace Fortran {
namespace lower {
-/// Information gathered to generate bounds operation and data entry/exit
-/// operations.
-struct AddrAndBoundsInfo {
- explicit AddrAndBoundsInfo() {}
- explicit AddrAndBoundsInfo(mlir::Value addr, mlir::Value rawInput)
- : addr(addr), rawInput(rawInput) {}
- explicit AddrAndBoundsInfo(mlir::Value addr, mlir::Value rawInput,
- mlir::Value isPresent)
- : addr(addr), rawInput(rawInput), isPresent(isPresent) {}
- explicit AddrAndBoundsInfo(mlir::Value addr, mlir::Value rawInput,
- mlir::Value isPresent, mlir::Type boxType)
- : addr(addr), rawInput(rawInput), isPresent(isPresent), boxType(boxType) {
- }
- mlir::Value addr = nullptr;
- mlir::Value rawInput = nullptr;
- mlir::Value isPresent = nullptr;
- mlir::Type boxType = nullptr;
- void dump(llvm::raw_ostream &os) {
- os << "AddrAndBoundsInfo addr: " << addr << "\n";
- os << "AddrAndBoundsInfo rawInput: " << rawInput << "\n";
- os << "AddrAndBoundsInfo isPresent: " << isPresent << "\n";
- os << "AddrAndBoundsInfo boxType: " << boxType << "\n";
- }
-};
-
/// Populates \p hint and \p memoryOrder with appropriate clause information
/// if present on atomic construct.
static inline void genOmpAtomicHintAndMemoryOrderClauses(
@@ -609,195 +581,13 @@ void createEmptyRegionBlocks(
}
}
-inline AddrAndBoundsInfo getDataOperandBaseAddr(fir::FirOpBuilder &builder,
- mlir::Value symAddr,
- bool isOptional,
- mlir::Location loc) {
- mlir::Value rawInput = symAddr;
- if (auto declareOp =
- mlir::dyn_cast_or_null<hlfir::DeclareOp>(symAddr.getDefiningOp())) {
- symAddr = declareOp.getResults()[0];
- rawInput = declareOp.getResults()[1];
- }
-
- if (!symAddr)
- llvm::report_fatal_error("could not retrieve symbol address");
-
- mlir::Value isPresent;
- if (isOptional)
- isPresent =
- builder.create<fir::IsPresentOp>(loc, builder.getI1Type(), rawInput);
-
- if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(
- fir::unwrapRefType(symAddr.getType()))) {
- if (mlir::isa<fir::RecordType>(boxTy.getEleTy()))
- TODO(loc, "derived type");
-
- // In case of a box reference, load it here to get the box value.
- // This is preferrable because then the same box value can then be used for
- // all address/dimension retrievals. For Fortran optional though, leave
- // the load generation for later so it can be done in the appropriate
- // if branches.
- if (mlir::isa<fir::ReferenceType>(symAddr.getType()) && !isOptional) {
- mlir::Value addr = builder.create<fir::LoadOp>(loc, symAddr);
- return AddrAndBoundsInfo(addr, rawInput, isPresent, boxTy);
- }
-
- return AddrAndBoundsInfo(symAddr, rawInput, isPresent, boxTy);
- }
- return AddrAndBoundsInfo(symAddr, rawInput, isPresent);
-}
-
-inline AddrAndBoundsInfo
+inline fir::factory::AddrAndBoundsInfo
getDataOperandBaseAddr(Fortran::lower::AbstractConverter &converter,
fir::FirOpBuilder &builder,
Fortran::lower::SymbolRef sym, mlir::Location loc) {
- return getDataOperandBaseAddr(builder, converter.getSymbolAddress(sym),
- Fortran::semantics::IsOptional(sym), loc);
-}
-
-template <typename BoundsOp, typename BoundsType>
-llvm::SmallVector<mlir::Value>
-gatherBoundsOrBoundValues(fir::FirOpBuilder &builder, mlir::Location loc,
- fir::ExtendedValue dataExv, mlir::Value box,
- bool collectValuesOnly = false) {
- assert(box && "box must exist");
- llvm::SmallVector<mlir::Value> values;
- mlir::Value byteStride;
- mlir::Type idxTy = builder.getIndexType();
- mlir::Type boundTy = builder.getType<BoundsType>();
- mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
- for (unsigned dim = 0; dim < dataExv.rank(); ++dim) {
- mlir::Value d = builder.createIntegerConstant(loc, idxTy, dim);
- mlir::Value baseLb =
- fir::factory::readLowerBound(builder, loc, dataExv, dim, one);
- auto dimInfo =
- builder.create<fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, box, d);
- mlir::Value lb = builder.createIntegerConstant(loc, idxTy, 0);
- mlir::Value ub =
- builder.create<mlir::arith::SubIOp>(loc, dimInfo.getExtent(), one);
- if (dim == 0) // First stride is the element size.
- byteStride = dimInfo.getByteStride();
- if (collectValuesOnly) {
- values.push_back(lb);
- values.push_back(ub);
- values.push_back(dimInfo.getExtent());
- values.push_back(byteStride);
- values.push_back(baseLb);
- } else {
- mlir::Value bound = builder.create<BoundsOp>(
- loc, boundTy, lb, ub, dimInfo.getExtent(), byteStride, true, baseLb);
- values.push_back(bound);
- }
- // Compute the stride for the next dimension.
- byteStride = builder.create<mlir::arith::MulIOp>(loc, byteStride,
- dimInfo.getExtent());
- }
- return values;
-}
-
-/// Generate the bounds operation from the descriptor information.
-template <typename BoundsOp, typename BoundsType>
-llvm::SmallVector<mlir::Value>
-genBoundsOpsFromBox(fir::FirOpBuilder &builder, mlir::Location loc,
- fir::ExtendedValue dataExv,
- Fortran::lower::AddrAndBoundsInfo &info) {
- llvm::SmallVector<mlir::Value> bounds;
- mlir::Type idxTy = builder.getIndexType();
- mlir::Type boundTy = builder.getType<BoundsType>();
-
- assert(mlir::isa<fir::BaseBoxType>(info.boxType) &&
- "expect fir.box or fir.class");
- assert(fir::unwrapRefType(info.addr.getType()) == info.boxType &&
- "expected box type consistency");
-
- if (info.isPresent) {
- llvm::SmallVector<mlir::Type> resTypes;
- constexpr unsigned nbValuesPerBound = 5;
- for (unsigned dim = 0; dim < dataExv.rank() * nbValuesPerBound; ++dim)
- resTypes.push_back(idxTy);
-
- mlir::Operation::result_range ifRes =
- builder.genIfOp(loc, resTypes, info.isPresent, /*withElseRegion=*/true)
- .genThen([&]() {
- mlir::Value box =
- !fir::isBoxAddress(info.addr.getType())
- ? info.addr
- : builder.create<fir::LoadOp>(loc, info.addr);
- llvm::SmallVector<mlir::Value> boundValues =
- gatherBoundsOrBoundValues<BoundsOp, BoundsType>(
- builder, loc, dataExv, box,
- /*collectValuesOnly=*/true);
- builder.create<fir::ResultOp>(loc, boundValues);
- })
- .genElse([&] {
- // Box is not present. Populate bound values with default values.
- llvm::SmallVector<mlir::Value> boundValues;
- mlir::Value zero = builder.createIntegerConstant(loc, idxTy, 0);
- mlir::Value mOne = builder.createMinusOneInteger(loc, idxTy);
- for (unsigned dim = 0; dim < dataExv.rank(); ++dim) {
- boundValues.push_back(zero); // lb
- boundValues.push_back(mOne); // ub
- boundValues.push_back(zero); // extent
- boundValues.push_back(zero); // byteStride
- boundValues.push_back(zero); // baseLb
- }
- builder.create<fir::ResultOp>(loc, boundValues);
- })
- .getResults();
- // Create the bound operations outside the if-then-else with the if op
- // results.
- for (unsigned i = 0; i < ifRes.size(); i += nbValuesPerBound) {
- mlir::Value bound = builder.create<BoundsOp>(
- loc, boundTy, ifRes[i], ifRes[i + 1], ifRes[i + 2], ifRes[i + 3],
- true, ifRes[i + 4]);
- bounds.push_back(bound);
- }
- } else {
- mlir::Value box = !fir::isBoxAddress(info.addr.getType())
- ? info.addr
- : builder.create<fir::LoadOp>(loc, info.addr);
- bounds = gatherBoundsOrBoundValues<BoundsOp, BoundsType>(builder, loc,
- dataExv, box);
- }
- return bounds;
-}
-
-/// Generate bounds operation for base array without any subscripts
-/// provided.
-template <typename BoundsOp, typename BoundsType>
-llvm::SmallVector<mlir::Value>
-genBaseBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
- fir::ExtendedValue dataExv, bool isAssumedSize) {
- mlir::Type idxTy = builder.getIndexType();
- mlir::Type boundTy = builder.getType<BoundsType>();
- llvm::SmallVector<mlir::Value> bounds;
-
- if (dataExv.rank() == 0)
- return bounds;
-
- mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
- const unsigned rank = dataExv.rank();
- for (unsigned dim = 0; dim < rank; ++dim) {
- mlir::Value baseLb =
- fir::factory::readLowerBound(builder, loc, dataExv, dim, one);
- mlir::Value zero = builder.createIntegerConstant(loc, idxTy, 0);
- mlir::Value ub;
- mlir::Value lb = zero;
- mlir::Value ext = fir::factory::readExtent(builder, loc, dataExv, dim);
- if (isAssumedSize && dim + 1 == rank) {
- ext = zero;
- ub = lb;
- } else {
- // ub = extent - 1
- ub = builder.create<mlir::arith::SubIOp>(loc, ext, one);
- }
-
- mlir::Value bound =
- builder.create<BoundsOp>(loc, boundTy, lb, ub, ext, one, false, baseLb);
- bounds.push_back(bound);
- }
- return bounds;
+ return fir::factory::getDataOperandBaseAddr(
+ builder, converter.getSymbolAddress(sym),
+ Fortran::semantics::IsOptional(sym), loc);
}
namespace detail {
@@ -878,7 +668,7 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
Fortran::lower::StatementContext &stmtCtx,
const std::vector<Fortran::evaluate::Subscript> &subscripts,
std::stringstream &asFortran, fir::ExtendedValue &dataExv,
- bool dataExvIsAssumedSize, AddrAndBoundsInfo &info,
+ bool dataExvIsAssumedSize, fir::factory::AddrAndBoundsInfo &info,
bool treatIndexAsSection = false) {
int dimension = 0;
mlir::Type idxTy = builder.getIndexType();
@@ -1083,7 +873,7 @@ std::optional<Ref> getRef(Expr &&expr) {
} // namespace detail
template <typename BoundsOp, typename BoundsType>
-AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
+fir::factory::AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
Fortran::lower::AbstractConverter &converter, fir::FirOpBuilder &builder,
semantics::SemanticsContext &semaCtx,
Fortran::lower::StatementContext &stmtCtx,
@@ -1093,7 +883,7 @@ AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
llvm::SmallVector<mlir::Value> &bounds, bool treatIndexAsSection = false) {
using namespace Fortran;
- AddrAndBoundsInfo info;
+ fir::factory::AddrAndBoundsInfo info;
if (!maybeDesignator) {
info = getDataOperandBaseAddr(converter, builder, symbol, operandLocation);
@@ -1158,9 +948,9 @@ AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
info.addr = fir::getBase(compExv);
info.rawInput = info.addr;
if (mlir::isa<fir::SequenceType>(fir::unwrapRefType(info.addr.getType())))
- bounds = genBaseBoundsOps<BoundsOp, BoundsType>(builder, operandLocation,
- compExv,
- /*isAssumedSize=*/false);
+ bounds = fir::factory::genBaseBoundsOps<BoundsOp, BoundsType>(
+ builder, operandLocation, compExv,
+ /*isAssumedSize=*/false);
asFortran << designator.AsFortran();
if (semantics::IsOptional(compRef->GetLastSymbol())) {
@@ -1187,7 +977,7 @@ AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
info.addr = boxAddrOp.getVal();
info.boxType = info.addr.getType();
info.rawInput = info.addr;
- bounds = genBoundsOpsFromBox<BoundsOp, BoundsType>(
+ bounds = fir::factory::genBoundsOpsFromBox<BoundsOp, BoundsType>(
builder, operandLocation, compExv, info);
}
} else {
@@ -1205,13 +995,13 @@ AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
if (mlir::isa<fir::BaseBoxType>(
fir::unwrapRefType(info.addr.getType()))) {
info.boxType = fir::unwrapRefType(info.addr.getType());
- bounds = genBoundsOpsFromBox<BoundsOp, BoundsType>(
+ bounds = fir::factory::genBoundsOpsFromBox<BoundsOp, BoundsType>(
builder, operandLocation, dataExv, info);
}
bool dataExvIsAssumedSize =
Fortran::semantics::IsAssumedSizeArray(symRef->get().GetUltimate());
if (mlir::isa<fir::SequenceType>(fir::unwrapRefType(info.addr.getType())))
- bounds = genBaseBoundsOps<BoundsOp, BoundsType>(
+ bounds = fir::factory::genBaseBoundsOps<BoundsOp, BoundsType>(
builder, operandLocation, dataExv, dataExvIsAssumedSize);
asFortran << symRef->get().name().ToString();
} else { // Unsupported
@@ -1222,24 +1012,6 @@ AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
return info;
}
-template <typename BoundsOp, typename BoundsType>
-llvm::SmallVector<mlir::Value>
-genImplicitBoundsOps(fir::FirOpBuilder &builder, lower::AddrAndBoundsInfo &info,
- fir::ExtendedValue dataExv, bool dataExvIsAssumedSize,
- mlir::Location loc) {
- llvm::SmallVector<mlir::Value> bounds;
-
- mlir::Value baseOp = info.rawInput;
- if (mlir::isa<fir::BaseBoxType>(fir::unwrapRefType(baseOp.getType())))
- bounds = lower::genBoundsOpsFromBox<BoundsOp, BoundsType>(builder, loc,
- dataExv, info);
- if (mlir::isa<fir::SequenceType>(fir::unwrapRefType(baseOp.getType()))) {
- bounds = lower::genBaseBoundsOps<BoundsOp, BoundsType>(
- builder, loc, dataExv, dataExvIsAssumedSize);
- }
-
- return bounds;
-}
} // namespace lower
} // namespace Fortran
diff --git a/flang/include/flang/Optimizer/Builder/DirectivesCommon.h b/flang/include/flang/Optimizer/Builder/DirectivesCommon.h
new file mode 100644
index 00000000000000..443b0ee59007fa
--- /dev/null
+++ b/flang/include/flang/Optimizer/Builder/DirectivesCommon.h
@@ -0,0 +1,256 @@
+//===-- DirectivesCommon.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
+//
+//===----------------------------------------------------------------------===//
+///
+/// A location to place directive utilities shared across multiple lowering
+/// and optimizer files, e.g. utilities shared in OpenMP and OpenACC.
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_BUILDER_DIRECTIVESCOMMON_H_
+#define FORTRAN_OPTIMIZER_BUILDER_DIRECTIVESCOMMON_H_
+
+#include "flang/Optimizer/Builder/BoxValue.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/HLFIR/HLFIROps.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+
+namespace fir::factory {
+
+/// Information gathered to generate bounds operation and data entry/exit
+/// operations.
+struct AddrAndBoundsInfo {
+ explicit AddrAndBoundsInfo() {}
+ explicit AddrAndBoundsInfo(mlir::Value addr, mlir::Value rawInput)
+ : addr(addr), rawInput(rawInput) {}
+ explicit AddrAndBoundsInfo(mlir::Value addr, mlir::Value rawInput,
+ mlir::Value isPresent)
+ : addr(addr), rawInput(rawInput), isPresent(isPresent) {}
+ explicit AddrAndBoundsInfo(mlir::Value addr, mlir::Value rawInput,
+ mlir::Value isPresent, mlir::Type boxType)
+ : addr(addr), rawInput(rawInput), isPresent(isPresent), boxType(boxType) {
+ }
+ mlir::Value addr = nullptr;
+ mlir::Value rawInput = nullptr;
+ mlir::Value isPresent = nullptr;
+ mlir::Type boxType = nullptr;
+ void dump(llvm::raw_ostream &os) {
+ os << "AddrAndBoundsInfo addr: " << addr << "\n";
+ os << "AddrAndBoundsInfo rawInput: " << rawInput << "\n";
+ os << "AddrAndBoundsInfo isPresent: " << isPresent << "\n";
+ os << "AddrAndBoundsInfo boxType: " << boxType << "\n";
+ }
+};
+
+inline AddrAndBoundsInfo getDataOperandBaseAddr(fir::FirOpBuilder &builder,
+ mlir::Value symAddr,
+ bool isOptional,
+ mlir::Location loc) {
+ mlir::Value rawInput = symAddr;
+ if (auto declareOp =
+ mlir::dyn_cast_or_null<hlfir::DeclareOp>(symAddr.getDefiningOp())) {
+ symAddr = declareOp.getResults()[0];
+ rawInput = declareOp.getResults()[1];
+ }
+
+ if (!symAddr)
+ llvm::report_fatal_error("could not retrieve symbol address");
+
+ mlir::Value isPresent;
+ if (isOptional)
+ isPresent =
+ builder.create<fir::IsPresentOp>(loc, builder.getI1Type(), rawInput);
+
+ if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(
+ fir::unwrapRefType(symAddr.getType()))) {
+ if (mlir::isa<fir::RecordType>(boxTy.getEleTy()))
+ TODO(loc, "derived type");
+
+ // In case of a box reference, load it here to get the box value.
+ // This is preferrable because then the same box value can then be used for
+ // all address/dimension retrievals. For Fortran optional though, leave
+ // the load generation for later so it can be done in the appropriate
+ // if branches.
+ if (mlir::isa<fir::ReferenceType>(symAddr.getType()) && !isOptional) {
+ mlir::Value addr = builder.create<fir::LoadOp>(loc, symAddr);
+ return AddrAndBoundsInfo(addr, rawInput, isPresent, boxTy);
+ }
+
+ return AddrAndBoundsInfo(symAddr, rawInput, isPresent, boxTy);
+ }
+ return AddrAndBoundsInfo(symAddr, rawInput, isPresent);
+}
+
+template <typename BoundsOp, typename BoundsType>
+llvm::SmallVector<mlir::Value>
+gatherBoundsOrBoundValues(fir::FirOpBuilder &builder, mlir::Location loc,
+ fir::ExtendedValue dataExv, mlir::Value box,
+ bool collectValuesOnly = false) {
+ assert(box && "box must exist");
+ llvm::SmallVector<mlir::Value> values;
+ mlir::Value byteStride;
+ mlir::Type idxTy = builder.getIndexType();
+ mlir::Type boundTy = builder.getType<BoundsType>();
+ mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
+ for (unsigned dim = 0; dim < dataExv.rank(); ++dim) {
+ mlir::Value d = builder.createIntegerConstant(loc, idxTy, dim);
+ mlir::Value baseLb =
+ fir::factory::readLowerBound(builder, loc, dataExv, dim, one);
+ auto dimInfo =
+ builder.create<fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, box, d);
+ mlir::Value lb = builder.createIntegerConstant(loc, idxTy, 0);
+ mlir::Value ub =
+ builder.create<mlir::arith::SubIOp>(loc, dimInfo.getExtent(), one);
+ if (dim == 0) // First stride is the element size.
+ byteStride = dimInfo.getByteStride();
+ if (collectValuesOnly) {
+ values.push_back(lb);
+ values.push_back(ub);
+ values.push_back(dimInfo.getExtent());
+ values.pus...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/123784
More information about the flang-commits
mailing list