@@ -2304,6 +2304,35 @@ class FirConverter : public Fortran::lower::AbstractConverter {
23042304 }
23052305 }
23062306
2307+ // Add AccessGroups attribute on operations in fir::DoLoopOp if this
2308+ // operation has the parallelAccesses attribute.
2309+ void attachAccessGroupAttrToDoLoopOperations (fir::DoLoopOp &doLoop) {
2310+ if (auto loopAnnotAttr = doLoop.getLoopAnnotationAttr ()) {
2311+ if (loopAnnotAttr.getParallelAccesses ().size ()) {
2312+ llvm::SmallVector<mlir::Attribute> accessGroupAttrs (
2313+ loopAnnotAttr.getParallelAccesses ().begin (),
2314+ loopAnnotAttr.getParallelAccesses ().end ());
2315+ mlir::ArrayAttr attrs =
2316+ mlir::ArrayAttr::get (builder->getContext (), accessGroupAttrs);
2317+ doLoop.walk ([&](mlir::Operation *op) {
2318+ if (fir::StoreOp storeOp = mlir::dyn_cast<fir::StoreOp>(op)) {
2319+ storeOp.setAccessGroupsAttr (attrs);
2320+ } else if (fir::LoadOp loadOp = mlir::dyn_cast<fir::LoadOp>(op)) {
2321+ loadOp.setAccessGroupsAttr (attrs);
2322+ } else if (hlfir::AssignOp assignOp =
2323+ mlir::dyn_cast<hlfir::AssignOp>(op)) {
2324+ // In some loops, the HLFIR AssignOp operation can be translated
2325+ // into FIR operation(s) containing StoreOp. It is therefore
2326+ // necessary to forward the AccessGroups attribute.
2327+ assignOp.getOperation ()->setAttr (" access_groups" , attrs);
2328+ } else if (fir::CallOp callOp = mlir::dyn_cast<fir::CallOp>(op)) {
2329+ callOp.setAccessGroupsAttr (attrs);
2330+ }
2331+ });
2332+ }
2333+ }
2334+ }
2335+
23072336 // / Generate FIR for a DO construct. There are six variants:
23082337 // / - unstructured infinite and while loops
23092338 // / - structured and unstructured increment loops
@@ -2452,6 +2481,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
24522481 // This call may generate a branch in some contexts.
24532482 genFIR (endDoEval, unstructuredContext);
24542483
2484+ // Add AccessGroups attribute on operations in fir::DoLoopOp if necessary
2485+ for (IncrementLoopInfo &info : incrementLoopNestInfo)
2486+ if (auto loopOp = mlir::dyn_cast_if_present<fir::DoLoopOp>(info.loopOp ))
2487+ attachAccessGroupAttrToDoLoopOperations (loopOp);
2488+
24552489 if (!incrementLoopNestInfo.empty () &&
24562490 incrementLoopNestInfo.back ().isConcurrent )
24572491 localSymbols.popScope ();
@@ -2540,22 +2574,31 @@ class FirConverter : public Fortran::lower::AbstractConverter {
25402574 {}, {}, {}, {});
25412575 }
25422576
2577+ // Enabling loop vectorization attribute.
2578+ mlir::LLVM::LoopVectorizeAttr
2579+ genLoopVectorizeAttr (mlir::BoolAttr disableAttr) {
2580+ mlir::LLVM::LoopVectorizeAttr va;
2581+ if (disableAttr)
2582+ va = mlir::LLVM::LoopVectorizeAttr::get (builder->getContext (),
2583+ /* disable=*/ disableAttr, {}, {},
2584+ {}, {}, {}, {});
2585+ return va;
2586+ }
2587+
25432588 void addLoopAnnotationAttr (
25442589 IncrementLoopInfo &info,
25452590 llvm::SmallVectorImpl<const Fortran::parser::CompilerDirective *> &dirs) {
2546- mlir::LLVM::LoopVectorizeAttr va ;
2591+ mlir::BoolAttr disableVecAttr ;
25472592 mlir::LLVM::LoopUnrollAttr ua;
25482593 mlir::LLVM::LoopUnrollAndJamAttr uja;
2594+ llvm::SmallVector<mlir::LLVM::AccessGroupAttr> aga;
25492595 bool has_attrs = false ;
25502596 for (const auto *dir : dirs) {
25512597 Fortran::common::visit (
25522598 Fortran::common::visitors{
25532599 [&](const Fortran::parser::CompilerDirective::VectorAlways &) {
2554- mlir::BoolAttr falseAttr =
2600+ disableVecAttr =
25552601 mlir::BoolAttr::get (builder->getContext (), false );
2556- va = mlir::LLVM::LoopVectorizeAttr::get (builder->getContext (),
2557- /* disable=*/ falseAttr,
2558- {}, {}, {}, {}, {}, {});
25592602 has_attrs = true ;
25602603 },
25612604 [&](const Fortran::parser::CompilerDirective::Unroll &u) {
@@ -2567,11 +2610,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
25672610 has_attrs = true ;
25682611 },
25692612 [&](const Fortran::parser::CompilerDirective::NoVector &u) {
2570- mlir::BoolAttr trueAttr =
2613+ disableVecAttr =
25712614 mlir::BoolAttr::get (builder->getContext (), true );
2572- va = mlir::LLVM::LoopVectorizeAttr::get (builder->getContext (),
2573- /* disable=*/ trueAttr,
2574- {}, {}, {}, {}, {}, {});
25752615 has_attrs = true ;
25762616 },
25772617 [&](const Fortran::parser::CompilerDirective::NoUnroll &u) {
@@ -2582,13 +2622,21 @@ class FirConverter : public Fortran::lower::AbstractConverter {
25822622 uja = genLoopUnrollAndJamAttr (/* unrollingFactor=*/ 0 );
25832623 has_attrs = true ;
25842624 },
2585-
2625+ [&](const Fortran::parser::CompilerDirective::IVDep &iv) {
2626+ disableVecAttr =
2627+ mlir::BoolAttr::get (builder->getContext (), false );
2628+ aga.push_back (
2629+ mlir::LLVM::AccessGroupAttr::get (builder->getContext ()));
2630+ has_attrs = true ;
2631+ },
25862632 [&](const auto &) {}},
25872633 dir->u );
25882634 }
2635+ mlir::LLVM::LoopVectorizeAttr va = genLoopVectorizeAttr (disableVecAttr);
25892636 mlir::LLVM::LoopAnnotationAttr la = mlir::LLVM::LoopAnnotationAttr::get (
25902637 builder->getContext (), {}, /* vectorize=*/ va, {}, /* unroll*/ ua,
2591- /* unroll_and_jam*/ uja, {}, {}, {}, {}, {}, {}, {}, {}, {}, {});
2638+ /* unroll_and_jam*/ uja, {}, {}, {}, {}, {}, {}, {}, {}, {},
2639+ /* parallelAccesses*/ aga);
25922640 if (has_attrs) {
25932641 if (auto loopOp = mlir::dyn_cast<fir::DoLoopOp>(info.loopOp ))
25942642 loopOp.setLoopAnnotationAttr (la);
@@ -3318,6 +3366,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
33183366 [&](const Fortran::parser::CompilerDirective::Prefetch &prefetch) {
33193367 TODO (getCurrentLocation (), " !$dir prefetch" );
33203368 },
3369+ [&](const Fortran::parser::CompilerDirective::IVDep &) {
3370+ attachDirectiveToLoop (dir, &eval);
3371+ },
33213372 [&](const auto &) {}},
33223373 dir.u );
33233374 }
0 commit comments