[flang] Lower volatile class types (#138607)
So far, only boxes and references have had their volatile attribute set during lowering. This patch enables the volatility of classes to be properly represented in the ir, same as box and ref. For simple cases, not much needs to change in the codegen or conversion patterns because the prior work on volatile refs/boxes propagates volatility already. I am running further testing with the strict verification enabled to find remaining cases of incorrect/missing volatile propagation.
This commit is contained in:
@@ -205,17 +205,8 @@ private:
|
||||
partInfo.resultShape =
|
||||
hlfir::genShape(getLoc(), getBuilder(), *partInfo.base);
|
||||
|
||||
// Dynamic type of polymorphic base must be kept if the designator is
|
||||
// polymorphic.
|
||||
if (isPolymorphic(designatorNode))
|
||||
return fir::ClassType::get(resultValueType);
|
||||
// Character scalar with dynamic length needs a fir.boxchar to hold the
|
||||
// designator length.
|
||||
auto charType = mlir::dyn_cast<fir::CharacterType>(resultValueType);
|
||||
if (charType && charType.hasDynamicLen())
|
||||
return fir::BoxCharType::get(charType.getContext(), charType.getFKind());
|
||||
|
||||
// When volatile is enabled, enable volatility on the designatory type.
|
||||
// Enable volatility on the designatory type if it has the VOLATILE
|
||||
// attribute or if the base is volatile.
|
||||
bool isVolatile = false;
|
||||
|
||||
// Check if this should be a volatile reference
|
||||
@@ -236,6 +227,17 @@ private:
|
||||
isVolatile = true;
|
||||
}
|
||||
|
||||
// Dynamic type of polymorphic base must be kept if the designator is
|
||||
// polymorphic.
|
||||
if (isPolymorphic(designatorNode))
|
||||
return fir::ClassType::get(resultValueType, isVolatile);
|
||||
|
||||
// Character scalar with dynamic length needs a fir.boxchar to hold the
|
||||
// designator length.
|
||||
auto charType = mlir::dyn_cast<fir::CharacterType>(resultValueType);
|
||||
if (charType && charType.hasDynamicLen())
|
||||
return fir::BoxCharType::get(charType.getContext(), charType.getFKind());
|
||||
|
||||
// Check if the base type is volatile
|
||||
if (partInfo.base.has_value()) {
|
||||
mlir::Type baseType = partInfo.base.value().getType();
|
||||
|
||||
43
flang/test/Lower/volatile-derived-type-pointer.f90
Normal file
43
flang/test/Lower/volatile-derived-type-pointer.f90
Normal file
@@ -0,0 +1,43 @@
|
||||
! RUN: bbc %s -o - --strict-fir-volatile-verifier | FileCheck %s
|
||||
|
||||
! Ensure that assignments between volatile classes/derived type pointer/targets
|
||||
! lower to the correct hlfir declare/designate operations.
|
||||
|
||||
module m
|
||||
type :: dt
|
||||
character :: c0="!"
|
||||
integer :: i=0
|
||||
character :: c1="!"
|
||||
end type
|
||||
end module
|
||||
program dataptrvolatile
|
||||
use m
|
||||
implicit none
|
||||
type(dt), volatile , target :: arr(100, 100), arr1(10000), t(100,100)
|
||||
class(dt), volatile , pointer :: ptr(:, :)
|
||||
integer :: i, j
|
||||
do i =1, 100
|
||||
do j =i, 100
|
||||
arr(i:, j:) = dt(i=-i)
|
||||
ptr(i:, j:) => arr(i:, j:)
|
||||
t(i:, j:) = ptr(i:, j:)
|
||||
end do
|
||||
end do
|
||||
end
|
||||
|
||||
! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}}(%{{.+}}) {fortran_attrs = #fir.var_attrs<target, volatile>, uniq_name = "_QFEarr"} : (!fir.ref<!fir.array<100x100x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>, !fir.shape<2>) -> (!fir.ref<!fir.array<100x100x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>, !fir.ref<!fir.array<100x100x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>)
|
||||
! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}}(%{{.+}}) {fortran_attrs = #fir.var_attrs<target, volatile>, uniq_name = "_QFEarr1"} : (!fir.ref<!fir.array<10000x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>, !fir.shape<1>) -> (!fir.ref<!fir.array<10000x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>, !fir.ref<!fir.array<10000x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>)
|
||||
! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {uniq_name = "_QFEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs<pointer, volatile>, uniq_name = "_QFEptr"} : (!fir.ref<!fir.class<!fir.ptr<!fir.array<?x?x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>>, volatile>, volatile>) -> (!fir.ref<!fir.class<!fir.ptr<!fir.array<?x?x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>>, volatile>, volatile>, !fir.ref<!fir.class<!fir.ptr<!fir.array<?x?x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>>, volatile>, volatile>)
|
||||
! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}}(%{{.+}}) {fortran_attrs = #fir.var_attrs<target, volatile>, uniq_name = "_QFEt"} : (!fir.ref<!fir.array<100x100x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>, !fir.shape<2>) -> (!fir.ref<!fir.array<100x100x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>, !fir.ref<!fir.array<100x100x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>)
|
||||
! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>) -> (!fir.ref<!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, !fir.ref<!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>)
|
||||
! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0{"c0"} typeparams %{{.+}} : (!fir.ref<!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, index) -> !fir.ref<!fir.char<1>>
|
||||
! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} typeparams %{{.+}} {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQclX21"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
|
||||
! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0{"i"} : (!fir.ref<!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>) -> !fir.ref<i32>
|
||||
! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0{"c1"} typeparams %{{.+}} : (!fir.ref<!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, index) -> !fir.ref<!fir.char<1>>
|
||||
! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} typeparams %{{.+}} {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQclX21"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
|
||||
! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0 (%{{.+}}:%{{.+}}:%{{.+}}, %{{.+}}:%{{.+}}:%{{.+}}) shape %{{.+}} : (!fir.ref<!fir.array<100x100x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>
|
||||
! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0 (%{{.+}}:%{{.+}}:%{{.+}}, %{{.+}}:%{{.+}}:%{{.+}}) shape %{{.+}} : (!fir.ref<!fir.array<100x100x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>
|
||||
! CHECK: %{{.+}} = hlfir.designate %{{.+}} (%{{.+}}:%{{.+}}:%{{.+}}, %{{.+}}:%{{.+}}:%{{.+}}) shape %{{.+}} : (!fir.class<!fir.ptr<!fir.array<?x?x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>>, volatile>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>
|
||||
! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0 (%{{.+}}:%{{.+}}:%{{.+}}, %{{.+}}:%{{.+}}:%{{.+}}) shape %{{.+}} : (!fir.ref<!fir.array<100x100x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTdt{c0:!fir.char<1>,i:i32,c1:!fir.char<1>}>>, volatile>
|
||||
Reference in New Issue
Block a user