================ @@ -88,6 +91,175 @@ void gatherFuncAndVarSyms( symbolAndClause.emplace_back(clause, *object.id()); } +int getComponentPlacementInParent( + const Fortran::semantics::Symbol *componentSym) { + const auto *derived = + componentSym->owner() + .derivedTypeSpec() + ->typeSymbol() + .detailsIf<Fortran::semantics::DerivedTypeDetails>(); + assert(derived && + "expected derived type details when processing component symbol"); + int placement = 0; + for (auto t : derived->componentNames()) { + if (t == componentSym->name()) + return placement; + placement++; + } + return -1; +} + +std::optional<Object> +getCompObjOrNull(std::optional<Object> object, + Fortran::semantics::SemanticsContext &semaCtx) { + if (!object) + return std::nullopt; + + auto ref = evaluate::ExtractDataRef(*object.value().ref()); + if (!ref) + return std::nullopt; + + if (std::get_if<evaluate::Component>(&ref->u)) + return object; + + auto baseObj = getBaseObject(object.value(), semaCtx); + if (!baseObj) + return std::nullopt; + + return getCompObjOrNull(baseObj.value(), semaCtx); +} + +llvm::SmallVector<int> +generateMemberPlacementIndices(const Object &object, + Fortran::semantics::SemanticsContext &semaCtx) { + std::list<int> indices; + auto compObj = getCompObjOrNull(object, semaCtx); + while (compObj) { + indices.push_front(getComponentPlacementInParent(compObj->id())); + compObj = + getCompObjOrNull(getBaseObject(compObj.value(), semaCtx), semaCtx); + } + + return llvm::SmallVector<int>{std::begin(indices), std::end(indices)}; +} + +static void calculateShapeAndFillIndices( + llvm::SmallVectorImpl<int64_t> &shape, + llvm::SmallVector<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 implaces -1 as filler + // values + 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); + } +} + +mlir::DenseIntElementsAttr createDenseElementsAttrFromIndices( + llvm::SmallVector<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(llvm::ArrayRef<int64_t>(shape), + mlir::IntegerType::get(builder.getContext(), 32)), + llvm::ArrayRef<int32_t>(indicesFlattened)); +} + +void insertChildMapInfoIntoParent( + Fortran::lower::AbstractConverter &converter, + std::map<const Fortran::semantics::Symbol *, + llvm::SmallVector<OmpMapMemberIndicesData>> &parentMemberIndices, + llvm::SmallVectorImpl<mlir::Value> &mapOperands, + llvm::SmallVectorImpl<mlir::Type> *mapSymTypes, + llvm::SmallVectorImpl<mlir::Location> *mapSymLocs, + llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *mapSymbols) { + for (auto indices : parentMemberIndices) { + bool parentExists = false; + size_t parentIdx; + for (parentIdx = 0; parentIdx < mapSymbols->size(); ++parentIdx) + if ((*mapSymbols)[parentIdx] == indices.first) { + parentExists = true; + break; + } + + if (parentExists) { + auto mapOp = mlir::dyn_cast<mlir::omp::MapInfoOp>( ---------------- skatrak wrote:
That's a good point. If you have a more informative message for this case, I'm fine with you putting that in a separate assert. https://github.com/llvm/llvm-project/pull/82853 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits