[flang-commits] [flang] e1d1da7 - Revert "[mlir][openacc][NFC] Use assembly format for acc.loop"

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Mon Apr 17 08:06:07 PDT 2023


Author: Valentin Clement
Date: 2023-04-17T08:05:51-07:00
New Revision: e1d1da71cba37b9c3e4b274380a1dc1fb79f9105

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

LOG: Revert "[mlir][openacc][NFC] Use assembly format for acc.loop"

This reverts commit 7960993e4638c6243c4b37f05bb61b080fe13d43.

Added: 
    

Modified: 
    flang/lib/Lower/OpenACC.cpp
    flang/test/Lower/OpenACC/acc-loop.f90
    flang/test/Lower/OpenACC/acc-parallel-loop.f90
    flang/test/Lower/OpenACC/acc-serial-loop.f90
    mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
    mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
    mlir/test/Dialect/OpenACC/invalid.mlir
    mlir/test/Dialect/OpenACC/ops.mlir

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 3a48177942e08..48ce1bae1e77f 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -263,7 +263,7 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
   mlir::Value gangStatic;
   llvm::SmallVector<mlir::Value, 2> tileOperands, privateOperands,
       reductionOperands;
-  bool hasGang = false, hasVector = false, hasWorker = false;
+  std::int64_t executionMapping = mlir::acc::OpenACCExecMapping::NONE;
 
   for (const Fortran::parser::AccClause &clause : accClauseList.v) {
     mlir::Location clauseLocation = converter.genLocation(clause.source);
@@ -292,21 +292,21 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
           }
         }
       }
-      hasGang = true;
+      executionMapping |= mlir::acc::OpenACCExecMapping::GANG;
     } else if (const auto *workerClause =
                    std::get_if<Fortran::parser::AccClause::Worker>(&clause.u)) {
       if (workerClause->v) {
         workerNum = fir::getBase(converter.genExprValue(
             *Fortran::semantics::GetExpr(*workerClause->v), stmtCtx));
       }
-      hasWorker = true;
+      executionMapping |= mlir::acc::OpenACCExecMapping::WORKER;
     } else if (const auto *vectorClause =
                    std::get_if<Fortran::parser::AccClause::Vector>(&clause.u)) {
       if (vectorClause->v) {
         vectorNum = fir::getBase(converter.genExprValue(
             *Fortran::semantics::GetExpr(*vectorClause->v), stmtCtx));
       }
-      hasVector = true;
+      executionMapping |= mlir::acc::OpenACCExecMapping::VECTOR;
     } else if (const auto *tileClause =
                    std::get_if<Fortran::parser::AccClause::Tile>(&clause.u)) {
       const Fortran::parser::AccTileExprList &accTileExprList = tileClause->v;
@@ -350,12 +350,7 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
   auto loopOp = createRegionOp<mlir::acc::LoopOp, mlir::acc::YieldOp>(
       firOpBuilder, currentLocation, operands, operandSegments);
 
-  if (hasGang)
-    loopOp.setHasGangAttr(firOpBuilder.getUnitAttr());
-  if (hasWorker)
-    loopOp.setHasWorkerAttr(firOpBuilder.getUnitAttr());
-  if (hasVector)
-    loopOp.setHasVectorAttr(firOpBuilder.getUnitAttr());
+  loopOp.setExecMappingAttr(firOpBuilder.getI64IntegerAttr(executionMapping));
 
   // Lower clauses mapped to attributes
   for (const Fortran::parser::AccClause &clause : accClauseList.v) {

diff  --git a/flang/test/Lower/OpenACC/acc-loop.f90 b/flang/test/Lower/OpenACC/acc-loop.f90
index 00b295a0899dd..ac9be539cd6d3 100644
--- a/flang/test/Lower/OpenACC/acc-loop.f90
+++ b/flang/test/Lower/OpenACC/acc-loop.f90
@@ -70,7 +70,7 @@ program acc_loop
   END DO
 
 !CHECK:      [[GANGNUM1:%.*]] = arith.constant 8 : i32
-!CHECK-NEXT: acc.loop gang(num=[[GANGNUM1]] : i32) {
+!CHECK-NEXT: acc.loop gang(num=[[GANGNUM1]]: i32) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}
@@ -81,7 +81,7 @@ program acc_loop
   END DO
 
 !CHECK:      [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
-!CHECK-NEXT: acc.loop gang(num=[[GANGNUM2]] : i32) {
+!CHECK-NEXT: acc.loop gang(num=[[GANGNUM2]]: i32) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}
@@ -91,7 +91,7 @@ program acc_loop
     a(i) = b(i)
   END DO
 
-!CHECK: acc.loop gang(num=%{{.*}} : i32, static=%{{.*}} : i32) {
+!CHECK: acc.loop gang(num=%{{.*}}: i32, static=%{{.*}}: i32) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}
@@ -112,7 +112,7 @@ program acc_loop
   END DO
 
 !CHECK: [[CONSTANT128:%.*]] = arith.constant 128 : i32
-!CHECK:      acc.loop vector([[CONSTANT128]] : i32) {
+!CHECK:      acc.loop vector([[CONSTANT128]]: i32) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}
@@ -123,7 +123,7 @@ program acc_loop
   END DO
 
 !CHECK:      [[VECTORLENGTH:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
-!CHECK:      acc.loop vector([[VECTORLENGTH]] : i32) {
+!CHECK:      acc.loop vector([[VECTORLENGTH]]: i32) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}
@@ -144,7 +144,7 @@ program acc_loop
   END DO
 
 !CHECK: [[WORKER128:%.*]] = arith.constant 128 : i32
-!CHECK:      acc.loop worker([[WORKER128]] : i32) {
+!CHECK:      acc.loop worker([[WORKER128]]: i32) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}
@@ -154,7 +154,7 @@ program acc_loop
     a(i) = b(i)
   END DO
 
-!CHECK:      acc.loop private(%{{.*}} : !fir.ref<!fir.array<10x10xf32>>) {
+!CHECK:      acc.loop private(%{{.*}}: !fir.ref<!fir.array<10x10xf32>>) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}
@@ -164,7 +164,7 @@ program acc_loop
     a(i) = b(i)
   END DO
 
-!CHECK:      acc.loop private(%{{.*}}, %{{.*}} : !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>) {
+!CHECK:      acc.loop private(%{{.*}}: !fir.ref<!fir.array<10x10xf32>>, %{{.*}}: !fir.ref<!fir.array<10x10xf32>>) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}
@@ -174,7 +174,7 @@ program acc_loop
     a(i) = b(i)
   END DO
 
-!CHECK:      acc.loop private(%{{.*}}, %{{.*}} : !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>) {
+!CHECK:      acc.loop private(%{{.*}}: !fir.ref<!fir.array<10x10xf32>>, %{{.*}}: !fir.ref<!fir.array<10x10xf32>>) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}
@@ -184,7 +184,7 @@ program acc_loop
     a(i) = b(i)
   END DO
 !CHECK:      [[TILESIZE:%.*]] = arith.constant 2 : i32
-!CHECK:      acc.loop tile([[TILESIZE]] : i32) {
+!CHECK:      acc.loop tile([[TILESIZE]]: i32) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}
@@ -194,7 +194,7 @@ program acc_loop
     a(i) = b(i)
   END DO
 !CHECK:      [[TILESIZEM1:%.*]] = arith.constant -1 : i32
-!CHECK:      acc.loop tile([[TILESIZEM1]] : i32) {
+!CHECK:      acc.loop tile([[TILESIZEM1]]: i32) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}
@@ -208,7 +208,7 @@ program acc_loop
 
 !CHECK:      [[TILESIZE1:%.*]] = arith.constant 2 : i32
 !CHECK:      [[TILESIZE2:%.*]] = arith.constant 2 : i32
-!CHECK:      acc.loop tile([[TILESIZE1]], [[TILESIZE2]] : i32, i32) {
+!CHECK:      acc.loop tile([[TILESIZE1]]: i32, [[TILESIZE2]]: i32) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}
@@ -218,7 +218,7 @@ program acc_loop
     a(i) = b(i)
   END DO
 
-!CHECK:      acc.loop tile(%{{.*}} : i32) {
+!CHECK:      acc.loop tile(%{{.*}}: i32) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}
@@ -230,7 +230,7 @@ program acc_loop
     END DO
   END DO
 
-!CHECK:      acc.loop tile(%{{.*}}, %{{.*}} : i32, i32) {
+!CHECK:      acc.loop tile(%{{.*}}: i32, %{{.*}}: i32) {
 !CHECK:        fir.do_loop
 !CHECK:        acc.yield
 !CHECK-NEXT: }{{$}}

diff  --git a/flang/test/Lower/OpenACC/acc-parallel-loop.f90 b/flang/test/Lower/OpenACC/acc-parallel-loop.f90
index ab662ab35a53e..f16448fb3d53f 100644
--- a/flang/test/Lower/OpenACC/acc-parallel-loop.f90
+++ b/flang/test/Lower/OpenACC/acc-parallel-loop.f90
@@ -418,7 +418,7 @@ subroutine acc_parallel_loop
   END DO
 
 !CHECK:      acc.parallel firstprivate([[B]] : !fir.ref<!fir.array<10xf32>>) private([[A]] : !fir.ref<!fir.array<10xf32>>) {
-!CHECK:        acc.loop private([[A]] : !fir.ref<!fir.array<10xf32>>) {
+!CHECK:        acc.loop private([[A]]: !fir.ref<!fir.array<10xf32>>) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -484,7 +484,7 @@ subroutine acc_parallel_loop
 
 !CHECK:      acc.parallel {
 !CHECK:        [[GANGNUM1:%.*]] = arith.constant 8 : i32
-!CHECK-NEXT:   acc.loop gang(num=[[GANGNUM1]] : i32) {
+!CHECK-NEXT:   acc.loop gang(num=[[GANGNUM1]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -498,7 +498,7 @@ subroutine acc_parallel_loop
 
 !CHECK:      acc.parallel {
 !CHECK:        [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
-!CHECK-NEXT:   acc.loop gang(num=[[GANGNUM2]] : i32) {
+!CHECK-NEXT:   acc.loop gang(num=[[GANGNUM2]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -511,7 +511,7 @@ subroutine acc_parallel_loop
   END DO
 
 !CHECK:      acc.parallel {
-!CHECK:        acc.loop gang(num=%{{.*}} : i32, static=%{{.*}} : i32) {
+!CHECK:        acc.loop gang(num=%{{.*}}: i32, static=%{{.*}}: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -537,7 +537,7 @@ subroutine acc_parallel_loop
 
 !CHECK:      acc.parallel {
 !CHECK:        [[CONSTANT128:%.*]] = arith.constant 128 : i32
-!CHECK:        acc.loop vector([[CONSTANT128]] : i32) {
+!CHECK:        acc.loop vector([[CONSTANT128]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -551,7 +551,7 @@ subroutine acc_parallel_loop
 
 !CHECK:      acc.parallel {
 !CHECK:        [[VECTORLENGTH:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
-!CHECK:        acc.loop vector([[VECTORLENGTH]] : i32) {
+!CHECK:        acc.loop vector([[VECTORLENGTH]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -578,7 +578,7 @@ subroutine acc_parallel_loop
 
 !CHECK:      acc.parallel {
 !CHECK:        [[WORKER128:%.*]] = arith.constant 128 : i32
-!CHECK:        acc.loop worker([[WORKER128]] : i32) {
+!CHECK:        acc.loop worker([[WORKER128]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -628,7 +628,7 @@ subroutine acc_parallel_loop
 
 !CHECK:      acc.parallel {
 !CHECK:        [[TILESIZE:%.*]] = arith.constant 2 : i32
-!CHECK:        acc.loop tile([[TILESIZE]] : i32) {
+!CHECK:        acc.loop tile([[TILESIZE]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -642,7 +642,7 @@ subroutine acc_parallel_loop
 
 !CHECK:      acc.parallel {
 !CHECK:        [[TILESIZEM1:%.*]] = arith.constant -1 : i32
-!CHECK:        acc.loop tile([[TILESIZEM1]] : i32) {
+!CHECK:        acc.loop tile([[TILESIZEM1]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -659,7 +659,7 @@ subroutine acc_parallel_loop
 !CHECK:      acc.parallel {
 !CHECK:        [[TILESIZE1:%.*]] = arith.constant 2 : i32
 !CHECK:        [[TILESIZE2:%.*]] = arith.constant 2 : i32
-!CHECK:        acc.loop tile([[TILESIZE1]], [[TILESIZE2]] : i32, i32) {
+!CHECK:        acc.loop tile([[TILESIZE1]]: i32, [[TILESIZE2]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -672,7 +672,7 @@ subroutine acc_parallel_loop
   END DO
 
 !CHECK:      acc.parallel {
-!CHECK:        acc.loop tile(%{{.*}} : i32) {
+!CHECK:        acc.loop tile(%{{.*}}: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -687,7 +687,7 @@ subroutine acc_parallel_loop
   END DO
 
 !CHECK:      acc.parallel {
-!CHECK:        acc.loop tile(%{{.*}}, %{{.*}} : i32, i32) {
+!CHECK:        acc.loop tile(%{{.*}}: i32, %{{.*}}: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}

diff  --git a/flang/test/Lower/OpenACC/acc-serial-loop.f90 b/flang/test/Lower/OpenACC/acc-serial-loop.f90
index c2ee38a7c4f00..e952554c7f48d 100644
--- a/flang/test/Lower/OpenACC/acc-serial-loop.f90
+++ b/flang/test/Lower/OpenACC/acc-serial-loop.f90
@@ -334,7 +334,7 @@ subroutine acc_serial_loop
   END DO
 
 !CHECK:      acc.serial firstprivate([[B]] : !fir.ref<!fir.array<10xf32>>) private([[A]] : !fir.ref<!fir.array<10xf32>>) {
-!CHECK:        acc.loop private([[A]] : !fir.ref<!fir.array<10xf32>>) {
+!CHECK:        acc.loop private([[A]]: !fir.ref<!fir.array<10xf32>>) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -400,7 +400,7 @@ subroutine acc_serial_loop
 
 !CHECK:      acc.serial {
 !CHECK:        [[GANGNUM1:%.*]] = arith.constant 8 : i32
-!CHECK-NEXT:   acc.loop gang(num=[[GANGNUM1]] : i32) {
+!CHECK-NEXT:   acc.loop gang(num=[[GANGNUM1]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -414,7 +414,7 @@ subroutine acc_serial_loop
 
 !CHECK:      acc.serial {
 !CHECK:        [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
-!CHECK-NEXT:   acc.loop gang(num=[[GANGNUM2]] : i32) {
+!CHECK-NEXT:   acc.loop gang(num=[[GANGNUM2]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -427,7 +427,7 @@ subroutine acc_serial_loop
   END DO
 
 !CHECK:      acc.serial {
-!CHECK:        acc.loop gang(num=%{{.*}} : i32, static=%{{.*}} : i32) {
+!CHECK:        acc.loop gang(num=%{{.*}}: i32, static=%{{.*}}: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -453,7 +453,7 @@ subroutine acc_serial_loop
 
 !CHECK:      acc.serial {
 !CHECK:        [[CONSTANT128:%.*]] = arith.constant 128 : i32
-!CHECK:        acc.loop vector([[CONSTANT128]] : i32) {
+!CHECK:        acc.loop vector([[CONSTANT128]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -467,7 +467,7 @@ subroutine acc_serial_loop
 
 !CHECK:      acc.serial {
 !CHECK:        [[VECTORLENGTH:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
-!CHECK:        acc.loop vector([[VECTORLENGTH]] : i32) {
+!CHECK:        acc.loop vector([[VECTORLENGTH]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -494,7 +494,7 @@ subroutine acc_serial_loop
 
 !CHECK:      acc.serial {
 !CHECK:        [[WORKER128:%.*]] = arith.constant 128 : i32
-!CHECK:        acc.loop worker([[WORKER128]] : i32) {
+!CHECK:        acc.loop worker([[WORKER128]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -544,7 +544,7 @@ subroutine acc_serial_loop
 
 !CHECK:      acc.serial {
 !CHECK:        [[TILESIZE:%.*]] = arith.constant 2 : i32
-!CHECK:        acc.loop tile([[TILESIZE]] : i32) {
+!CHECK:        acc.loop tile([[TILESIZE]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -558,7 +558,7 @@ subroutine acc_serial_loop
 
 !CHECK:      acc.serial {
 !CHECK:        [[TILESIZEM1:%.*]] = arith.constant -1 : i32
-!CHECK:        acc.loop tile([[TILESIZEM1]] : i32) {
+!CHECK:        acc.loop tile([[TILESIZEM1]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -575,7 +575,7 @@ subroutine acc_serial_loop
 !CHECK:      acc.serial {
 !CHECK:        [[TILESIZE1:%.*]] = arith.constant 2 : i32
 !CHECK:        [[TILESIZE2:%.*]] = arith.constant 2 : i32
-!CHECK:        acc.loop tile([[TILESIZE1]], [[TILESIZE2]] : i32, i32) {
+!CHECK:        acc.loop tile([[TILESIZE1]]: i32, [[TILESIZE2]]: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -588,7 +588,7 @@ subroutine acc_serial_loop
   END DO
 
 !CHECK:      acc.serial {
-!CHECK:        acc.loop tile(%{{.*}} : i32) {
+!CHECK:        acc.loop tile(%{{.*}}: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}
@@ -603,7 +603,7 @@ subroutine acc_serial_loop
   END DO
 
 !CHECK:      acc.serial {
-!CHECK:        acc.loop tile(%{{.*}}, %{{.*}} : i32, i32) {
+!CHECK:        acc.loop tile(%{{.*}}: i32, %{{.*}}: i32) {
 !CHECK:          fir.do_loop
 !CHECK:          acc.yield
 !CHECK-NEXT:   }{{$}}

diff  --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
index 1e8e1dee48f92..b2b3caf10bf7d 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
@@ -547,39 +547,32 @@ def OpenACC_LoopOp : OpenACC_Op<"loop", [AttrSizedOperandSegments]> {
                        UnitAttr:$seq,
                        UnitAttr:$independent,
                        UnitAttr:$auto_,
-                       UnitAttr:$hasGang,
-                       UnitAttr:$hasWorker,
-                       UnitAttr:$hasVector,
                        Variadic<IntOrIndex>:$tileOperands,
                        Variadic<AnyType>:$privateOperands,
                        OptionalAttr<OpenACC_ReductionOpAttr>:$reductionOp,
-                       Variadic<AnyType>:$reductionOperands);
+                       Variadic<AnyType>:$reductionOperands,
+                       DefaultValuedAttr<I64Attr, "0">:$exec_mapping);
 
   let results = (outs Variadic<AnyType>:$results);
 
   let regions = (region AnyRegion:$region);
 
   let extraClassDeclaration = [{
+    static StringRef getCollapseAttrStrName() { return "collapse"; }
+    static StringRef getSeqAttrStrName() { return "seq"; }
+    static StringRef getIndependentAttrStrName() { return "independent"; }
     static StringRef getAutoAttrStrName() { return "auto"; }
+    static StringRef getExecutionMappingAttrStrName() { return "exec_mapping"; }
+    static StringRef getGangKeyword() { return "gang"; }
     static StringRef getGangNumKeyword() { return "num"; }
     static StringRef getGangStaticKeyword() { return "static"; }
+    static StringRef getVectorKeyword() { return "vector"; }
+    static StringRef getWorkerKeyword() { return "worker"; }
+    static StringRef getTileKeyword() { return "tile"; }
+    static StringRef getPrivateKeyword() { return "private"; }
+    static StringRef getReductionKeyword() { return "reduction"; }
   }];
-
   let hasCustomAssemblyFormat = 1;
-  let assemblyFormat = [{
-    oilist(
-        `gang` `` custom<GangClause>($gangNum, type($gangNum), $gangStatic, type($gangStatic), $hasGang)
-      | `worker` `` custom<WorkerClause>($workerNum, type($workerNum), $hasWorker)
-      | `vector` `` custom<VectorClause>($vectorLength, type($vectorLength), $hasVector)
-      | `private` `(` $privateOperands `:` type($privateOperands) `)`
-      | `tile` `(` $tileOperands `:` type($tileOperands) `)`
-      | `reduction` `(` $reductionOperands `:` type($reductionOperands) `)`
-    )
-    $region
-    ( `(` type($results)^ `)` )?
-    attr-dict-with-keyword
-  }];
-
   let hasVerifier = 1;
 }
 

diff  --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index 4b3b43881975a..82b358d659a24 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -52,6 +52,85 @@ static ParseResult parseRegions(OpAsmParser &parser, OperationState &state,
   return success();
 }
 
+static ParseResult
+parseOperandList(OpAsmParser &parser, StringRef keyword,
+                 SmallVectorImpl<OpAsmParser::UnresolvedOperand> &args,
+                 SmallVectorImpl<Type> &argTypes, OperationState &result) {
+  if (failed(parser.parseOptionalKeyword(keyword)))
+    return success();
+
+  if (failed(parser.parseLParen()))
+    return failure();
+
+  // Exit early if the list is empty.
+  if (succeeded(parser.parseOptionalRParen()))
+    return success();
+
+  if (failed(parser.parseCommaSeparatedList([&]() {
+        OpAsmParser::UnresolvedOperand arg;
+        Type type;
+
+        if (parser.parseOperand(arg, /*allowResultNumber=*/false) ||
+            parser.parseColonType(type))
+          return failure();
+
+        args.push_back(arg);
+        argTypes.push_back(type);
+        return success();
+      })) ||
+      failed(parser.parseRParen()))
+    return failure();
+
+  return parser.resolveOperands(args, argTypes, parser.getCurrentLocation(),
+                                result.operands);
+}
+
+static void printOperandList(Operation::operand_range operands,
+                             StringRef listName, OpAsmPrinter &printer) {
+
+  if (!operands.empty()) {
+    printer << " " << listName << "(";
+    llvm::interleaveComma(operands, printer, [&](Value op) {
+      printer << op << ": " << op.getType();
+    });
+    printer << ")";
+  }
+}
+
+static ParseResult parseOperandAndType(OpAsmParser &parser,
+                                       OperationState &result) {
+  OpAsmParser::UnresolvedOperand operand;
+  Type type;
+  if (parser.parseOperand(operand) || parser.parseColonType(type) ||
+      parser.resolveOperand(operand, type, result.operands))
+    return failure();
+  return success();
+}
+
+/// Parse optional operand and its type wrapped in parenthesis.
+/// Example:
+///   `(` %vectorLength: i64 `)`
+static OptionalParseResult parseOptionalOperandAndType(OpAsmParser &parser,
+                                                       OperationState &result) {
+  if (succeeded(parser.parseOptionalLParen())) {
+    return failure(parseOperandAndType(parser, result) || parser.parseRParen());
+  }
+  return std::nullopt;
+}
+
+/// Parse optional operand with its type prefixed with prefixKeyword `=`.
+/// Example:
+///   num=%gangNum: i32
+static OptionalParseResult parserOptionalOperandAndTypeWithPrefix(
+    OpAsmParser &parser, OperationState &result, StringRef prefixKeyword) {
+  if (succeeded(parser.parseOptionalKeyword(prefixKeyword))) {
+    if (parser.parseEqual() || parseOperandAndType(parser, result))
+      return failure();
+    return success();
+  }
+  return std::nullopt;
+}
+
 static bool isComputeOperation(Operation *op) {
   return isa<acc::ParallelOp>(op) || isa<acc::LoopOp>(op);
 }
@@ -153,114 +232,180 @@ Value KernelsOp::getDataOperand(unsigned i) {
 // LoopOp
 //===----------------------------------------------------------------------===//
 
-static ParseResult
-parseGangClause(OpAsmParser &parser,
-                std::optional<OpAsmParser::UnresolvedOperand> &gangNum,
-                Type &gangNumType,
-                std::optional<OpAsmParser::UnresolvedOperand> &gangStatic,
-                Type &gangStaticType, UnitAttr &hasGang) {
-  hasGang = UnitAttr::get(parser.getBuilder().getContext());
-  // optional gang operands
+/// Parse acc.loop operation
+/// operation := `acc.loop`
+///              (`gang` ( `(` (`num=` value)? (`,` `static=` value `)`)? )? )?
+///              (`vector` ( `(` value `)` )? )? (`worker` (`(` value `)`)? )?
+///              (`vector_length` `(` value `)`)?
+///              (`tile` `(` value-list `)`)?
+///              (`private` `(` value-list `)`)?
+///              (`reduction` `(` value-list `)`)?
+///              region attr-dict?
+ParseResult LoopOp::parse(OpAsmParser &parser, OperationState &result) {
+  Builder &builder = parser.getBuilder();
+  unsigned executionMapping = OpenACCExecMapping::NONE;
+  SmallVector<Type, 8> operandTypes;
+  SmallVector<OpAsmParser::UnresolvedOperand, 8> privateOperands,
+      reductionOperands;
+  SmallVector<OpAsmParser::UnresolvedOperand, 8> tileOperands;
+  OptionalParseResult gangNum, gangStatic, worker, vector;
+
+  // gang?
+  if (succeeded(parser.parseOptionalKeyword(LoopOp::getGangKeyword())))
+    executionMapping |= OpenACCExecMapping::GANG;
+
+  // optional gang operand
   if (succeeded(parser.parseOptionalLParen())) {
-    if (succeeded(parser.parseOptionalKeyword(LoopOp::getGangNumKeyword()))) {
-      if (parser.parseEqual())
-        return failure();
-      gangNum = OpAsmParser::UnresolvedOperand{};
-      if (parser.parseOperand(*gangNum) || parser.parseColonType(gangNumType))
-        return failure();
-    } else {
-      gangNum = std::nullopt;
-    }
+    gangNum = parserOptionalOperandAndTypeWithPrefix(
+        parser, result, LoopOp::getGangNumKeyword());
+    if (gangNum.has_value() && failed(*gangNum))
+      return failure();
     // FIXME: Comma should require subsequent operands.
     (void)parser.parseOptionalComma();
-    if (succeeded(
-            parser.parseOptionalKeyword(LoopOp::getGangStaticKeyword()))) {
-      gangStatic = OpAsmParser::UnresolvedOperand{};
-      if (parser.parseEqual())
-        return failure();
-      gangStatic = OpAsmParser::UnresolvedOperand{};
-      if (parser.parseOperand(*gangStatic) ||
-          parser.parseColonType(gangStaticType))
-        return failure();
-    }
+    gangStatic = parserOptionalOperandAndTypeWithPrefix(
+        parser, result, LoopOp::getGangStaticKeyword());
+    if (gangStatic.has_value() && failed(*gangStatic))
+      return failure();
     // FIXME: Why allow optional last commas?
     (void)parser.parseOptionalComma();
     if (failed(parser.parseRParen()))
       return failure();
   }
+
+  // worker?
+  if (succeeded(parser.parseOptionalKeyword(LoopOp::getWorkerKeyword())))
+    executionMapping |= OpenACCExecMapping::WORKER;
+
+  // optional worker operand
+  worker = parseOptionalOperandAndType(parser, result);
+  if (worker.has_value() && failed(*worker))
+    return failure();
+
+  // vector?
+  if (succeeded(parser.parseOptionalKeyword(LoopOp::getVectorKeyword())))
+    executionMapping |= OpenACCExecMapping::VECTOR;
+
+  // optional vector operand
+  vector = parseOptionalOperandAndType(parser, result);
+  if (vector.has_value() && failed(*vector))
+    return failure();
+
+  // tile()?
+  if (failed(parseOperandList(parser, LoopOp::getTileKeyword(), tileOperands,
+                              operandTypes, result)))
+    return failure();
+
+  // private()?
+  if (failed(parseOperandList(parser, LoopOp::getPrivateKeyword(),
+                              privateOperands, operandTypes, result)))
+    return failure();
+
+  // reduction()?
+  if (failed(parseOperandList(parser, LoopOp::getReductionKeyword(),
+                              reductionOperands, operandTypes, result)))
+    return failure();
+
+  if (executionMapping != acc::OpenACCExecMapping::NONE)
+    result.addAttribute(LoopOp::getExecutionMappingAttrStrName(),
+                        builder.getI64IntegerAttr(executionMapping));
+
+  // Parse optional results in case there is a reduce.
+  if (parser.parseOptionalArrowTypeList(result.types))
+    return failure();
+
+  if (failed(parseRegions<LoopOp>(parser, result)))
+    return failure();
+
+  result.addAttribute(LoopOp::getOperandSegmentSizeAttr(),
+                      builder.getDenseI32ArrayAttr(
+                          {static_cast<int32_t>(gangNum.has_value() ? 1 : 0),
+                           static_cast<int32_t>(gangStatic.has_value() ? 1 : 0),
+                           static_cast<int32_t>(worker.has_value() ? 1 : 0),
+                           static_cast<int32_t>(vector.has_value() ? 1 : 0),
+                           static_cast<int32_t>(tileOperands.size()),
+                           static_cast<int32_t>(privateOperands.size()),
+                           static_cast<int32_t>(reductionOperands.size())}));
+
+  if (failed(parser.parseOptionalAttrDictWithKeyword(result.attributes)))
+    return failure();
+
   return success();
 }
 
-void printGangClause(OpAsmPrinter &p, Operation *op, Value gangNum,
-                     Type gangNumType, Value gangStatic, Type gangStaticType,
-                     UnitAttr hasGang) {
-  if (gangNum || gangStatic) {
-    p << "(";
-    if (gangNum) {
-      p << LoopOp::getGangNumKeyword() << "=" << gangNum << " : "
-        << gangNumType;
+void LoopOp::print(OpAsmPrinter &printer) {
+  unsigned execMapping = getExecMapping();
+  if (execMapping & OpenACCExecMapping::GANG) {
+    printer << " " << LoopOp::getGangKeyword();
+    Value gangNum = getGangNum();
+    Value gangStatic = getGangStatic();
+
+    // Print optional gang operands
+    if (gangNum || gangStatic) {
+      printer << "(";
+      if (gangNum) {
+        printer << LoopOp::getGangNumKeyword() << "=" << gangNum << ": "
+                << gangNum.getType();
+        if (gangStatic)
+          printer << ", ";
+      }
       if (gangStatic)
-        p << ", ";
+        printer << LoopOp::getGangStaticKeyword() << "=" << gangStatic << ": "
+                << gangStatic.getType();
+      printer << ")";
     }
-    if (gangStatic)
-      p << LoopOp::getGangStaticKeyword() << "=" << gangStatic << " : "
-        << gangStaticType;
-    p << ")";
   }
-}
 
-static ParseResult
-parseWorkerClause(OpAsmParser &parser,
-                  std::optional<OpAsmParser::UnresolvedOperand> &workerNum,
-                  Type &workerNumType, UnitAttr &hasWorker) {
-  hasWorker = UnitAttr::get(parser.getBuilder().getContext());
-  if (succeeded(parser.parseOptionalLParen())) {
-    workerNum = OpAsmParser::UnresolvedOperand{};
-    if (parser.parseOperand(*workerNum) ||
-        parser.parseColonType(workerNumType) || parser.parseRParen())
-      return failure();
+  if (execMapping & OpenACCExecMapping::WORKER) {
+    printer << " " << LoopOp::getWorkerKeyword();
+
+    // Print optional worker operand if present
+    if (Value workerNum = getWorkerNum())
+      printer << "(" << workerNum << ": " << workerNum.getType() << ")";
   }
-  return success();
-}
 
-void printWorkerClause(OpAsmPrinter &p, Operation *op, Value workerNum,
-                       Type workerNumType, UnitAttr hasWorker) {
-  if (workerNum)
-    p << "(" << workerNum << " : " << workerNumType << ")";
-}
+  if (execMapping & OpenACCExecMapping::VECTOR) {
+    printer << " " << LoopOp::getVectorKeyword();
 
-static ParseResult
-parseVectorClause(OpAsmParser &parser,
-                  std::optional<OpAsmParser::UnresolvedOperand> &vectorLength,
-                  Type &vectorLengthType, UnitAttr &hasVector) {
-  hasVector = UnitAttr::get(parser.getBuilder().getContext());
-  if (succeeded(parser.parseOptionalLParen())) {
-    vectorLength = OpAsmParser::UnresolvedOperand{};
-    if (parser.parseOperand(*vectorLength) ||
-        parser.parseColonType(vectorLengthType) || parser.parseRParen())
-      return failure();
+    // Print optional vector operand if present
+    if (Value vectorLength = this->getVectorLength())
+      printer << "(" << vectorLength << ": " << vectorLength.getType() << ")";
   }
-  return success();
-}
 
-void printVectorClause(OpAsmPrinter &p, Operation *op, Value vectorLength,
-                       Type vectorLengthType, UnitAttr hasVector) {
-  if (vectorLength)
-    p << "(" << vectorLength << " : " << vectorLengthType << ")";
+  // tile()?
+  printOperandList(getTileOperands(), LoopOp::getTileKeyword(), printer);
+
+  // private()?
+  printOperandList(getPrivateOperands(), LoopOp::getPrivateKeyword(), printer);
+
+  // reduction()?
+  printOperandList(getReductionOperands(), LoopOp::getReductionKeyword(),
+                   printer);
+
+  if (getNumResults() > 0)
+    printer << " -> (" << getResultTypes() << ")";
+
+  printer << ' ';
+  printer.printRegion(getRegion(),
+                      /*printEntryBlockArgs=*/false,
+                      /*printBlockTerminators=*/true);
+
+  printer.printOptionalAttrDictWithKeyword(
+      (*this)->getAttrs(), {LoopOp::getExecutionMappingAttrStrName(),
+                            LoopOp::getOperandSegmentSizeAttr()});
 }
 
 LogicalResult acc::LoopOp::verify() {
   // auto, independent and seq attribute are mutually exclusive.
   if ((getAuto_() && (getIndependent() || getSeq())) ||
       (getIndependent() && getSeq())) {
-    return emitError() << "only one of \"" << acc::LoopOp::getAutoAttrStrName()
-                       << "\", " << getIndependentAttrName() << ", "
-                       << getSeqAttrName()
-                       << " can be present at the same time";
+    return emitError("only one of " + acc::LoopOp::getAutoAttrStrName() + ", " +
+                     acc::LoopOp::getIndependentAttrStrName() + ", " +
+                     acc::LoopOp::getSeqAttrStrName() +
+                     " can be present at the same time");
   }
 
   // Gang, worker and vector are incompatible with seq.
-  if (getSeq() && (getHasGang() || getHasWorker() || getHasVector()))
+  if (getSeq() && getExecMapping() != OpenACCExecMapping::NONE)
     return emitError("gang, worker or vector cannot appear with the seq attr");
 
   // Check non-empty body().

diff  --git a/mlir/test/Dialect/OpenACC/invalid.mlir b/mlir/test/Dialect/OpenACC/invalid.mlir
index d7dc39c280a2d..e99508b18ecde 100644
--- a/mlir/test/Dialect/OpenACC/invalid.mlir
+++ b/mlir/test/Dialect/OpenACC/invalid.mlir
@@ -62,7 +62,7 @@ acc.loop {
 
 // -----
 
-// expected-error at +1 {{only one of "auto", "independent", "seq" can be present at the same time}}
+// expected-error at +1 {{only one of auto, independent, seq can be present at the same time}}
 acc.loop {
   acc.yield
 } attributes {auto_, seq}

diff  --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir
index b1ee051699a8b..c1eaa499496e0 100644
--- a/mlir/test/Dialect/OpenACC/ops.mlir
+++ b/mlir/test/Dialect/OpenACC/ops.mlir
@@ -250,11 +250,11 @@ func.func @testloopop() -> () {
     "test.openacc_dummy_op"() : () -> ()
     acc.yield
   }
-  acc.loop tile(%i64Value, %i64Value : i64, i64) {
+  acc.loop tile(%i64Value: i64, %i64Value: i64) {
     "test.openacc_dummy_op"() : () -> ()
     acc.yield
   }
-  acc.loop tile(%i32Value, %i32Value : i32, i32) {
+  acc.loop tile(%i32Value: i32, %i32Value: i32) {
     "test.openacc_dummy_op"() : () -> ()
     acc.yield
   }
@@ -268,55 +268,55 @@ func.func @testloopop() -> () {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }
-// CHECK:      acc.loop gang(num=[[I64VALUE]] : i64) {
+// CHECK:      acc.loop gang(num=[[I64VALUE]]: i64) {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }
-// CHECK:      acc.loop gang(static=[[I64VALUE]] : i64) {
+// CHECK:      acc.loop gang(static=[[I64VALUE]]: i64) {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }
-// CHECK:      acc.loop worker([[I64VALUE]] : i64) {
+// CHECK:      acc.loop worker([[I64VALUE]]: i64) {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }
-// CHECK:      acc.loop worker([[I32VALUE]] : i32) {
+// CHECK:      acc.loop worker([[I32VALUE]]: i32) {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }
-// CHECK:      acc.loop worker([[IDXVALUE]] : index) {
+// CHECK:      acc.loop worker([[IDXVALUE]]: index) {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }
-// CHECK:      acc.loop vector([[I64VALUE]] : i64) {
+// CHECK:      acc.loop vector([[I64VALUE]]: i64) {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }
-// CHECK:      acc.loop vector([[I32VALUE]] : i32) {
+// CHECK:      acc.loop vector([[I32VALUE]]: i32) {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }
-// CHECK:      acc.loop vector([[IDXVALUE]] : index) {
+// CHECK:      acc.loop vector([[IDXVALUE]]: index) {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }
-// CHECK:      acc.loop gang(num=[[I64VALUE]] : i64) worker vector {
+// CHECK:      acc.loop gang(num=[[I64VALUE]]: i64) worker vector {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }
-// CHECK:      acc.loop gang(num=[[I64VALUE]] : i64, static=[[I64VALUE]] : i64) worker([[I64VALUE]] : i64) vector([[I64VALUE]] : i64) {
+// CHECK:      acc.loop gang(num=[[I64VALUE]]: i64, static=[[I64VALUE]]: i64) worker([[I64VALUE]]: i64) vector([[I64VALUE]]: i64) {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }
-// CHECK:      acc.loop gang(num=[[I32VALUE]] : i32, static=[[IDXVALUE]] : index) {
+// CHECK:      acc.loop gang(num=[[I32VALUE]]: i32, static=[[IDXVALUE]]: index) {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }
-// CHECK:      acc.loop tile([[I64VALUE]], [[I64VALUE]] : i64, i64) {
+// CHECK:      acc.loop tile([[I64VALUE]]: i64, [[I64VALUE]]: i64) {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }
-// CHECK:      acc.loop tile([[I32VALUE]], [[I32VALUE]] : i32, i32) {
+// CHECK:      acc.loop tile([[I32VALUE]]: i32, [[I32VALUE]]: i32) {
 // CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
 // CHECK-NEXT:   acc.yield
 // CHECK-NEXT: }


        


More information about the flang-commits mailing list