[flang-commits] [flang] e657acd - [flang] Handle NULL(mold) used in initializer region
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Sat Sep 24 06:23:20 PDT 2022
Author: Valentin Clement
Date: 2022-09-24T15:23:08+02:00
New Revision: e657acd449a8b765db8bb333e3e969c9f787b640
URL: https://github.com/llvm/llvm-project/commit/e657acd449a8b765db8bb333e3e969c9f787b640
DIFF: https://github.com/llvm/llvm-project/commit/e657acd449a8b765db8bb333e3e969c9f787b640.diff
LOG: [flang] Handle NULL(mold) used in initializer region
NULL intrinsic with a MOLD argument can be used in a type constructor.
This patch handles this use case with a specific lowering that create
an unallocated box with the MOLD type.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D134554
Added:
Modified:
flang/include/flang/Evaluate/tools.h
flang/lib/Evaluate/tools.cpp
flang/lib/Lower/ConvertVariable.cpp
flang/test/Lower/default-initialization-globals.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h
index dc0c02669cbe6..85de4805958b8 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -946,6 +946,8 @@ bool IsNullProcedurePointer(const Expr<SomeType> &);
bool IsNullPointer(const Expr<SomeType> &);
bool IsObjectPointer(const Expr<SomeType> &, FoldingContext &);
+const ProcedureRef *GetProcedureRef(const Expr<SomeType> &);
+
// Can Expr be passed as absent to an optional dummy argument.
// See 15.5.2.12 point 1 for more details.
bool MayBePassedAsAbsentOptional(const Expr<SomeType> &, FoldingContext &);
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index 5836e47c21971..51b09f3b7af4e 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -784,6 +784,10 @@ bool IsObjectPointer(const Expr<SomeType> &expr, FoldingContext &context) {
}
}
+const ProcedureRef *GetProcedureRef(const Expr<SomeType> &expr) {
+ return UnwrapProcedureRef(expr);
+}
+
// IsNullPointer() & variations
template <bool IS_PROC_PTR> struct IsNullPointerHelper {
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 97c8d6866355a..3de87ca9f4bc3 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -189,17 +189,41 @@ mlir::Value Fortran::lower::genInitialDataTarget(
return fir::factory::createUnallocatedBox(builder, loc, boxType,
/*nonDeferredParams=*/llvm::None);
// Pointer initial data target, and NULL(mold).
- if (const Fortran::semantics::Symbol *sym =
- Fortran::evaluate::GetFirstSymbol(initialTarget)) {
+ for (const auto &sym : Fortran::evaluate::CollectSymbols(initialTarget)) {
// Length parameters processing will need care in global initializer
// context.
- if (hasDerivedTypeWithLengthParameters(*sym))
+ if (hasDerivedTypeWithLengthParameters(sym))
TODO(loc, "initial-data-target with derived type length parameters");
- auto var = Fortran::lower::pft::Variable(*sym, /*global=*/true);
+ auto var = Fortran::lower::pft::Variable(sym, /*global=*/true);
Fortran::lower::instantiateVariable(converter, var, globalOpSymMap,
storeMap);
}
+
+ // Handle NULL(mold) as a special case. Return an unallocated box of MOLD
+ // type. The return box is correctly created as a fir.box<fir.ptr<T>> where
+ // T is extracted from the MOLD argument.
+ if (const Fortran::evaluate::ProcedureRef *procRef =
+ Fortran::evaluate::GetProcedureRef(initialTarget)) {
+ const Fortran::evaluate::SpecificIntrinsic *intrinsic =
+ procRef->proc().GetSpecificIntrinsic();
+ if (intrinsic && intrinsic->name == "null") {
+ assert(procRef->arguments().size() == 1 &&
+ "Expecting mold argument for NULL intrinsic");
+ const auto *argExpr = procRef->arguments()[0].value().UnwrapExpr();
+ assert(argExpr);
+ const Fortran::semantics::Symbol *sym =
+ Fortran::evaluate::GetFirstSymbol(*argExpr);
+ fir::ExtendedValue exv =
+ globalOpSymMap.lookupSymbol(sym).toExtendedValue();
+ const auto *mold = exv.getBoxOf<fir::MutableBoxValue>();
+ fir::BoxType boxType = mold->getBoxTy();
+ mlir::Value box =
+ fir::factory::createUnallocatedBox(builder, loc, boxType, {});
+ return box;
+ }
+ }
+
mlir::Value box;
if (initialTarget.Rank() > 0) {
box = fir::getBase(Fortran::lower::createSomeArrayBox(
diff --git a/flang/test/Lower/default-initialization-globals.f90 b/flang/test/Lower/default-initialization-globals.f90
index bde2636537569..3f7a6cd7ada56 100644
--- a/flang/test/Lower/default-initialization-globals.f90
+++ b/flang/test/Lower/default-initialization-globals.f90
@@ -55,6 +55,12 @@ module tinit
integer :: j = 3
end type
+ type tv
+ real, pointer :: v(:)
+ end type
+
+ real, pointer :: mv(:)
+
! Test scalar with default init
type(t0) :: at0
! CHECK-LABEL: fir.global @_QMtinitEat0 : !fir.type<_QMtinitTt0{k:i32}> {
@@ -125,6 +131,17 @@ module tinit
! CHECK: %[[VAL_45:.*]] = fir.undefined i32
! CHECK: %[[VAL_46:.*]] = fir.insert_value %[[VAL_44]], %[[VAL_45]], ["l", !fir.type<_QMtinitTtextendst0{k:i32,l:i32}>] : (!fir.type<_QMtinitTtextendst0{k:i32,l:i32}>, i32) -> !fir.type<_QMtinitTtextendst0{k:i32,l:i32}>
! CHECK: fir.has_value %[[VAL_46]] : !fir.type<_QMtinitTtextendst0{k:i32,l:i32}>
+
+ type(tv) :: withmold = tv(null(mv))
+ ! CHECK-LABEL: fir.global @_QMtinitEwithmold
+ ! CHECK: %[[C0:.*]] = arith.constant 0 : index
+ ! CHECK: %[[UNDEF:.*]] = fir.undefined !fir.type<_QMtinitTtv{v:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
+ ! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.ptr<!fir.array<?xf32>>
+ ! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[ZEROBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.ptr<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
+ ! CHECK: %[[RET:.*]] = fir.insert_value %[[UNDEF]], %[[ZEROBOX]], ["v", !fir.type<_QMtinitTtv{v:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>] : (!fir.type<_QMtinitTtv{v:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>, !fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.type<_QMtinitTtv{v:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
+ ! CHECK: fir.has_value %[[RET]] : !fir.type<_QMtinitTtv{v:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
+
end module
More information about the flang-commits
mailing list