Skip to content

Commit 1ddf3cf

Browse files
author
Razvan Lupusoru
committed
Include box rejection and better dynamic size checks
1 parent 3d6c19f commit 1ddf3cf

File tree

1 file changed

+43
-24
lines changed

1 file changed

+43
-24
lines changed

flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -757,23 +757,27 @@ mlir::Value OpenACCPointerLikeModel<Ty>::genAllocate(
757757
llvm::StringRef varName, mlir::Type varType, mlir::Value originalVar,
758758
bool &needsFree) const {
759759

760-
// Get the element type from the pointer type
761-
mlir::Type eleTy = mlir::cast<Ty>(pointer).getElementType();
760+
// Unwrap to get the pointee type.
761+
mlir::Type pointeeTy = fir::dyn_cast_ptrEleTy(pointer);
762+
assert(pointeeTy && "expected pointee type to be extractable");
763+
764+
// Box types are descriptors that contain both metadata and a pointer to data.
765+
// The `genAllocate` API is designed for simple allocations and cannot
766+
// properly handle the dual nature of boxes. Using `generatePrivateInit`
767+
// instead can allocate both the descriptor and its referenced data. For use
768+
// cases that require an empty descriptor storage, potentially this could be
769+
// implemented here.
770+
if (fir::isa_box_type(pointeeTy))
771+
return {};
762772

763773
// Unlimited polymorphic (class(*)) cannot be handled - size unknown
764-
if (fir::isUnlimitedPolymorphicType(eleTy))
774+
if (fir::isUnlimitedPolymorphicType(pointeeTy))
765775
return {};
766776

767-
// Character types with dynamic length cannot be handled without a descriptor.
768-
if (auto charTy = mlir::dyn_cast<fir::CharacterType>(eleTy))
769-
if (charTy.hasDynamicLen())
770-
return {};
771-
772-
// Return null for dynamic or unknown shape arrays because the size of the
777+
// Return null for dynamic size types because the size of the
773778
// allocation cannot be determined simply from the type.
774-
if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(eleTy))
775-
if (seqTy.hasDynamicExtents() || seqTy.hasUnknownShape())
776-
return {};
779+
if (fir::hasDynamicSize(pointeeTy))
780+
return {};
777781

778782
// Use heap allocation for fir.heap, stack allocation for others (fir.ref,
779783
// fir.ptr, fir.llvm_ptr). For fir.ptr, which is supposed to represent a
@@ -783,10 +787,10 @@ mlir::Value OpenACCPointerLikeModel<Ty>::genAllocate(
783787
mlir::Value allocation;
784788
if (std::is_same_v<Ty, fir::HeapType>) {
785789
needsFree = true;
786-
allocation = fir::AllocMemOp::create(builder, loc, eleTy);
790+
allocation = fir::AllocMemOp::create(builder, loc, pointeeTy);
787791
} else {
788792
needsFree = false;
789-
allocation = fir::AllocaOp::create(builder, loc, eleTy);
793+
allocation = fir::AllocaOp::create(builder, loc, pointeeTy);
790794
}
791795

792796
// Convert to the requested pointer type if needed.
@@ -862,6 +866,17 @@ bool OpenACCPointerLikeModel<Ty>::genFree(
862866
mlir::TypedValue<mlir::acc::PointerLikeType> varToFree,
863867
mlir::Value allocRes, mlir::Type varType) const {
864868

869+
// Unwrap to get the pointee type.
870+
mlir::Type pointeeTy = fir::dyn_cast_ptrEleTy(pointer);
871+
assert(pointeeTy && "expected pointee type to be extractable");
872+
873+
// Box types contain both a descriptor and data. The `genFree` API
874+
// handles simple deallocations and cannot properly manage both parts.
875+
// Using `generatePrivateDestroy` instead can free both the descriptor and
876+
// its referenced data.
877+
if (fir::isa_box_type(pointeeTy))
878+
return false;
879+
865880
// If pointer type is HeapType, assume it's a heap allocation
866881
if (std::is_same_v<Ty, fir::HeapType>) {
867882
fir::FreeMemOp::create(builder, loc, varToFree);
@@ -925,22 +940,26 @@ bool OpenACCPointerLikeModel<Ty>::genCopy(
925940
if (source.getType() != destination.getType())
926941
return false;
927942

928-
mlir::Type eleTy = mlir::cast<Ty>(pointer).getElementType();
943+
// Unwrap to get the pointee type.
944+
mlir::Type pointeeTy = fir::dyn_cast_ptrEleTy(pointer);
945+
assert(pointeeTy && "expected pointee type to be extractable");
946+
947+
// Box types contain both a descriptor and referenced data. The genCopy API
948+
// handles simple copies and cannot properly manage both parts.
949+
if (fir::isa_box_type(pointeeTy))
950+
return false;
929951

930952
// Unlimited polymorphic (class(*)) cannot be handled because source and
931953
// destination types are not known.
932-
if (fir::isUnlimitedPolymorphicType(eleTy))
954+
if (fir::isUnlimitedPolymorphicType(pointeeTy))
933955
return false;
934956

935-
// Dynamic lengths without descriptor do not have size information.
936-
if (auto charTy = mlir::dyn_cast<fir::CharacterType>(eleTy))
937-
if (charTy.hasDynamicLen())
938-
return false;
939-
if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(eleTy))
940-
if (seqTy.hasDynamicExtents() || seqTy.hasUnknownShape())
941-
return false;
957+
// Return false for dynamic size types because the copy logic
958+
// cannot be determined simply from the type.
959+
if (fir::hasDynamicSize(pointeeTy))
960+
return false;
942961

943-
if (fir::isa_trivial(eleTy)) {
962+
if (fir::isa_trivial(pointeeTy)) {
944963
auto loadVal = fir::LoadOp::create(builder, loc, source);
945964
fir::StoreOp::create(builder, loc, loadVal, destination);
946965
} else {

0 commit comments

Comments
 (0)