@@ -1640,6 +1640,7 @@ getRefPtrIfDeclareTarget(mlir::Value value,
1640
1640
// value) more than neccessary.
1641
1641
struct MapInfoData : llvm::OpenMPIRBuilder::MapInfosTy {
1642
1642
llvm::SmallVector<bool , 4 > IsDeclareTarget;
1643
+ llvm::SmallVector<bool , 4 > IsAMember;
1643
1644
llvm::SmallVector<mlir::Operation *, 4 > MapClause;
1644
1645
llvm::SmallVector<llvm::Value *, 4 > OriginalValue;
1645
1646
// Stripped off array/pointer to get the underlying
@@ -1728,13 +1729,11 @@ void collectMapDataFromMapOperands(MapInfoData &mapData,
1728
1729
LLVM::ModuleTranslation &moduleTranslation,
1729
1730
DataLayout &dl,
1730
1731
llvm::IRBuilderBase &builder) {
1731
- auto mapFill = [&](mlir::Value mapValue) {
1732
- assert (mlir::isa<mlir::omp::MapInfoOp>(mapValue.getDefiningOp ()) &&
1733
- " missing map info operation or incorrect map info operation type" );
1732
+ for (mlir::Value mapValue : mapOperands) {
1734
1733
if (auto mapOp = mlir::dyn_cast_if_present<mlir::omp::MapInfoOp>(
1735
1734
mapValue.getDefiningOp ())) {
1736
- mapData.OriginalValue .push_back (moduleTranslation. lookupValue (
1737
- mapOp. getVarPtrPtr () ? mapOp. getVarPtrPtr () : mapOp.getVarPtr ()));
1735
+ mapData.OriginalValue .push_back (
1736
+ moduleTranslation. lookupValue ( mapOp.getVarPtr ()));
1738
1737
mapData.Pointers .push_back (mapData.OriginalValue .back ());
1739
1738
1740
1739
if (llvm::Value *refPtr =
@@ -1759,41 +1758,27 @@ void collectMapDataFromMapOperands(MapInfoData &mapData,
1759
1758
mapOp.getLoc (), *moduleTranslation.getOpenMPBuilder ()));
1760
1759
mapData.DevicePointers .push_back (
1761
1760
llvm::OpenMPIRBuilder::DeviceInfoTy::None);
1762
- }
1763
- };
1764
1761
1765
- // In the case of Fortran descriptors some members get added implicitly
1766
- // after the target region has been generated during CodeGen lowering
1767
- // which prevents them from being added trivially to the target region
1768
- // as map arguments, we must handle this case here by generating
1769
- // MapInfoData for them.
1770
- // TODO: Revisit this when implementing derived types explicit member
1771
- // mapping, we likely want to represent these identically to simplify
1772
- // the overall lowering
1773
- SmallVector<Value> mapMemberOperands;
1774
- for (size_t i = 0 ; i < mapOperands.size (); ++i) {
1775
- auto mapInfoOp =
1776
- mlir::dyn_cast<mlir::omp::MapInfoOp>(mapOperands[i].getDefiningOp ());
1777
- for (auto members : mapInfoOp.getMembers ()) {
1778
- if (!std::any_of (mapOperands.begin (), mapOperands.end (),
1779
- [&](auto mapOp) {
1780
- return mapOp.getDefiningOp () ==
1781
- members.getDefiningOp ();
1782
- }) &&
1783
- !std::any_of (mapMemberOperands.begin (), mapMemberOperands.end (),
1784
- [&](auto mapOp) {
1785
- return mapOp.getDefiningOp () ==
1786
- members.getDefiningOp ();
1787
- }))
1788
- mapMemberOperands.push_back (members);
1762
+ // Check if this is a member mapping and correctly assign that it is, if
1763
+ // it is a member of a larger object.
1764
+ // TODO: Need better handling of members, and distinguishing of members
1765
+ // that are implicitly allocated on device vs explicitly passed in as
1766
+ // arguments.
1767
+ // TODO: May require some further additions to support nested record
1768
+ // types, i.e. member maps that can have member maps.
1769
+ mapData.IsAMember .push_back (false );
1770
+ for (mlir::Value mapValue : mapOperands) {
1771
+ if (auto map = mlir::dyn_cast_if_present<mlir::omp::MapInfoOp>(
1772
+ mapValue.getDefiningOp ())) {
1773
+ for (auto member : map.getMembers ()) {
1774
+ if (member == mapOp) {
1775
+ mapData.IsAMember .back () = true ;
1776
+ }
1777
+ }
1778
+ }
1779
+ }
1789
1780
}
1790
1781
}
1791
-
1792
- for (mlir::Value mapValue : mapOperands)
1793
- mapFill (mapValue);
1794
-
1795
- for (mlir::Value mapValue : mapMemberOperands)
1796
- mapFill (mapValue);
1797
1782
}
1798
1783
1799
1784
static void processMapWithMembersOf (
@@ -1960,35 +1945,22 @@ static void genMapInfos(llvm::IRBuilderBase &builder,
1960
1945
combinedInfo.Names .clear ();
1961
1946
};
1962
1947
1963
- llvm::SmallVector<size_t , 4 > primaryMapIdx;
1964
- for (size_t i = 0 ; i < mapData.MapClause .size (); ++i) {
1965
- primaryMapIdx.push_back (i);
1966
- }
1967
-
1968
- // TODO: Handle nested MembersOf, currently only cares about the first level
1969
- // of nesting (all that was relevant for Fortran descriptors), but a slight
1970
- // refactoring of mapInfoData to hold nestings or membersOf may be a better
1971
- // approach to simplify things.
1972
- for (size_t i = 0 ; i < mapData.MapClause .size (); ++i) {
1973
- auto mapInfoOp = mlir::dyn_cast<mlir::omp::MapInfoOp>(mapData.MapClause [i]);
1974
- for (auto member : mapInfoOp.getMembers ()) {
1975
- for (size_t j = 0 ; j < primaryMapIdx.size (); j++) {
1976
- if (member.getDefiningOp () == mapData.MapClause [primaryMapIdx[j]]) {
1977
- primaryMapIdx.erase (&primaryMapIdx[j]);
1978
- j--;
1979
- }
1980
- }
1981
- }
1982
- }
1983
-
1984
1948
// We operate under the assumption that all vectors that are
1985
1949
// required in MapInfoData are of equal lengths (either filled with
1986
1950
// default constructed data or appropiate information) so we can
1987
1951
// utilise the size from any component of MapInfoData, if we can't
1988
1952
// something is missing from the initial MapInfoData construction.
1989
- for (unsigned long i : primaryMapIdx) {
1990
- auto mapInfoOp = mlir::dyn_cast<mlir::omp::MapInfoOp>(mapData.MapClause [i]);
1953
+ for (size_t i = 0 ; i < mapData.MapClause .size (); ++i) {
1954
+ // NOTE/TODO: We currently do not handle member mapping seperately from it's
1955
+ // parent or explicit mapping of a parent and member in the same operation,
1956
+ // this will need to change in the near future, for now we primarily handle
1957
+ // descriptor mapping from fortran, generalised as mapping record types
1958
+ // with implicit member maps. This lowering needs further generalisation to
1959
+ // fully support fortran derived types, and C/C++ structures and classes.
1960
+ if (mapData.IsAMember [i])
1961
+ continue ;
1991
1962
1963
+ auto mapInfoOp = mlir::dyn_cast<mlir::omp::MapInfoOp>(mapData.MapClause [i]);
1992
1964
if (!mapInfoOp.getMembers ().empty ()) {
1993
1965
processMapWithMembersOf (moduleTranslation, builder, *ompBuilder, dl,
1994
1966
combinedInfo, mapData, i, isTargetParams);
@@ -2136,7 +2108,7 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
2136
2108
deviceID = intAttr.getInt ();
2137
2109
2138
2110
RTLFn = llvm::omp::OMPRTL___tgt_target_data_update_mapper;
2139
- mapOperands = updateDataOp.getMotionOperands ();
2111
+ mapOperands = updateDataOp.getMapOperands ();
2140
2112
return success ();
2141
2113
})
2142
2114
.Default ([&](Operation *op) {
@@ -2633,7 +2605,12 @@ convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder,
2633
2605
llvm::SmallVector<llvm::Value *, 4 > kernelInput;
2634
2606
for (size_t i = 0 ; i < mapOperands.size (); ++i) {
2635
2607
// declare target arguments are not passed to kernels as arguments
2636
- if (!mapData.IsDeclareTarget [i])
2608
+ // TODO: We currently do not handle cases where a member is explicitly
2609
+ // passed in as an argument, this will likley need to be handled in
2610
+ // the near future, rather than using IsAMember, it may be better to
2611
+ // test if the relevant BlockArg is used within the target region and
2612
+ // then use that as a basis for exclusion in the kernel inputs.
2613
+ if (!mapData.IsDeclareTarget [i] && !mapData.IsAMember [i])
2637
2614
kernelInput.push_back (mapData.OriginalValue [i]);
2638
2615
}
2639
2616
0 commit comments