================ @@ -183,173 +466,119 @@ getComponentObject(std::optional<Object> object, return getComponentObject(baseObj.value(), semaCtx); } -static void -generateMemberPlacementIndices(const Object &object, - llvm::SmallVectorImpl<int> &indices, - semantics::SemanticsContext &semaCtx) { +void generateMemberPlacementIndices(const Object &object, + llvm::SmallVectorImpl<int64_t> &indices, + semantics::SemanticsContext &semaCtx) { + assert(indices.empty() && "indices vector passed to " + "generateMemberPlacementIndices should be empty"); auto compObj = getComponentObject(object, semaCtx); + while (compObj) { - indices.push_back(getComponentPlacementInParent(compObj->sym())); + int64_t index = getComponentPlacementInParent(compObj->sym()); + assert( + index >= 0 && + "unexpected index value returned from getComponentPlacementInParent"); + indices.push_back(index); compObj = getComponentObject(getBaseObject(compObj.value(), semaCtx), semaCtx); } - indices = llvm::SmallVector<int>{llvm::reverse(indices)}; + indices = llvm::SmallVector<int64_t>{llvm::reverse(indices)}; } -void addChildIndexAndMapToParent( - const omp::Object &object, - std::map<const semantics::Symbol *, - llvm::SmallVector<OmpMapMemberIndicesData>> &parentMemberIndices, - mlir::omp::MapInfoOp &mapOp, semantics::SemanticsContext &semaCtx) { - std::optional<evaluate::DataRef> dataRef = ExtractDataRef(object.ref()); - assert(dataRef.has_value() && - "DataRef could not be extracted during mapping of derived type " - "cannot proceed"); - const semantics::Symbol *parentSym = &dataRef->GetFirstSymbol(); - assert(parentSym && "Could not find parent symbol during lower of " - "a component member in OpenMP map clause"); - llvm::SmallVector<int> indices; +void OmpMapParentAndMemberData::addChildIndexAndMapToParent( + const omp::Object &object, mlir::omp::MapInfoOp &mapOp, + semantics::SemanticsContext &semaCtx) { + llvm::SmallVector<int64_t> indices; generateMemberPlacementIndices(object, indices, semaCtx); - parentMemberIndices[parentSym].push_back({indices, mapOp}); + memberPlacementIndices.push_back(indices); + memberMap.push_back(mapOp); } -static void calculateShapeAndFillIndices( - llvm::SmallVectorImpl<int64_t> &shape, - llvm::SmallVectorImpl<OmpMapMemberIndicesData> &memberPlacementData) { - shape.push_back(memberPlacementData.size()); - size_t largestIndicesSize = - std::max_element(memberPlacementData.begin(), memberPlacementData.end(), - [](auto a, auto b) { - return a.memberPlacementIndices.size() < - b.memberPlacementIndices.size(); - }) - ->memberPlacementIndices.size(); - shape.push_back(largestIndicesSize); - - // DenseElementsAttr expects a rectangular shape for the data, so all - // index lists have to be of the same length, this emplaces -1 as filler. - for (auto &v : memberPlacementData) { - if (v.memberPlacementIndices.size() < largestIndicesSize) { - auto *prevEnd = v.memberPlacementIndices.end(); - v.memberPlacementIndices.resize(largestIndicesSize); - std::fill(prevEnd, v.memberPlacementIndices.end(), -1); - } +bool isMemberOrParentAllocatableOrPointer( + const Object &object, semantics::SemanticsContext &semaCtx) { + if (semantics::IsAllocatableOrObjectPointer(object.sym())) + return true; + + auto compObj = getBaseObject(object, semaCtx); + while (compObj) { + if (semantics::IsAllocatableOrObjectPointer(compObj.value().sym())) + return true; + compObj = getBaseObject(compObj.value(), semaCtx); } -} -static mlir::DenseIntElementsAttr createDenseElementsAttrFromIndices( - llvm::SmallVectorImpl<OmpMapMemberIndicesData> &memberPlacementData, - fir::FirOpBuilder &builder) { - llvm::SmallVector<int64_t> shape; - calculateShapeAndFillIndices(shape, memberPlacementData); - - llvm::SmallVector<int> indicesFlattened = - std::accumulate(memberPlacementData.begin(), memberPlacementData.end(), - llvm::SmallVector<int>(), - [](llvm::SmallVector<int> &x, OmpMapMemberIndicesData y) { - x.insert(x.end(), y.memberPlacementIndices.begin(), - y.memberPlacementIndices.end()); - return x; - }); - - return mlir::DenseIntElementsAttr::get( - mlir::VectorType::get(shape, - mlir::IntegerType::get(builder.getContext(), 32)), - indicesFlattened); + return false; } void insertChildMapInfoIntoParent( - lower::AbstractConverter &converter, - std::map<const semantics::Symbol *, - llvm::SmallVector<OmpMapMemberIndicesData>> &parentMemberIndices, + lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx, + lower::StatementContext &stmtCtx, + std::map<Object, OmpMapParentAndMemberData> &parentMemberIndices, llvm::SmallVectorImpl<mlir::Value> &mapOperands, llvm::SmallVectorImpl<const semantics::Symbol *> &mapSyms) { + fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); for (auto indices : parentMemberIndices) { - bool parentExists = false; - size_t parentIdx; - for (parentIdx = 0; parentIdx < mapSyms.size(); ++parentIdx) { - if (mapSyms[parentIdx] == indices.first) { - parentExists = true; - break; - } - } - - if (parentExists) { + auto *parentIter = llvm::find_if( + mapSyms, [&indices](auto v) { return v == indices.first.sym(); }); + if (parentIter != mapSyms.end()) { auto mapOp = llvm::cast<mlir::omp::MapInfoOp>( - mapOperands[parentIdx].getDefiningOp()); + mapOperands[std::distance(mapSyms.begin(), parentIter)] + .getDefiningOp()); // NOTE: To maintain appropriate SSA ordering, we move the parent map // which will now have references to its children after the last // of its members to be generated. This is necessary when a user // has defined a series of parent and children maps where the parent // precedes the children. An alternative, may be to do // delayed generation of map info operations from the clauses and - // organize them first before generation. - mapOp->moveAfter(indices.second.back().memberMap); + // organize them first before generation. Or to use the + // topologicalSort utility which will enforce a stronger SSA + // dominance ordering at the cost of efficiency/time. + mapOp->moveAfter(indices.second.memberMap.back()); - for (auto memberIndicesData : indices.second) - mapOp.getMembersMutable().append( - memberIndicesData.memberMap.getResult()); + for (mlir::omp::MapInfoOp memberMap : indices.second.memberMap) + mapOp.getMembersMutable().append(memberMap.getResult()); - mapOp.setMembersIndexAttr(createDenseElementsAttrFromIndices( - indices.second, converter.getFirOpBuilder())); + mapOp.setMembersIndexAttr(firOpBuilder.create2DI64ArrayAttr( + indices.second.memberPlacementIndices)); } else { // NOTE: We take the map type of the first child, this may not // be the correct thing to do, however, we shall see. For the moment // it allows this to work with enter and exit without causing MLIR // verification issues. The more appropriate thing may be to take // the "main" map type clause from the directive being used. - uint64_t mapType = indices.second[0].memberMap.getMapType().value_or(0); - - // create parent to emplace and bind members - mlir::Value origSymbol = converter.getSymbolAddress(*indices.first); + uint64_t mapType = indices.second.memberMap[0].getMapType().value_or(0); llvm::SmallVector<mlir::Value> members; - for (OmpMapMemberIndicesData memberIndicesData : indices.second) - members.push_back((mlir::Value)memberIndicesData.memberMap); - - mlir::Value mapOp = createMapInfoOp( - converter.getFirOpBuilder(), origSymbol.getLoc(), origSymbol, - /*varPtrPtr=*/mlir::Value(), indices.first->name().ToString(), - /*bounds=*/{}, members, - createDenseElementsAttrFromIndices(indices.second, - converter.getFirOpBuilder()), - mapType, mlir::omp::VariableCaptureKind::ByRef, origSymbol.getType(), + for (mlir::omp::MapInfoOp memberMap : indices.second.memberMap) ---------------- skatrak wrote:
Nit: Call `members.reserve(indices.second.memberMap.size())` before the loop. https://github.com/llvm/llvm-project/pull/113557 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits