Lines Matching defs:hlfir
8 // In some special cases we can bufferize hlfir expressions in a more optimal
38 namespace hlfir {
41 } // namespace hlfir
50 /// %expr = hlfir.elemental %shape : [...] {
52 /// %0 = hlfir.designate %array(%arg0)
54 /// hlfir.yield_element %element
56 /// hlfir.assign %expr to %array
57 /// hlfir.destroy %expr
62 /// %expr = hlfir.elemental %shape : [...] {
64 /// %0 = hlfir.designate %read_array(%arg0)
66 /// hlfir.yield_element %element
70 /// hlfir.assign %expr to %write_array
71 /// hlfir.destroy %expr
80 : public mlir::OpRewritePattern<hlfir::ElementalOp> {
84 hlfir::AssignOp assign;
85 hlfir::DestroyOp destroy;
88 static std::optional<MatchInfo> findMatch(hlfir::ElementalOp elemental);
90 /// Returns the array indices for the given hlfir.designate.
95 getDesignatorIndices(hlfir::DesignateOp designate);
98 using mlir::OpRewritePattern<hlfir::ElementalOp>::OpRewritePattern;
101 matchAndRewrite(hlfir::ElementalOp elemental,
154 // %ref = hlfir.designate %array(%index)
156 if (auto designate = accessedVal.getDefiningOp<hlfir::DesignateOp>()) {
170 // by two hlfir.designate operations.
186 // Analyzes two hlfir.designate results and returns the overlap kind.
313 auto des1 = ref1.getDefiningOp<hlfir::DesignateOp>();
314 auto des2 = ref2.getDefiningOp<hlfir::DesignateOp>();
363 // hlfir.designate %6#0 (%c2:%c7999:%c1, %c1:%c120:%c1, %0)
364 // hlfir.designate %6#0 (%c2:%c7999:%c1, %c1:%c120:%c1, %1)
371 // hlfir.designate %6#0 (%c2:%c2:%c1)
372 // hlfir.designate %6#0 (%c2)
442 hlfir::DesignateOp designate) {
454 // %19 = hlfir.designate %13 (%18) : (!fir.box<...>, index) -> ...
462 // %19 = hlfir.designate %13 (...) : (!fir.box<...>, index) -> ...
508 ElementalAssignBufferization::findMatch(hlfir::ElementalOp elemental) {
518 if (hlfir::elementalOpMustProduceTemp(elemental)) {
526 .Case([&](hlfir::AssignOp op) { match.assign = op; })
527 .Case([&](hlfir::DestroyOp op) { match.destroy = op; });
535 // TODO: this could be extended to also allow hlfir.expr by first bufferizing
548 mlir::Type eleTy = hlfir::getFortranElementType(arrayType);
559 // hlfir.assign. If it is not a realloc assignment, we can trust that
572 // hlfir.assign, check there are no effects which make this unsafe
622 effect.getValue().getDefiningOp<hlfir::DesignateOp>()) {
677 hlfir::ElementalOp elemental, mlir::PatternRewriter &rewriter) const {
685 auto extents = hlfir::getIndexExtents(loc, builder, elemental.getShape());
690 // Generate a loop nest looping around the hlfir.elemental shape and clone
691 // hlfir.elemental region inside the inner loop
692 hlfir::LoopNest loopNest =
693 hlfir::genLoopNest(loc, builder, extents, !elemental.isOrdered(),
696 auto yield = hlfir::inlineElementalOp(loc, builder, elemental,
698 hlfir::Entity elementValue{yield.getElementValue()};
702 auto arrayElement = hlfir::getElementAt(
703 loc, builder, hlfir::Entity{match->array}, loopNest.oneBasedIndices);
704 builder.create<hlfir::AssignOp>(
714 /// Expand hlfir.assign of a scalar RHS to array LHS into a loop nest
716 /// hlfir.assign %cst to %0 : f32, !fir.ref<!fir.array<6x6xf32>>
720 /// %1 = hlfir.designate %0 (%arg1, %arg0) :
722 /// hlfir.assign %cst to %1 : f32, !fir.ref<f32>
726 : public mlir::OpRewritePattern<hlfir::AssignOp> {
729 using mlir::OpRewritePattern<hlfir::AssignOp>::OpRewritePattern;
732 matchAndRewrite(hlfir::AssignOp assign,
737 hlfir::AssignOp assign, mlir::PatternRewriter &rewriter) const {
747 hlfir::Entity lhs{assign.getLhs()};
760 lhs = hlfir::derefPointersAndAllocatables(loc, builder, lhs);
761 mlir::Value shape = hlfir::genShape(loc, builder, lhs);
763 hlfir::getIndexExtents(loc, builder, shape);
764 hlfir::LoopNest loopNest =
765 hlfir::genLoopNest(loc, builder, extents, /*isUnordered=*/true,
769 hlfir::getElementAt(loc, builder, lhs, loopNest.oneBasedIndices);
770 builder.create<hlfir::AssignOp>(loc, rhs, arrayElement);
781 auto extents = hlfir::getIndexExtents(loc, builder, shape);
864 /// %e = hlfir.elemental %shape unordered
865 /// %r = hlfir.count %e
882 if constexpr (std::is_same_v<Op, hlfir::AnyOp> ||
883 std::is_same_v<Op, hlfir::AllOp> ||
884 std::is_same_v<Op, hlfir::CountOp>) {
887 } else if constexpr (std::is_same_v<Op, hlfir::MaxvalOp> ||
888 std::is_same_v<Op, hlfir::MinvalOp>) {
891 } else if constexpr (std::is_same_v<Op, hlfir::MaxlocOp> ||
892 std::is_same_v<Op, hlfir::MinlocOp>) {
900 hlfir::ElementalOp elemental;
901 hlfir::DesignateOp designate;
903 if ((elemental = source.template getDefiningOp<hlfir::ElementalOp>())) {
906 source.template getDefiningOp<hlfir::DesignateOp>())) {
925 auto resEntity = hlfir::Entity{designate.getResult()};
926 auto tmp = builder.create<hlfir::DesignateOp>(
939 if constexpr (std::is_same_v<Op, hlfir::AnyOp>) {
951 } else if constexpr (std::is_same_v<Op, hlfir::AllOp>) {
963 } else if constexpr (std::is_same_v<Op, hlfir::CountOp>) {
980 } else if constexpr (std::is_same_v<Op, hlfir::MaxlocOp> ||
981 std::is_same_v<Op, hlfir::MinlocOp>) {
985 } else if constexpr (std::is_same_v<Op, hlfir::MaxvalOp> ||
986 std::is_same_v<Op, hlfir::MinvalOp>) {
987 bool isMax = std::is_same_v<Op, hlfir::MaxvalOp>;
1012 hlfir::DestroyOp srcDestroy;
1014 srcDestroy = mlir::dyn_cast<hlfir::DestroyOp>(*srcUsers.begin());
1016 srcDestroy = mlir::dyn_cast<hlfir::DestroyOp>(*++srcUsers.begin());
1030 // %e = hlfir.elemental %shape ({ ... })
1031 // %m = hlfir.minloc %array mask %e
1043 bool isMax = std::is_same_v<Op, hlfir::MaxlocOp>;
1046 mloc.getMask().template getDefiningOp<hlfir::ElementalOp>();
1047 if (!elemental || hlfir::elementalOpMustProduceTemp(elemental))
1052 unsigned rank = mlir::cast<hlfir::ExprType>(mloc.getType()).getShape()[0];
1057 mlir::Type elementType = hlfir::getFortranElementType(arrayType);
1066 rank, hlfir::getFortranElementType(mloc.getType())));
1084 hlfir::YieldElementOp yield =
1085 hlfir::inlineElementalOp(loc, builder, elemental, oneBasedIndices);
1103 mlir::Value addr = hlfir::getElementAt(loc, builder, hlfir::Entity{array},
1124 hlfir::getFortranElementType(resultArr.getType());
1130 mlir::Value resultElemAddr = builder.create<hlfir::DesignateOp>(
1156 return builder.create<hlfir::DesignateOp>(loc, resultRefTy, resultArr,
1161 mlir::Type resultElemTy = hlfir::getFortranElementType(resultArr.getType());
1168 mlir::Value resultElemAddr = builder.create<hlfir::DesignateOp>(
1177 mlir::Value asExpr = builder.create<hlfir::AsExprOp>(
1184 llvm::SmallVector<hlfir::DestroyOp> destroys;
1185 llvm::SmallVector<hlfir::AssignOp> assigns;
1187 if (auto destroy = mlir::dyn_cast<hlfir::DestroyOp>(user))
1189 else if (auto assign = mlir::dyn_cast<hlfir::AssignOp>(user))
1196 hlfir::DestroyOp elemDestroy;
1198 elemDestroy = mlir::dyn_cast<hlfir::DestroyOp>(*elemUsers.begin());
1200 elemDestroy = mlir::dyn_cast<hlfir::DestroyOp>(*++elemUsers.begin());
1217 : public mlir::OpRewritePattern<hlfir::EvaluateInMemoryOp> {
1220 using mlir::OpRewritePattern<hlfir::EvaluateInMemoryOp>::OpRewritePattern;
1223 matchAndRewrite(hlfir::EvaluateInMemoryOp,
1228 tryUsingAssignLhsDirectly(hlfir::EvaluateInMemoryOp evalInMem,
1231 hlfir::DestroyOp destroy;
1232 hlfir::AssignOp assign;
1237 .Case([&](hlfir::AssignOp op) { assign = op; })
1238 .Case([&](hlfir::DestroyOp op) { destroy = op; });
1244 hlfir::Entity lhs{assign.getLhs()};
1266 // Any variables affected between the hlfir.evalInMem and assignment must not
1285 mlir::Value rawLhs = hlfir::genVariableRawAddress(loc, builder, lhs);
1286 hlfir::computeEvaluateOpIn(loc, builder, evalInMem, rawLhs);
1294 hlfir::EvaluateInMemoryOp evalInMem,
1303 auto [temp, isHeapAllocated] = hlfir::computeEvaluateOpInNewTemp(
1305 rewriter.replaceOpWithNewOp<hlfir::AsExprOp>(
1311 : public hlfir::impl::OptimizedBufferizationBase<
1324 // but it might be better to run this pass on hlfir.assign
1332 patterns.insert<ReductionConversion<hlfir::CountOp>>(context);
1333 patterns.insert<ReductionConversion<hlfir::AnyOp>>(context);
1334 patterns.insert<ReductionConversion<hlfir::AllOp>>(context);
1336 // patterns.insert<ReductionConversion<hlfir::MaxlocOp>>(context);
1337 // patterns.insert<ReductionConversion<hlfir::MinlocOp>>(context);
1338 patterns.insert<ReductionConversion<hlfir::MaxvalOp>>(context);
1339 patterns.insert<ReductionConversion<hlfir::MinvalOp>>(context);
1340 patterns.insert<ReductionMaskConversion<hlfir::MinlocOp>>(context);
1341 patterns.insert<ReductionMaskConversion<hlfir::MaxlocOp>>(context);
1343 // patterns.insert<ReductionMaskConversion<hlfir::MaxvalOp>>(context);
1344 // patterns.insert<ReductionMaskConversion<hlfir::MinvalOp>>(context);