hlfir::ElementalOp elemental,
mlir::ValueRange oneBasedIndices);
+std::pair<fir::ExtendedValue, std::optional<hlfir::CleanupFunction>>
+convertToValue(mlir::Location loc, fir::FirOpBuilder &builder,
+ const hlfir::Entity &entity);
+
+std::pair<fir::ExtendedValue, std::optional<hlfir::CleanupFunction>>
+convertToAddress(mlir::Location loc, fir::FirOpBuilder &builder,
+ const hlfir::Entity &entity, mlir::Type targetType);
+
+std::pair<fir::BoxValue, std::optional<hlfir::CleanupFunction>>
+convertToBox(mlir::Location loc, fir::FirOpBuilder &builder,
+ const hlfir::Entity &entity, mlir::Type targetType);
} // namespace hlfir
#endif // FORTRAN_OPTIMIZER_BUILDER_HLFIRTOOLS_H
return HlfirBuilder(loc, converter, symMap, stmtCtx).gen(expr);
}
-static fir::ExtendedValue placeTrivialInMemory(mlir::Location loc,
- fir::FirOpBuilder &builder,
- mlir::Value val,
- mlir::Type fortranType) {
- auto temp = builder.createTemporary(loc, fortranType);
- builder.createStoreWithConvert(loc, val, temp);
- return temp;
-}
-
fir::BoxValue Fortran::lower::convertToBox(
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
hlfir::Entity entity, Fortran::lower::StatementContext &stmtCtx,
mlir::Type fortranType) {
- auto exv = Fortran::lower::translateToExtendedValue(
- loc, converter.getFirOpBuilder(), entity, stmtCtx);
- if (fir::isa_trivial(fir::getBase(exv).getType()))
- exv = placeTrivialInMemory(loc, converter.getFirOpBuilder(),
- fir::getBase(exv), fortranType);
- return fir::factory::createBoxValue(converter.getFirOpBuilder(), loc, exv);
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+ auto [exv, cleanup] = hlfir::convertToBox(loc, builder, entity, fortranType);
+ if (cleanup)
+ stmtCtx.attachCleanup(*cleanup);
+ return exv;
}
fir::BoxValue Fortran::lower::convertExprToBox(
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
hlfir::Entity entity, Fortran::lower::StatementContext &stmtCtx,
mlir::Type fortranType) {
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
- entity = hlfir::derefPointersAndAllocatables(loc, builder, entity);
- fir::ExtendedValue exv =
- Fortran::lower::translateToExtendedValue(loc, builder, entity, stmtCtx);
- if (fir::isa_trivial(fir::getBase(exv).getType()))
- return placeTrivialInMemory(loc, builder, fir::getBase(exv), fortranType);
+ auto [exv, cleanup] =
+ hlfir::convertToAddress(loc, builder, entity, fortranType);
+ if (cleanup)
+ stmtCtx.attachCleanup(*cleanup);
return exv;
}
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
hlfir::Entity entity, Fortran::lower::StatementContext &stmtCtx) {
auto &builder = converter.getFirOpBuilder();
- fir::ExtendedValue exv =
- Fortran::lower::translateToExtendedValue(loc, builder, entity, stmtCtx);
- // Load scalar references to integer, logical, real, or complex value
- // to an mlir value, dereference allocatable and pointers, and get rid
- // of fir.box that are not needed or create a copy into contiguous memory.
- return exv.match(
- [&](const fir::UnboxedValue &box) -> fir::ExtendedValue {
- if (mlir::Type elementType = fir::dyn_cast_ptrEleTy(box.getType()))
- if (fir::isa_trivial(elementType))
- return builder.create<fir::LoadOp>(loc, box);
- return box;
- },
- [&](const fir::CharBoxValue &box) -> fir::ExtendedValue { return box; },
- [&](const fir::ArrayBoxValue &box) -> fir::ExtendedValue { return box; },
- [&](const fir::CharArrayBoxValue &box) -> fir::ExtendedValue {
- return box;
- },
- [&](const auto &) -> fir::ExtendedValue {
- TODO(loc, "lower descriptor designator to HLFIR value");
- });
+ auto [exv, cleanup] = hlfir::convertToValue(loc, builder, entity);
+ if (cleanup)
+ stmtCtx.attachCleanup(*cleanup);
+ return exv;
}
fir::ExtendedValue Fortran::lower::convertExprToValue(
}
return {{static_cast<mlir::Value>(entity)}, {}};
}
+
+std::pair<fir::ExtendedValue, std::optional<hlfir::CleanupFunction>>
+hlfir::convertToValue(mlir::Location loc, fir::FirOpBuilder &builder,
+ const hlfir::Entity &entity) {
+ auto [exv, cleanup] = translateToExtendedValue(loc, builder, entity);
+ // Load scalar references to integer, logical, real, or complex value
+ // to an mlir value, dereference allocatable and pointers, and get rid
+ // of fir.box that are not needed or create a copy into contiguous memory.
+ exv = exv.match(
+ [&](const fir::UnboxedValue &box) -> fir::ExtendedValue {
+ if (mlir::Type elementType = fir::dyn_cast_ptrEleTy(box.getType()))
+ if (fir::isa_trivial(elementType))
+ return builder.create<fir::LoadOp>(loc, box);
+ return box;
+ },
+ [&](const fir::CharBoxValue &box) -> fir::ExtendedValue { return box; },
+ [&](const fir::ArrayBoxValue &box) -> fir::ExtendedValue { return box; },
+ [&](const fir::CharArrayBoxValue &box) -> fir::ExtendedValue {
+ return box;
+ },
+ [&](const auto &) -> fir::ExtendedValue {
+ TODO(loc, "lower descriptor designator to HLFIR value");
+ });
+ return {exv, cleanup};
+}
+
+static fir::ExtendedValue placeTrivialInMemory(mlir::Location loc,
+ fir::FirOpBuilder &builder,
+ mlir::Value val,
+ mlir::Type targetType) {
+ auto temp = builder.createTemporary(loc, targetType);
+ if (targetType != val.getType())
+ builder.createStoreWithConvert(loc, val, temp);
+ else
+ builder.create<fir::StoreOp>(loc, val, temp);
+ return temp;
+}
+
+std::pair<fir::BoxValue, std::optional<hlfir::CleanupFunction>>
+hlfir::convertToBox(mlir::Location loc, fir::FirOpBuilder &builder,
+ const hlfir::Entity &entity, mlir::Type targetType) {
+ auto [exv, cleanup] = translateToExtendedValue(loc, builder, entity);
+ mlir::Value base = fir::getBase(exv);
+ if (fir::isa_trivial(base.getType()))
+ exv = placeTrivialInMemory(loc, builder, base, targetType);
+ fir::BoxValue box = fir::factory::createBoxValue(builder, loc, exv);
+ return {box, cleanup};
+}
+
+std::pair<fir::ExtendedValue, std::optional<hlfir::CleanupFunction>>
+hlfir::convertToAddress(mlir::Location loc, fir::FirOpBuilder &builder,
+ const hlfir::Entity &entity, mlir::Type targetType) {
+ hlfir::Entity derefedEntity =
+ hlfir::derefPointersAndAllocatables(loc, builder, entity);
+ auto [exv, cleanup] =
+ hlfir::translateToExtendedValue(loc, builder, derefedEntity);
+ mlir::Value base = fir::getBase(exv);
+ if (fir::isa_trivial(base.getType()))
+ exv = placeTrivialInMemory(loc, builder, base, targetType);
+ return {exv, cleanup};
+}