[flang-commits] [flang] 2e1982f - [flang][openacc] Add acc.declare_action attributes on operation

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Tue Aug 15 09:44:47 PDT 2023


Author: Valentin Clement
Date: 2023-08-15T09:44:42-07:00
New Revision: 2e1982f31d27867fbd5253b4fa38f81612e52b88

URL: https://github.com/llvm/llvm-project/commit/2e1982f31d27867fbd5253b4fa38f81612e52b88
DIFF: https://github.com/llvm/llvm-project/commit/2e1982f31d27867fbd5253b4fa38f81612e52b88.diff

LOG: [flang][openacc] Add acc.declare_action attributes on operation

This patches adds the acc.declare_action attrbites on
post allocate operation and pre/post deallocate operations.

Reviewed By: razvanlupusoru

Differential Revision: https://reviews.llvm.org/D157915

Added: 
    

Modified: 
    flang/include/flang/Lower/OpenACC.h
    flang/include/flang/Optimizer/Builder/MutableBox.h
    flang/lib/Lower/Allocatable.cpp
    flang/lib/Lower/OpenACC.cpp
    flang/lib/Optimizer/Builder/MutableBox.cpp
    flang/test/Lower/OpenACC/acc-declare.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Lower/OpenACC.h b/flang/include/flang/Lower/OpenACC.h
index 8d072aa34acf09..847c279d5d2a57 100644
--- a/flang/include/flang/Lower/OpenACC.h
+++ b/flang/include/flang/Lower/OpenACC.h
@@ -40,6 +40,7 @@ struct OpenACCDeclarativeConstruct;
 
 namespace semantics {
 class SemanticsContext;
+class Symbol;
 }
 
 namespace lower {
@@ -86,6 +87,14 @@ mlir::acc::FirstprivateRecipeOp createOrGetFirstprivateRecipe(mlir::OpBuilder &,
                                                               mlir::Location,
                                                               mlir::Type);
 
+void attachDeclarePostAllocAction(AbstractConverter &, fir::FirOpBuilder &,
+                                  const Fortran::semantics::Symbol &);
+void attachDeclarePreDeallocAction(AbstractConverter &, fir::FirOpBuilder &,
+                                   mlir::Value beginOpValue,
+                                   const Fortran::semantics::Symbol &);
+void attachDeclarePostDeallocAction(AbstractConverter &, fir::FirOpBuilder &,
+                                    const Fortran::semantics::Symbol &);
+
 } // namespace lower
 } // namespace Fortran
 

diff  --git a/flang/include/flang/Optimizer/Builder/MutableBox.h b/flang/include/flang/Optimizer/Builder/MutableBox.h
index 9056f8ddd29fcc..1a67dbfa32314a 100644
--- a/flang/include/flang/Optimizer/Builder/MutableBox.h
+++ b/flang/include/flang/Optimizer/Builder/MutableBox.h
@@ -131,8 +131,8 @@ void genInlinedAllocation(fir::FirOpBuilder &builder, mlir::Location loc,
                           mlir::ValueRange lenParams, llvm::StringRef allocName,
                           bool mustBeHeap = false);
 
-void genInlinedDeallocate(fir::FirOpBuilder &builder, mlir::Location loc,
-                          const fir::MutableBoxValue &box);
+mlir::Value genInlinedDeallocate(fir::FirOpBuilder &builder, mlir::Location loc,
+                                 const fir::MutableBoxValue &box);
 
 /// When the MutableBoxValue was passed as a fir.ref<fir.box> to a call that may
 /// have modified it, update the MutableBoxValue according to the

diff  --git a/flang/lib/Lower/Allocatable.cpp b/flang/lib/Lower/Allocatable.cpp
index 2050ca1ab9d944..67324e18ef6053 100644
--- a/flang/lib/Lower/Allocatable.cpp
+++ b/flang/lib/Lower/Allocatable.cpp
@@ -16,6 +16,7 @@
 #include "flang/Lower/ConvertType.h"
 #include "flang/Lower/IterationSpace.h"
 #include "flang/Lower/Mangler.h"
+#include "flang/Lower/OpenACC.h"
 #include "flang/Lower/PFTBuilder.h"
 #include "flang/Lower/Runtime.h"
 #include "flang/Lower/StatementContext.h"
@@ -387,6 +388,7 @@ class AllocateStmtHelper {
       genSourceMoldAllocation(alloc, boxAddr, /*isSource=*/false);
     else
       genSimpleAllocation(alloc, boxAddr);
+    postAllocationAction(alloc);
   }
 
   static bool lowerBoundsAreOnes(const Allocation &alloc) {
@@ -442,6 +444,12 @@ class AllocateStmtHelper {
                                        /*mustBeHeap=*/true);
   }
 
+  void postAllocationAction(const Allocation &alloc) {
+    if (alloc.getSymbol().test(Fortran::semantics::Symbol::Flag::AccDeclare))
+      Fortran::lower::attachDeclarePostAllocAction(converter, builder,
+                                                   alloc.getSymbol());
+  }
+
   void genSimpleAllocation(const Allocation &alloc,
                            const fir::MutableBoxValue &box) {
     if (!box.isDerived() && !errorManager.hasStatSpec() &&
@@ -730,16 +738,15 @@ void Fortran::lower::genAllocateStmt(
 //===----------------------------------------------------------------------===//
 
 // Generate deallocation of a pointer/allocatable.
-static void genDeallocate(fir::FirOpBuilder &builder, mlir::Location loc,
-                          const fir::MutableBoxValue &box,
-                          ErrorManager &errorManager,
-                          mlir::Value declaredTypeDesc = {}) {
+static mlir::Value genDeallocate(fir::FirOpBuilder &builder, mlir::Location loc,
+                                 const fir::MutableBoxValue &box,
+                                 ErrorManager &errorManager,
+                                 mlir::Value declaredTypeDesc = {}) {
   // Deallocate intrinsic types inline.
   if (!box.isDerived() && !box.isPolymorphic() &&
       !box.isUnlimitedPolymorphic() && !errorManager.hasStatSpec() &&
       !useAllocateRuntime) {
-    fir::factory::genInlinedDeallocate(builder, loc, box);
-    return;
+    return fir::factory::genInlinedDeallocate(builder, loc, box);
   }
   // Use runtime calls to deallocate descriptor cases. Sync MutableBoxValue
   // with its descriptor before and after calls if needed.
@@ -748,6 +755,7 @@ static void genDeallocate(fir::FirOpBuilder &builder, mlir::Location loc,
       genRuntimeDeallocate(builder, loc, box, errorManager, declaredTypeDesc);
   fir::factory::syncMutableBoxFromIRBox(builder, loc, box);
   errorManager.assignStat(builder, loc, stat);
+  return stat;
 }
 
 void Fortran::lower::genDeallocateBox(
@@ -762,6 +770,22 @@ void Fortran::lower::genDeallocateBox(
   genDeallocate(builder, loc, box, errorManager, declaredTypeDesc);
 }
 
+static void preDeallocationAction(Fortran::lower::AbstractConverter &converter,
+                                  fir::FirOpBuilder &builder,
+                                  mlir::Value beginOpValue,
+                                  const Fortran::semantics::Symbol &sym) {
+  if (sym.test(Fortran::semantics::Symbol::Flag::AccDeclare))
+    Fortran::lower::attachDeclarePreDeallocAction(converter, builder,
+                                                  beginOpValue, sym);
+}
+
+static void postDeallocationAction(Fortran::lower::AbstractConverter &converter,
+                                   fir::FirOpBuilder &builder,
+                                   const Fortran::semantics::Symbol &sym) {
+  if (sym.test(Fortran::semantics::Symbol::Flag::AccDeclare))
+    Fortran::lower::attachDeclarePostDeallocAction(converter, builder, sym);
+}
+
 void Fortran::lower::genDeallocateStmt(
     Fortran::lower::AbstractConverter &converter,
     const Fortran::parser::DeallocateStmt &stmt, mlir::Location loc) {
@@ -784,12 +808,11 @@ void Fortran::lower::genDeallocateStmt(
   mlir::OpBuilder::InsertPoint insertPt = builder.saveInsertionPoint();
   for (const Fortran::parser::AllocateObject &allocateObject :
        std::get<std::list<Fortran::parser::AllocateObject>>(stmt.t)) {
+    const Fortran::semantics::Symbol &symbol = unwrapSymbol(allocateObject);
     fir::MutableBoxValue box =
         genMutableBoxValue(converter, loc, allocateObject);
-
     mlir::Value declaredTypeDesc = {};
     if (box.isPolymorphic()) {
-      const Fortran::semantics::Symbol &symbol = unwrapSymbol(allocateObject);
       assert(symbol.GetType());
       if (const Fortran::semantics::DerivedTypeSpec *derivedTypeSpec =
               symbol.GetType()->AsDerived()) {
@@ -797,7 +820,10 @@ void Fortran::lower::genDeallocateStmt(
             Fortran::lower::getTypeDescAddr(converter, loc, *derivedTypeSpec);
       }
     }
-    genDeallocate(builder, loc, box, errorManager, declaredTypeDesc);
+    mlir::Value beginOpValue =
+        genDeallocate(builder, loc, box, errorManager, declaredTypeDesc);
+    preDeallocationAction(converter, builder, beginOpValue, symbol);
+    postDeallocationAction(converter, builder, symbol);
   }
   builder.restoreInsertionPoint(insertPt);
 }

diff  --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 33dc37e8b43f50..68e3f2701b9172 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -2780,3 +2780,44 @@ void Fortran::lower::genOpenACCDeclarativeConstruct(
       },
       accDeclConstruct.u);
 }
+
+void Fortran::lower::attachDeclarePostAllocAction(
+    AbstractConverter &converter, fir::FirOpBuilder &builder,
+    const Fortran::semantics::Symbol &sym) {
+  std::stringstream fctName;
+  fctName << converter.mangleName(sym) << declarePostAllocSuffix.str();
+  mlir::Operation &op = builder.getInsertionBlock()->back();
+  op.setAttr(mlir::acc::getDeclareActionAttrName(),
+             mlir::acc::DeclareActionAttr::get(
+                 builder.getContext(),
+                 /*preAlloc=*/{},
+                 /*postAlloc=*/builder.getSymbolRefAttr(fctName.str()),
+                 /*preDealloc=*/{}, /*postDealloc=*/{}));
+}
+
+void Fortran::lower::attachDeclarePreDeallocAction(
+    AbstractConverter &converter, fir::FirOpBuilder &builder,
+    mlir::Value beginOpValue, const Fortran::semantics::Symbol &sym) {
+  std::stringstream fctName;
+  fctName << converter.mangleName(sym) << declarePreDeallocSuffix.str();
+  beginOpValue.getDefiningOp()->setAttr(
+      mlir::acc::getDeclareActionAttrName(),
+      mlir::acc::DeclareActionAttr::get(
+          builder.getContext(),
+          /*preAlloc=*/{}, /*postAlloc=*/{},
+          /*preDealloc=*/builder.getSymbolRefAttr(fctName.str()),
+          /*postDealloc=*/{}));
+}
+
+void Fortran::lower::attachDeclarePostDeallocAction(
+    AbstractConverter &converter, fir::FirOpBuilder &builder,
+    const Fortran::semantics::Symbol &sym) {
+  std::stringstream fctName;
+  fctName << converter.mangleName(sym) << declarePostAllocSuffix.str();
+  mlir::Operation &op = builder.getInsertionBlock()->back();
+  op.setAttr(mlir::acc::getDeclareActionAttrName(),
+             mlir::acc::DeclareActionAttr::get(
+                 builder.getContext(),
+                 /*preAlloc=*/{}, /*postAlloc=*/{}, /*preDealloc=*/{},
+                 /*postDealloc=*/builder.getSymbolRefAttr(fctName.str())));
+}

diff  --git a/flang/lib/Optimizer/Builder/MutableBox.cpp b/flang/lib/Optimizer/Builder/MutableBox.cpp
index a673c441b25bea..e7eac8bf5270a8 100644
--- a/flang/lib/Optimizer/Builder/MutableBox.cpp
+++ b/flang/lib/Optimizer/Builder/MutableBox.cpp
@@ -753,12 +753,14 @@ void fir::factory::genInlinedAllocation(
                 fir::MustBeHeapAttr::get(builder.getContext(), mustBeHeap));
 }
 
-void fir::factory::genInlinedDeallocate(fir::FirOpBuilder &builder,
-                                        mlir::Location loc,
-                                        const fir::MutableBoxValue &box) {
+mlir::Value
+fir::factory::genInlinedDeallocate(fir::FirOpBuilder &builder,
+                                   mlir::Location loc,
+                                   const fir::MutableBoxValue &box) {
   auto addr = MutablePropertyReader(builder, loc, box).readBaseAddress();
   genFinalizeAndFree(builder, loc, addr);
   MutablePropertyWriter{builder, loc, box}.setUnallocatedStatus();
+  return addr;
 }
 
 fir::factory::MutableBoxReallocation fir::factory::genReallocIfNeeded(

diff  --git a/flang/test/Lower/OpenACC/acc-declare.f90 b/flang/test/Lower/OpenACC/acc-declare.f90
index d3b9efe438b1a2..6761e640100c59 100644
--- a/flang/test/Lower/OpenACC/acc-declare.f90
+++ b/flang/test/Lower/OpenACC/acc-declare.f90
@@ -265,6 +265,24 @@ subroutine acc_declare_deviceptr2()
 ! CHECK: %[[DEVICEPTR:.*]] = acc.deviceptr varPtr(%[[ALLOCA]] : !fir.ref<!fir.array<100xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xf32>> {name = "dataparam"}
 ! CHECK: acc.declare_enter dataOperands(%[[DEVICEPTR]] : !fir.ref<!fir.array<100xf32>>)
 
+  subroutine acc_declare_allocate()
+    integer, allocatable :: a(:)
+    !$acc declare create(a)
+
+    allocate(a(100))
+
+! CHECK: %{{.*}} = fir.allocmem !fir.array<?xi32>, %{{.*}} {fir.must_be_heap = true, uniq_name = "_QMacc_declareFacc_declare_allocateEa.alloc"}
+! CHECK: fir.store %{{.*}} to %{{.*}} {acc.declare_action = #acc.declare_action<postAlloc = @_QMacc_declareFacc_declare_allocateEa_acc_declare_update_desc_post_alloc>} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+
+    deallocate(a)
+
+! CHECK: %{{.*}} = fir.box_addr %{{.*}} {acc.declare_action = #acc.declare_action<preDealloc = @_QMacc_declareFacc_declare_allocateEa_acc_declare_update_desc_pre_dealloc>} : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
+
+! CHECK: fir.freemem %{{.*}} : !fir.heap<!fir.array<?xi32>>
+! CHECK: fir.store %{{.*}} to %{{.*}} {acc.declare_action = #acc.declare_action<postDealloc = @_QMacc_declareFacc_declare_allocateEa_acc_declare_update_desc_post_alloc>} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+
+  end subroutine
+
 end module
 
 module acc_declare_allocatable_test
@@ -314,3 +332,21 @@ module acc_declare_allocatable_test
 ! CHECK:         acc.delete accPtr(%[[DEVICEPTR]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) {dataClause = #acc<data_clause acc_create>, name = "data1", structured = false}
 ! CHECK:         acc.terminator
 ! CHECK:       }
+
+! Test that the pre/post alloc/dealloc attributes are set when the
+! allocate/deallocate statement are in a 
diff erent module.
+module acc_declare_allocatable_test2
+contains
+  subroutine init()
+    use acc_declare_allocatable_test
+    allocate(data1(100))
+! CHECK: fir.store %{{.*}} to %{{.*}} {acc.declare_action = #acc.declare_action<postAlloc = @_QMacc_declare_allocatable_testEdata1_acc_declare_update_desc_post_alloc>} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+  end subroutine
+
+  subroutine finalize()
+    use acc_declare_allocatable_test
+    deallocate(data1)
+! CHECK: %{{.*}} = fir.box_addr %{{.*}} {acc.declare_action = #acc.declare_action<preDealloc = @_QMacc_declare_allocatable_testEdata1_acc_declare_update_desc_pre_dealloc>} : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
+! CHECK: fir.store %{{.*}} to %{{.*}} {acc.declare_action = #acc.declare_action<postDealloc = @_QMacc_declare_allocatable_testEdata1_acc_declare_update_desc_post_alloc>} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+  end subroutine
+end module


        


More information about the flang-commits mailing list