[PATCH] D90472: [flang][openacc] Lower update directive

Valentin Clement via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 30 08:44:26 PDT 2020


clementval created this revision.
clementval added reviewers: sscalpone, schweitz, jeanPerier, SouraVX, kiranchandramohan.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
clementval requested review of this revision.

This patch upstream the lowering of Update directive that was initially done in
https://github.com/flang-compiler/f18-llvm-project/pull/528


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D90472

Files:
  flang/lib/Lower/OpenACC.cpp


Index: flang/lib/Lower/OpenACC.cpp
===================================================================
--- flang/lib/Lower/OpenACC.cpp
+++ flang/lib/Lower/OpenACC.cpp
@@ -626,6 +626,85 @@
     exitDataOp.finalizeAttr(firOpBuilder.getUnitAttr());
 }
 
+static void
+genACCUpdateOp(Fortran::lower::AbstractConverter &converter,
+               const Fortran::parser::AccClauseList &accClauseList) {
+  mlir::Value ifCond, async, waitDevnum;
+  SmallVector<Value, 2> hostOperands, deviceOperands, waitOperands;
+
+  // Async and wait clause have optional values but can be present with
+  // no value as well. When there is no value, the op has an attribute to
+  // represent the clause.
+  bool addAsyncAttr = false;
+  bool addWaitAttr = false;
+  bool addIfPresentAttr = false;
+
+  auto &firOpBuilder = converter.getFirOpBuilder();
+  auto currentLocation = converter.getCurrentLocation();
+
+  // Lower clauses values mapped to operands.
+  // Keep track of each group of operands separatly as clauses can appear
+  // more than once.
+  for (const auto &clause : accClauseList.v) {
+    if (const auto *asyncClause =
+            std::get_if<Fortran::parser::AccClause::Async>(&clause.u)) {
+      const auto &asyncClauseValue = asyncClause->v;
+      if (asyncClauseValue) { // async has a value.
+        async = fir::getBase(converter.genExprValue(
+            *Fortran::semantics::GetExpr(*asyncClauseValue)));
+      } else {
+        addAsyncAttr = true;
+      }
+    } else if (const auto *waitClause =
+                   std::get_if<Fortran::parser::AccClause::Wait>(&clause.u)) {
+      const auto &waitClauseValue = waitClause->v;
+      if (waitClauseValue) { // wait has a value.
+        const Fortran::parser::AccWaitArgument &waitArg = *waitClauseValue;
+        const std::list<Fortran::parser::ScalarIntExpr> &waitList =
+            std::get<std::list<Fortran::parser::ScalarIntExpr>>(waitArg.t);
+        for (const Fortran::parser::ScalarIntExpr &value : waitList) {
+          mlir::Value v = fir::getBase(
+              converter.genExprValue(*Fortran::semantics::GetExpr(value)));
+          waitOperands.push_back(v);
+        }
+
+        const std::optional<Fortran::parser::ScalarIntExpr> &waitDevnumValue =
+            std::get<std::optional<Fortran::parser::ScalarIntExpr>>(waitArg.t);
+        if (waitDevnumValue)
+          waitDevnum = fir::getBase(converter.genExprValue(
+              *Fortran::semantics::GetExpr(*waitDevnumValue)));
+      } else {
+        addWaitAttr = true;
+      }
+    } else if (const auto *hostClause =
+                   std::get_if<Fortran::parser::AccClause::Host>(&clause.u)) {
+      genObjectList(hostClause->v, converter, hostOperands);
+    } else if (const auto *deviceClause =
+                   std::get_if<Fortran::parser::AccClause::Device>(&clause.u)) {
+      genObjectList(deviceClause->v, converter, deviceOperands);
+    }
+  }
+
+  // Prepare the operand segement size attribute and the operands value range.
+  SmallVector<mlir::Value, 10> operands;
+  SmallVector<int32_t, 5> operandSegments;
+  addOperand(operands, operandSegments, async);
+  addOperand(operands, operandSegments, waitDevnum);
+  addOperands(operands, operandSegments, waitOperands);
+  addOperands(operands, operandSegments, hostOperands);
+  addOperands(operands, operandSegments, deviceOperands);
+
+  auto updateOp = createSimpleOp<mlir::acc::UpdateOp>(
+      firOpBuilder, currentLocation, operands, operandSegments);
+
+  if (addAsyncAttr)
+    updateOp.asyncAttr(firOpBuilder.getUnitAttr());
+  if (addWaitAttr)
+    updateOp.waitAttr(firOpBuilder.getUnitAttr());
+  if (addIfPresentAttr)
+    updateOp.ifPresentAttr(firOpBuilder.getUnitAttr());
+}
+
 static void
 genACC(Fortran::lower::AbstractConverter &converter,
        Fortran::lower::pft::Evaluation &eval,
@@ -646,7 +725,7 @@
   } else if (standaloneDirective.v == llvm::acc::Directive::ACCD_set) {
     TODO("OpenACC set directive not lowered yet!");
   } else if (standaloneDirective.v == llvm::acc::Directive::ACCD_update) {
-    TODO("OpenACC update directive not lowered yet!");
+    genACCUpdateOp(converter, accClauseList);
   }
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D90472.301917.patch
Type: text/x-patch
Size: 4172 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201030/9b6f0217/attachment.bin>


More information about the llvm-commits mailing list