Skip to content

Commit 662133a

Browse files
authored
[flang][OpenMP][OpenACC] remove libEvaluate dependency in passes (#123784)
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 #123377
1 parent 0ca6b2b commit 662133a

File tree

9 files changed

+301
-271
lines changed

9 files changed

+301
-271
lines changed

flang/include/flang/Lower/DirectivesCommon.h

Lines changed: 14 additions & 242 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,9 @@
2929
#include "flang/Lower/PFTBuilder.h"
3030
#include "flang/Lower/StatementContext.h"
3131
#include "flang/Lower/Support/Utils.h"
32-
#include "flang/Optimizer/Builder/BoxValue.h"
33-
#include "flang/Optimizer/Builder/FIRBuilder.h"
32+
#include "flang/Optimizer/Builder/DirectivesCommon.h"
3433
#include "flang/Optimizer/Builder/HLFIRTools.h"
35-
#include "flang/Optimizer/Builder/Todo.h"
3634
#include "flang/Optimizer/Dialect/FIRType.h"
37-
#include "flang/Optimizer/HLFIR/HLFIROps.h"
3835
#include "flang/Parser/parse-tree.h"
3936
#include "flang/Semantics/openmp-directive-sets.h"
4037
#include "flang/Semantics/tools.h"
@@ -49,31 +46,6 @@
4946
namespace Fortran {
5047
namespace lower {
5148

52-
/// Information gathered to generate bounds operation and data entry/exit
53-
/// operations.
54-
struct AddrAndBoundsInfo {
55-
explicit AddrAndBoundsInfo() {}
56-
explicit AddrAndBoundsInfo(mlir::Value addr, mlir::Value rawInput)
57-
: addr(addr), rawInput(rawInput) {}
58-
explicit AddrAndBoundsInfo(mlir::Value addr, mlir::Value rawInput,
59-
mlir::Value isPresent)
60-
: addr(addr), rawInput(rawInput), isPresent(isPresent) {}
61-
explicit AddrAndBoundsInfo(mlir::Value addr, mlir::Value rawInput,
62-
mlir::Value isPresent, mlir::Type boxType)
63-
: addr(addr), rawInput(rawInput), isPresent(isPresent), boxType(boxType) {
64-
}
65-
mlir::Value addr = nullptr;
66-
mlir::Value rawInput = nullptr;
67-
mlir::Value isPresent = nullptr;
68-
mlir::Type boxType = nullptr;
69-
void dump(llvm::raw_ostream &os) {
70-
os << "AddrAndBoundsInfo addr: " << addr << "\n";
71-
os << "AddrAndBoundsInfo rawInput: " << rawInput << "\n";
72-
os << "AddrAndBoundsInfo isPresent: " << isPresent << "\n";
73-
os << "AddrAndBoundsInfo boxType: " << boxType << "\n";
74-
}
75-
};
76-
7749
/// Populates \p hint and \p memoryOrder with appropriate clause information
7850
/// if present on atomic construct.
7951
static inline void genOmpAtomicHintAndMemoryOrderClauses(
@@ -609,195 +581,13 @@ void createEmptyRegionBlocks(
609581
}
610582
}
611583

612-
inline AddrAndBoundsInfo getDataOperandBaseAddr(fir::FirOpBuilder &builder,
613-
mlir::Value symAddr,
614-
bool isOptional,
615-
mlir::Location loc) {
616-
mlir::Value rawInput = symAddr;
617-
if (auto declareOp =
618-
mlir::dyn_cast_or_null<hlfir::DeclareOp>(symAddr.getDefiningOp())) {
619-
symAddr = declareOp.getResults()[0];
620-
rawInput = declareOp.getResults()[1];
621-
}
622-
623-
if (!symAddr)
624-
llvm::report_fatal_error("could not retrieve symbol address");
625-
626-
mlir::Value isPresent;
627-
if (isOptional)
628-
isPresent =
629-
builder.create<fir::IsPresentOp>(loc, builder.getI1Type(), rawInput);
630-
631-
if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(
632-
fir::unwrapRefType(symAddr.getType()))) {
633-
if (mlir::isa<fir::RecordType>(boxTy.getEleTy()))
634-
TODO(loc, "derived type");
635-
636-
// In case of a box reference, load it here to get the box value.
637-
// This is preferrable because then the same box value can then be used for
638-
// all address/dimension retrievals. For Fortran optional though, leave
639-
// the load generation for later so it can be done in the appropriate
640-
// if branches.
641-
if (mlir::isa<fir::ReferenceType>(symAddr.getType()) && !isOptional) {
642-
mlir::Value addr = builder.create<fir::LoadOp>(loc, symAddr);
643-
return AddrAndBoundsInfo(addr, rawInput, isPresent, boxTy);
644-
}
645-
646-
return AddrAndBoundsInfo(symAddr, rawInput, isPresent, boxTy);
647-
}
648-
return AddrAndBoundsInfo(symAddr, rawInput, isPresent);
649-
}
650-
651-
inline AddrAndBoundsInfo
584+
inline fir::factory::AddrAndBoundsInfo
652585
getDataOperandBaseAddr(Fortran::lower::AbstractConverter &converter,
653586
fir::FirOpBuilder &builder,
654587
Fortran::lower::SymbolRef sym, mlir::Location loc) {
655-
return getDataOperandBaseAddr(builder, converter.getSymbolAddress(sym),
656-
Fortran::semantics::IsOptional(sym), loc);
657-
}
658-
659-
template <typename BoundsOp, typename BoundsType>
660-
llvm::SmallVector<mlir::Value>
661-
gatherBoundsOrBoundValues(fir::FirOpBuilder &builder, mlir::Location loc,
662-
fir::ExtendedValue dataExv, mlir::Value box,
663-
bool collectValuesOnly = false) {
664-
assert(box && "box must exist");
665-
llvm::SmallVector<mlir::Value> values;
666-
mlir::Value byteStride;
667-
mlir::Type idxTy = builder.getIndexType();
668-
mlir::Type boundTy = builder.getType<BoundsType>();
669-
mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
670-
for (unsigned dim = 0; dim < dataExv.rank(); ++dim) {
671-
mlir::Value d = builder.createIntegerConstant(loc, idxTy, dim);
672-
mlir::Value baseLb =
673-
fir::factory::readLowerBound(builder, loc, dataExv, dim, one);
674-
auto dimInfo =
675-
builder.create<fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, box, d);
676-
mlir::Value lb = builder.createIntegerConstant(loc, idxTy, 0);
677-
mlir::Value ub =
678-
builder.create<mlir::arith::SubIOp>(loc, dimInfo.getExtent(), one);
679-
if (dim == 0) // First stride is the element size.
680-
byteStride = dimInfo.getByteStride();
681-
if (collectValuesOnly) {
682-
values.push_back(lb);
683-
values.push_back(ub);
684-
values.push_back(dimInfo.getExtent());
685-
values.push_back(byteStride);
686-
values.push_back(baseLb);
687-
} else {
688-
mlir::Value bound = builder.create<BoundsOp>(
689-
loc, boundTy, lb, ub, dimInfo.getExtent(), byteStride, true, baseLb);
690-
values.push_back(bound);
691-
}
692-
// Compute the stride for the next dimension.
693-
byteStride = builder.create<mlir::arith::MulIOp>(loc, byteStride,
694-
dimInfo.getExtent());
695-
}
696-
return values;
697-
}
698-
699-
/// Generate the bounds operation from the descriptor information.
700-
template <typename BoundsOp, typename BoundsType>
701-
llvm::SmallVector<mlir::Value>
702-
genBoundsOpsFromBox(fir::FirOpBuilder &builder, mlir::Location loc,
703-
fir::ExtendedValue dataExv,
704-
Fortran::lower::AddrAndBoundsInfo &info) {
705-
llvm::SmallVector<mlir::Value> bounds;
706-
mlir::Type idxTy = builder.getIndexType();
707-
mlir::Type boundTy = builder.getType<BoundsType>();
708-
709-
assert(mlir::isa<fir::BaseBoxType>(info.boxType) &&
710-
"expect fir.box or fir.class");
711-
assert(fir::unwrapRefType(info.addr.getType()) == info.boxType &&
712-
"expected box type consistency");
713-
714-
if (info.isPresent) {
715-
llvm::SmallVector<mlir::Type> resTypes;
716-
constexpr unsigned nbValuesPerBound = 5;
717-
for (unsigned dim = 0; dim < dataExv.rank() * nbValuesPerBound; ++dim)
718-
resTypes.push_back(idxTy);
719-
720-
mlir::Operation::result_range ifRes =
721-
builder.genIfOp(loc, resTypes, info.isPresent, /*withElseRegion=*/true)
722-
.genThen([&]() {
723-
mlir::Value box =
724-
!fir::isBoxAddress(info.addr.getType())
725-
? info.addr
726-
: builder.create<fir::LoadOp>(loc, info.addr);
727-
llvm::SmallVector<mlir::Value> boundValues =
728-
gatherBoundsOrBoundValues<BoundsOp, BoundsType>(
729-
builder, loc, dataExv, box,
730-
/*collectValuesOnly=*/true);
731-
builder.create<fir::ResultOp>(loc, boundValues);
732-
})
733-
.genElse([&] {
734-
// Box is not present. Populate bound values with default values.
735-
llvm::SmallVector<mlir::Value> boundValues;
736-
mlir::Value zero = builder.createIntegerConstant(loc, idxTy, 0);
737-
mlir::Value mOne = builder.createMinusOneInteger(loc, idxTy);
738-
for (unsigned dim = 0; dim < dataExv.rank(); ++dim) {
739-
boundValues.push_back(zero); // lb
740-
boundValues.push_back(mOne); // ub
741-
boundValues.push_back(zero); // extent
742-
boundValues.push_back(zero); // byteStride
743-
boundValues.push_back(zero); // baseLb
744-
}
745-
builder.create<fir::ResultOp>(loc, boundValues);
746-
})
747-
.getResults();
748-
// Create the bound operations outside the if-then-else with the if op
749-
// results.
750-
for (unsigned i = 0; i < ifRes.size(); i += nbValuesPerBound) {
751-
mlir::Value bound = builder.create<BoundsOp>(
752-
loc, boundTy, ifRes[i], ifRes[i + 1], ifRes[i + 2], ifRes[i + 3],
753-
true, ifRes[i + 4]);
754-
bounds.push_back(bound);
755-
}
756-
} else {
757-
mlir::Value box = !fir::isBoxAddress(info.addr.getType())
758-
? info.addr
759-
: builder.create<fir::LoadOp>(loc, info.addr);
760-
bounds = gatherBoundsOrBoundValues<BoundsOp, BoundsType>(builder, loc,
761-
dataExv, box);
762-
}
763-
return bounds;
764-
}
765-
766-
/// Generate bounds operation for base array without any subscripts
767-
/// provided.
768-
template <typename BoundsOp, typename BoundsType>
769-
llvm::SmallVector<mlir::Value>
770-
genBaseBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
771-
fir::ExtendedValue dataExv, bool isAssumedSize) {
772-
mlir::Type idxTy = builder.getIndexType();
773-
mlir::Type boundTy = builder.getType<BoundsType>();
774-
llvm::SmallVector<mlir::Value> bounds;
775-
776-
if (dataExv.rank() == 0)
777-
return bounds;
778-
779-
mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
780-
const unsigned rank = dataExv.rank();
781-
for (unsigned dim = 0; dim < rank; ++dim) {
782-
mlir::Value baseLb =
783-
fir::factory::readLowerBound(builder, loc, dataExv, dim, one);
784-
mlir::Value zero = builder.createIntegerConstant(loc, idxTy, 0);
785-
mlir::Value ub;
786-
mlir::Value lb = zero;
787-
mlir::Value ext = fir::factory::readExtent(builder, loc, dataExv, dim);
788-
if (isAssumedSize && dim + 1 == rank) {
789-
ext = zero;
790-
ub = lb;
791-
} else {
792-
// ub = extent - 1
793-
ub = builder.create<mlir::arith::SubIOp>(loc, ext, one);
794-
}
795-
796-
mlir::Value bound =
797-
builder.create<BoundsOp>(loc, boundTy, lb, ub, ext, one, false, baseLb);
798-
bounds.push_back(bound);
799-
}
800-
return bounds;
588+
return fir::factory::getDataOperandBaseAddr(
589+
builder, converter.getSymbolAddress(sym),
590+
Fortran::semantics::IsOptional(sym), loc);
801591
}
802592

803593
namespace detail {
@@ -878,7 +668,7 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
878668
Fortran::lower::StatementContext &stmtCtx,
879669
const std::vector<Fortran::evaluate::Subscript> &subscripts,
880670
std::stringstream &asFortran, fir::ExtendedValue &dataExv,
881-
bool dataExvIsAssumedSize, AddrAndBoundsInfo &info,
671+
bool dataExvIsAssumedSize, fir::factory::AddrAndBoundsInfo &info,
882672
bool treatIndexAsSection = false) {
883673
int dimension = 0;
884674
mlir::Type idxTy = builder.getIndexType();
@@ -1083,7 +873,7 @@ std::optional<Ref> getRef(Expr &&expr) {
1083873
} // namespace detail
1084874

1085875
template <typename BoundsOp, typename BoundsType>
1086-
AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
876+
fir::factory::AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
1087877
Fortran::lower::AbstractConverter &converter, fir::FirOpBuilder &builder,
1088878
semantics::SemanticsContext &semaCtx,
1089879
Fortran::lower::StatementContext &stmtCtx,
@@ -1093,7 +883,7 @@ AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
1093883
llvm::SmallVector<mlir::Value> &bounds, bool treatIndexAsSection = false) {
1094884
using namespace Fortran;
1095885

1096-
AddrAndBoundsInfo info;
886+
fir::factory::AddrAndBoundsInfo info;
1097887

1098888
if (!maybeDesignator) {
1099889
info = getDataOperandBaseAddr(converter, builder, symbol, operandLocation);
@@ -1158,9 +948,9 @@ AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
1158948
info.addr = fir::getBase(compExv);
1159949
info.rawInput = info.addr;
1160950
if (mlir::isa<fir::SequenceType>(fir::unwrapRefType(info.addr.getType())))
1161-
bounds = genBaseBoundsOps<BoundsOp, BoundsType>(builder, operandLocation,
1162-
compExv,
1163-
/*isAssumedSize=*/false);
951+
bounds = fir::factory::genBaseBoundsOps<BoundsOp, BoundsType>(
952+
builder, operandLocation, compExv,
953+
/*isAssumedSize=*/false);
1164954
asFortran << designator.AsFortran();
1165955

1166956
if (semantics::IsOptional(compRef->GetLastSymbol())) {
@@ -1187,7 +977,7 @@ AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
1187977
info.addr = boxAddrOp.getVal();
1188978
info.boxType = info.addr.getType();
1189979
info.rawInput = info.addr;
1190-
bounds = genBoundsOpsFromBox<BoundsOp, BoundsType>(
980+
bounds = fir::factory::genBoundsOpsFromBox<BoundsOp, BoundsType>(
1191981
builder, operandLocation, compExv, info);
1192982
}
1193983
} else {
@@ -1205,13 +995,13 @@ AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
1205995
if (mlir::isa<fir::BaseBoxType>(
1206996
fir::unwrapRefType(info.addr.getType()))) {
1207997
info.boxType = fir::unwrapRefType(info.addr.getType());
1208-
bounds = genBoundsOpsFromBox<BoundsOp, BoundsType>(
998+
bounds = fir::factory::genBoundsOpsFromBox<BoundsOp, BoundsType>(
1209999
builder, operandLocation, dataExv, info);
12101000
}
12111001
bool dataExvIsAssumedSize =
12121002
Fortran::semantics::IsAssumedSizeArray(symRef->get().GetUltimate());
12131003
if (mlir::isa<fir::SequenceType>(fir::unwrapRefType(info.addr.getType())))
1214-
bounds = genBaseBoundsOps<BoundsOp, BoundsType>(
1004+
bounds = fir::factory::genBaseBoundsOps<BoundsOp, BoundsType>(
12151005
builder, operandLocation, dataExv, dataExvIsAssumedSize);
12161006
asFortran << symRef->get().name().ToString();
12171007
} else { // Unsupported
@@ -1222,24 +1012,6 @@ AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
12221012
return info;
12231013
}
12241014

1225-
template <typename BoundsOp, typename BoundsType>
1226-
llvm::SmallVector<mlir::Value>
1227-
genImplicitBoundsOps(fir::FirOpBuilder &builder, lower::AddrAndBoundsInfo &info,
1228-
fir::ExtendedValue dataExv, bool dataExvIsAssumedSize,
1229-
mlir::Location loc) {
1230-
llvm::SmallVector<mlir::Value> bounds;
1231-
1232-
mlir::Value baseOp = info.rawInput;
1233-
if (mlir::isa<fir::BaseBoxType>(fir::unwrapRefType(baseOp.getType())))
1234-
bounds = lower::genBoundsOpsFromBox<BoundsOp, BoundsType>(builder, loc,
1235-
dataExv, info);
1236-
if (mlir::isa<fir::SequenceType>(fir::unwrapRefType(baseOp.getType()))) {
1237-
bounds = lower::genBaseBoundsOps<BoundsOp, BoundsType>(
1238-
builder, loc, dataExv, dataExvIsAssumedSize);
1239-
}
1240-
1241-
return bounds;
1242-
}
12431015
} // namespace lower
12441016
} // namespace Fortran
12451017

0 commit comments

Comments
 (0)