diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -263,7 +263,7 @@ mlir::Value gangStatic; llvm::SmallVector tileOperands, privateOperands, reductionOperands; - std::int64_t executionMapping = mlir::acc::OpenACCExecMapping::NONE; + bool hasGang = false, hasVector = false, hasWorker = false; for (const Fortran::parser::AccClause &clause : accClauseList.v) { mlir::Location clauseLocation = converter.genLocation(clause.source); @@ -292,21 +292,21 @@ } } } - executionMapping |= mlir::acc::OpenACCExecMapping::GANG; + hasGang = true; } else if (const auto *workerClause = std::get_if(&clause.u)) { if (workerClause->v) { workerNum = fir::getBase(converter.genExprValue( *Fortran::semantics::GetExpr(*workerClause->v), stmtCtx)); } - executionMapping |= mlir::acc::OpenACCExecMapping::WORKER; + hasWorker = true; } else if (const auto *vectorClause = std::get_if(&clause.u)) { if (vectorClause->v) { vectorNum = fir::getBase(converter.genExprValue( *Fortran::semantics::GetExpr(*vectorClause->v), stmtCtx)); } - executionMapping |= mlir::acc::OpenACCExecMapping::VECTOR; + hasVector = true; } else if (const auto *tileClause = std::get_if(&clause.u)) { const Fortran::parser::AccTileExprList &accTileExprList = tileClause->v; @@ -350,7 +350,12 @@ auto loopOp = createRegionOp( firOpBuilder, currentLocation, operands, operandSegments); - loopOp.setExecMappingAttr(firOpBuilder.getI64IntegerAttr(executionMapping)); + if (hasGang) + loopOp.setHasGangAttr(firOpBuilder.getUnitAttr()); + if (hasWorker) + loopOp.setHasWorkerAttr(firOpBuilder.getUnitAttr()); + if (hasVector) + loopOp.setHasVectorAttr(firOpBuilder.getUnitAttr()); // Lower clauses mapped to attributes for (const Fortran::parser::AccClause &clause : accClauseList.v) { diff --git a/flang/test/Lower/OpenACC/acc-kernels-loop.f90 b/flang/test/Lower/OpenACC/acc-kernels-loop.f90 --- a/flang/test/Lower/OpenACC/acc-kernels-loop.f90 +++ b/flang/test/Lower/OpenACC/acc-kernels-loop.f90 @@ -471,7 +471,7 @@ !CHECK: acc.kernels { !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: }{{$}} @@ -485,7 +485,7 @@ !CHECK: acc.kernels { !CHECK: [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref -!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: }{{$}} @@ -524,7 +524,7 @@ !CHECK: acc.kernels { !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: }{{$}} @@ -538,7 +538,7 @@ !CHECK: acc.kernels { !CHECK: [[VECTORLENGTH:%.*]] = fir.load %{{.*}} : !fir.ref -!CHECK: acc.loop vector([[VECTORLENGTH]]: i32) { +!CHECK: acc.loop vector([[VECTORLENGTH]] : i32) { !CHECK: fir.do_loop !CHECK: acc.yield !CHECK-NEXT: }{{$}} @@ -565,7 +565,7 @@ !CHECK: acc.kernels { !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: }{{$}} @@ -615,7 +615,7 @@ !CHECK: acc.kernels { !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: }{{$}} @@ -629,7 +629,7 @@ !CHECK: acc.kernels { !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: }{{$}} @@ -646,7 +646,7 @@ !CHECK: acc.kernels { !CHECK: [[TILESIZE1:%.*]] = arith.constant 2 : i32 !CHECK: [[TILESIZE2:%.*]] = arith.constant 2 : i32 -!CHECK: acc.loop tile([[TILESIZE1]]: i32, [[TILESIZE2]]: i32) { +!CHECK: acc.loop tile([[TILESIZE1]], [[TILESIZE2]] : i32, i32) { !CHECK: fir.do_loop !CHECK: acc.yield !CHECK-NEXT: }{{$}} @@ -674,7 +674,7 @@ END DO !CHECK: acc.kernels { -!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-loop.f90 b/flang/test/Lower/OpenACC/acc-loop.f90 --- a/flang/test/Lower/OpenACC/acc-loop.f90 +++ b/flang/test/Lower/OpenACC/acc-loop.f90 @@ -70,7 +70,7 @@ 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 @@ END DO !CHECK: [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref -!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 @@ 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 @@ 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 @@ END DO !CHECK: [[VECTORLENGTH:%.*]] = fir.load %{{.*}} : !fir.ref -!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 @@ 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 @@ a(i) = b(i) END DO -!CHECK: acc.loop private(%{{.*}}: !fir.ref>) { +!CHECK: acc.loop private(%{{.*}} : !fir.ref>) { !CHECK: fir.do_loop !CHECK: acc.yield !CHECK-NEXT: }{{$}} @@ -164,7 +164,7 @@ a(i) = b(i) END DO -!CHECK: acc.loop private(%{{.*}}: !fir.ref>, %{{.*}}: !fir.ref>) { +!CHECK: acc.loop private(%{{.*}}, %{{.*}} : !fir.ref>, !fir.ref>) { !CHECK: fir.do_loop !CHECK: acc.yield !CHECK-NEXT: }{{$}} @@ -174,7 +174,7 @@ a(i) = b(i) END DO -!CHECK: acc.loop private(%{{.*}}: !fir.ref>, %{{.*}}: !fir.ref>) { +!CHECK: acc.loop private(%{{.*}}, %{{.*}} : !fir.ref>, !fir.ref>) { !CHECK: fir.do_loop !CHECK: acc.yield !CHECK-NEXT: }{{$}} @@ -184,7 +184,7 @@ 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 @@ 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 @@ !CHECK: [[TILESIZE1:%.*]] = arith.constant 2 : i32 !CHECK: [[TILESIZE2:%.*]] = arith.constant 2 : i32 -!CHECK: acc.loop tile([[TILESIZE1]]: i32, [[TILESIZE2]]: i32) { +!CHECK: acc.loop tile([[TILESIZE1]], [[TILESIZE2]] : i32, i32) { !CHECK: fir.do_loop !CHECK: acc.yield !CHECK-NEXT: }{{$}} @@ -218,7 +218,7 @@ 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 @@ 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 --- a/flang/test/Lower/OpenACC/acc-parallel-loop.f90 +++ b/flang/test/Lower/OpenACC/acc-parallel-loop.f90 @@ -418,7 +418,7 @@ END DO !CHECK: acc.parallel firstprivate([[B]] : !fir.ref>) private([[A]] : !fir.ref>) { -!CHECK: acc.loop private([[A]]: !fir.ref>) { +!CHECK: acc.loop private([[A]] : !fir.ref>) { !CHECK: fir.do_loop !CHECK: acc.yield !CHECK-NEXT: }{{$}} @@ -484,7 +484,7 @@ !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 @@ !CHECK: acc.parallel { !CHECK: [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref -!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 @@ 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 @@ !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 @@ !CHECK: acc.parallel { !CHECK: [[VECTORLENGTH:%.*]] = fir.load %{{.*}} : !fir.ref -!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 @@ !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 @@ !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 @@ !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 @@ !CHECK: acc.parallel { !CHECK: [[TILESIZE1:%.*]] = arith.constant 2 : i32 !CHECK: [[TILESIZE2:%.*]] = arith.constant 2 : i32 -!CHECK: acc.loop tile([[TILESIZE1]]: i32, [[TILESIZE2]]: i32) { +!CHECK: acc.loop tile([[TILESIZE1]], [[TILESIZE2]] : i32, i32) { !CHECK: fir.do_loop !CHECK: acc.yield !CHECK-NEXT: }{{$}} @@ -672,7 +672,7 @@ 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 @@ 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 --- a/flang/test/Lower/OpenACC/acc-serial-loop.f90 +++ b/flang/test/Lower/OpenACC/acc-serial-loop.f90 @@ -334,7 +334,7 @@ END DO !CHECK: acc.serial firstprivate([[B]] : !fir.ref>) private([[A]] : !fir.ref>) { -!CHECK: acc.loop private([[A]]: !fir.ref>) { +!CHECK: acc.loop private([[A]] : !fir.ref>) { !CHECK: fir.do_loop !CHECK: acc.yield !CHECK-NEXT: }{{$}} @@ -400,7 +400,7 @@ !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 @@ !CHECK: acc.serial { !CHECK: [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref -!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 @@ 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 @@ !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 @@ !CHECK: acc.serial { !CHECK: [[VECTORLENGTH:%.*]] = fir.load %{{.*}} : !fir.ref -!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 @@ !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 @@ !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 @@ !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 @@ !CHECK: acc.serial { !CHECK: [[TILESIZE1:%.*]] = arith.constant 2 : i32 !CHECK: [[TILESIZE2:%.*]] = arith.constant 2 : i32 -!CHECK: acc.loop tile([[TILESIZE1]]: i32, [[TILESIZE2]]: i32) { +!CHECK: acc.loop tile([[TILESIZE1]], [[TILESIZE2]] : i32, i32) { !CHECK: fir.do_loop !CHECK: acc.yield !CHECK-NEXT: }{{$}} @@ -588,7 +588,7 @@ 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 @@ 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 --- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td @@ -547,32 +547,39 @@ UnitAttr:$seq, UnitAttr:$independent, UnitAttr:$auto_, + UnitAttr:$hasGang, + UnitAttr:$hasWorker, + UnitAttr:$hasVector, Variadic:$tileOperands, Variadic:$privateOperands, OptionalAttr:$reductionOp, - Variadic:$reductionOperands, - DefaultValuedAttr:$exec_mapping); + Variadic:$reductionOperands); let results = (outs Variadic:$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($gangNum, type($gangNum), $gangStatic, type($gangStatic), $hasGang) + | `worker` `` custom($workerNum, type($workerNum), $hasWorker) + | `vector` `` custom($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 --- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp +++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp @@ -52,85 +52,6 @@ return success(); } -static ParseResult -parseOperandList(OpAsmParser &parser, StringRef keyword, - SmallVectorImpl &args, - SmallVectorImpl &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(op) || isa(op); } @@ -232,180 +153,114 @@ // LoopOp //===----------------------------------------------------------------------===// -/// 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 operandTypes; - SmallVector privateOperands, - reductionOperands; - SmallVector tileOperands; - OptionalParseResult gangNum, gangStatic, worker, vector; - - // gang? - if (succeeded(parser.parseOptionalKeyword(LoopOp::getGangKeyword()))) - executionMapping |= OpenACCExecMapping::GANG; - - // optional gang operand +static ParseResult +parseGangClause(OpAsmParser &parser, + std::optional &gangNum, + Type &gangNumType, + std::optional &gangStatic, + Type &gangStaticType, UnitAttr &hasGang) { + hasGang = UnitAttr::get(parser.getBuilder().getContext()); + // optional gang operands if (succeeded(parser.parseOptionalLParen())) { - gangNum = parserOptionalOperandAndTypeWithPrefix( - parser, result, LoopOp::getGangNumKeyword()); - if (gangNum.has_value() && failed(*gangNum)) - return failure(); + 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; + } // FIXME: Comma should require subsequent operands. (void)parser.parseOptionalComma(); - gangStatic = parserOptionalOperandAndTypeWithPrefix( - parser, result, LoopOp::getGangStaticKeyword()); - if (gangStatic.has_value() && failed(*gangStatic)) - return failure(); + 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(); + } // 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(parser, result))) - return failure(); - - result.addAttribute(LoopOp::getOperandSegmentSizeAttr(), - builder.getDenseI32ArrayAttr( - {static_cast(gangNum.has_value() ? 1 : 0), - static_cast(gangStatic.has_value() ? 1 : 0), - static_cast(worker.has_value() ? 1 : 0), - static_cast(vector.has_value() ? 1 : 0), - static_cast(tileOperands.size()), - static_cast(privateOperands.size()), - static_cast(reductionOperands.size())})); - - if (failed(parser.parseOptionalAttrDictWithKeyword(result.attributes))) - return failure(); - return success(); } -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 << ", "; - } +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; if (gangStatic) - printer << LoopOp::getGangStaticKeyword() << "=" << gangStatic << ": " - << gangStatic.getType(); - printer << ")"; + p << ", "; } + if (gangStatic) + p << LoopOp::getGangStaticKeyword() << "=" << gangStatic << " : " + << gangStaticType; + p << ")"; } +} - if (execMapping & OpenACCExecMapping::WORKER) { - printer << " " << LoopOp::getWorkerKeyword(); - - // Print optional worker operand if present - if (Value workerNum = getWorkerNum()) - printer << "(" << workerNum << ": " << workerNum.getType() << ")"; +static ParseResult +parseWorkerClause(OpAsmParser &parser, + std::optional &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(); } + return success(); +} - if (execMapping & OpenACCExecMapping::VECTOR) { - printer << " " << LoopOp::getVectorKeyword(); +void printWorkerClause(OpAsmPrinter &p, Operation *op, Value workerNum, + Type workerNumType, UnitAttr hasWorker) { + if (workerNum) + p << "(" << workerNum << " : " << workerNumType << ")"; +} - // Print optional vector operand if present - if (Value vectorLength = this->getVectorLength()) - printer << "(" << vectorLength << ": " << vectorLength.getType() << ")"; +static ParseResult +parseVectorClause(OpAsmParser &parser, + std::optional &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(); } + return success(); +} - // 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()}); +void printVectorClause(OpAsmPrinter &p, Operation *op, Value vectorLength, + Type vectorLengthType, UnitAttr hasVector) { + if (vectorLength) + p << "(" << vectorLength << " : " << vectorLengthType << ")"; } 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() + ", " + - acc::LoopOp::getIndependentAttrStrName() + ", " + - acc::LoopOp::getSeqAttrStrName() + - " can be present at the same time"); + return emitError() << "only one of \"" << acc::LoopOp::getAutoAttrStrName() + << "\", " << getIndependentAttrName() << ", " + << getSeqAttrName() + << " can be present at the same time"; } // Gang, worker and vector are incompatible with seq. - if (getSeq() && getExecMapping() != OpenACCExecMapping::NONE) + if (getSeq() && (getHasGang() || getHasWorker() || getHasVector())) 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 --- a/mlir/test/Dialect/OpenACC/invalid.mlir +++ b/mlir/test/Dialect/OpenACC/invalid.mlir @@ -62,7 +62,7 @@ // ----- -// expected-error@+1 {{only one of auto, independent, seq can be present at the same time}} +// expected-error@+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 --- a/mlir/test/Dialect/OpenACC/ops.mlir +++ b/mlir/test/Dialect/OpenACC/ops.mlir @@ -250,11 +250,11 @@ "test.openacc_dummy_op"() : () -> () acc.yield } - acc.loop tile(%i64Value: i64, %i64Value: i64) { + acc.loop tile(%i64Value, %i64Value : i64, i64) { "test.openacc_dummy_op"() : () -> () acc.yield } - acc.loop tile(%i32Value: i32, %i32Value: i32) { + acc.loop tile(%i32Value, %i32Value : i32, i32) { "test.openacc_dummy_op"() : () -> () acc.yield } @@ -268,55 +268,55 @@ // 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]]: i64, [[I64VALUE]]: i64) { +// CHECK: acc.loop tile([[I64VALUE]], [[I64VALUE]] : i64, i64) { // CHECK-NEXT: "test.openacc_dummy_op"() : () -> () // CHECK-NEXT: acc.yield // CHECK-NEXT: } -// CHECK: acc.loop tile([[I32VALUE]]: i32, [[I32VALUE]]: i32) { +// CHECK: acc.loop tile([[I32VALUE]], [[I32VALUE]] : i32, i32) { // CHECK-NEXT: "test.openacc_dummy_op"() : () -> () // CHECK-NEXT: acc.yield // CHECK-NEXT: }