diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -92,6 +92,8 @@ NODE(parser, AccSizeExprList) NODE(parser, AccSelfClause) NODE(parser, AccStandaloneDirective) + NODE(parser, AccDeviceTypeExpr) + NODE(parser, AccDeviceTypeExprList) NODE(parser, AccTileExpr) NODE(parser, AccTileExprList) NODE(parser, AccLoopDirective) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3887,6 +3887,17 @@ std::tuple, std::list> t; }; +struct AccDeviceTypeExpr { + TUPLE_CLASS_BOILERPLATE(AccDeviceTypeExpr); + CharBlock source; + std::tuple> t; // if null then * +}; + +struct AccDeviceTypeExprList { + WRAPPER_CLASS_BOILERPLATE( + AccDeviceTypeExprList, std::list); +}; + struct AccTileExpr { TUPLE_CLASS_BOILERPLATE(AccTileExpr); CharBlock source; 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 @@ -758,20 +758,23 @@ } else if (const auto *deviceTypeClause = std::get_if( &clause.u)) { - - const auto &deviceTypeValue = deviceTypeClause->v; - if (deviceTypeValue) { - for (const auto &scalarIntExpr : *deviceTypeValue) { - mlir::Value expr = fir::getBase(converter.genExprValue( - *Fortran::semantics::GetExpr(scalarIntExpr))); - deviceTypeOperands.push_back(expr); + const Fortran::parser::AccDeviceTypeExprList &deviceTypeExprList = + deviceTypeClause->v; + for (const auto &deviceTypeExpr : deviceTypeExprList.v) { + const auto &expr = + std::get>( + deviceTypeExpr.t); + if (expr) { + deviceTypeOperands.push_back(fir::getBase( + converter.genExprValue(*Fortran::semantics::GetExpr(*expr)))); + } else { + // * was passed as value and will be represented as a -1 constant + // integer. + mlir::Value star = firOpBuilder.createIntegerConstant( + currentLocation, firOpBuilder.getIntegerType(32), + /* STAR */ -1); + deviceTypeOperands.push_back(star); } - } else { - // * was passed as value and will be represented as a -1 constant - // integer. - mlir::Value star = firOpBuilder.createIntegerConstant( - currentLocation, firOpBuilder.getIntegerType(32), /* STAR */ -1); - deviceTypeOperands.push_back(star); } } } @@ -846,20 +849,23 @@ } else if (const auto *deviceTypeClause = std::get_if( &clause.u)) { - - const auto &deviceTypeValue = deviceTypeClause->v; - if (deviceTypeValue) { - for (const auto &scalarIntExpr : *deviceTypeValue) { - mlir::Value expr = fir::getBase(converter.genExprValue( - *Fortran::semantics::GetExpr(scalarIntExpr))); - deviceTypeOperands.push_back(expr); + const Fortran::parser::AccDeviceTypeExprList &deviceTypeExprList = + deviceTypeClause->v; + for (const auto &deviceTypeExpr : deviceTypeExprList.v) { + const auto &expr = + std::get>( + deviceTypeExpr.t); + if (expr) { + deviceTypeOperands.push_back(fir::getBase( + converter.genExprValue(*Fortran::semantics::GetExpr(*expr)))); + } else { + // * was passed as value and will be represented as a -1 constant + // integer. + mlir::Value star = firOpBuilder.createIntegerConstant( + currentLocation, firOpBuilder.getIntegerType(32), + /* STAR */ -1); + deviceTypeOperands.push_back(star); } - } else { - // * was passed as value and will be represented as a -1 constant - // integer. - mlir::Value star = firOpBuilder.createIntegerConstant( - currentLocation, firOpBuilder.getIntegerType(32), /* STAR */ -1); - deviceTypeOperands.push_back(star); } } else if (const auto *hostClause = std::get_if(&clause.u)) { diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp --- a/flang/lib/Parser/openacc-parsers.cpp +++ b/flang/lib/Parser/openacc-parsers.cpp @@ -62,12 +62,9 @@ "DEVICE_RESIDENT" >> construct(construct( parenthesized(Parser{}))) || - ("DEVICE_TYPE"_tok || "DTYPE"_tok) >> - construct(construct(parenthesized( - "*" >> construct>>()))) || ("DEVICE_TYPE"_tok || "DTYPE"_tok) >> construct(construct( - parenthesized(maybe(nonemptyList(scalarIntExpr))))) || + parenthesized(Parser{}))) || "FINALIZE" >> construct(construct()) || "FIRSTPRIVATE" >> construct(construct( parenthesized(Parser{}))) || @@ -137,6 +134,12 @@ construct("*" >> construct>())) TYPE_PARSER(construct(nonemptyList(Parser{}))) +TYPE_PARSER(construct(scalarIntExpr) || + construct( + "*" >> construct>())) +TYPE_PARSER( + construct(nonemptyList(Parser{}))) + // tile size is one of: // * (represented as an empty std::optional) // constant-int-expr diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td --- a/llvm/include/llvm/Frontend/OpenACC/ACC.td +++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td @@ -128,10 +128,8 @@ // 2.4 def ACCC_DeviceType : Clause<"device_type"> { - let flangClass = "ScalarIntExpr"; + let flangClass = "AccDeviceTypeExprList"; let defaultValue = "*"; - let isValueOptional = true; - let isValueList = true; } // 2.6.6