@@ -3011,19 +3011,17 @@ genACC(Fortran::lower::AbstractConverter &converter,
3011
3011
funcName = funcOp.getName ();
3012
3012
}
3013
3013
3014
- mlir::OpBuilder modBuilder (mod.getBodyRegion ());
3015
- std::stringstream routineOpName;
3016
- routineOpName << accRoutinePrefix.str () << routineCounter++;
3017
- auto routineOp = modBuilder.create <mlir::acc::RoutineOp>(
3018
- loc, routineOpName.str (), funcName, mlir::StringAttr{}, false , false ,
3019
- false , false , false , false , mlir::IntegerAttr{});
3014
+ bool hasSeq = false , hasGang = false , hasWorker = false , hasVector = false ,
3015
+ hasNohost = false ;
3016
+ std::optional<std::string> bindName = std::nullopt;
3017
+ std::optional<int64_t > gangDim = std::nullopt;
3020
3018
3021
3019
for (const Fortran::parser::AccClause &clause : clauses.v ) {
3022
3020
if (std::get_if<Fortran::parser::AccClause::Seq>(&clause.u )) {
3023
- routineOp. setSeqAttr (builder. getUnitAttr ()) ;
3021
+ hasSeq = true ;
3024
3022
} else if (const auto *gangClause =
3025
3023
std::get_if<Fortran::parser::AccClause::Gang>(&clause.u )) {
3026
- routineOp. setGangAttr (builder. getUnitAttr ()) ;
3024
+ hasGang = true ;
3027
3025
if (gangClause->v ) {
3028
3026
const Fortran::parser::AccGangArgList &x = *gangClause->v ;
3029
3027
for (const Fortran::parser::AccGangArg &gangArg : x.v ) {
@@ -3034,36 +3032,60 @@ genACC(Fortran::lower::AbstractConverter &converter,
3034
3032
if (!dimValue)
3035
3033
mlir::emitError (loc,
3036
3034
" dim value must be a constant positive integer" );
3037
- routineOp.setGangDimAttr (
3038
- builder.getIntegerAttr (builder.getIntegerType (32 ), *dimValue));
3035
+ gangDim = *dimValue;
3039
3036
}
3040
3037
}
3041
3038
}
3042
3039
} else if (std::get_if<Fortran::parser::AccClause::Vector>(&clause.u )) {
3043
- routineOp. setVectorAttr (builder. getUnitAttr ()) ;
3040
+ hasVector = true ;
3044
3041
} else if (std::get_if<Fortran::parser::AccClause::Worker>(&clause.u )) {
3045
- routineOp. setWorkerAttr (builder. getUnitAttr ()) ;
3042
+ hasWorker = true ;
3046
3043
} else if (std::get_if<Fortran::parser::AccClause::Nohost>(&clause.u )) {
3047
- routineOp. setNohostAttr (builder. getUnitAttr ()) ;
3044
+ hasNohost = true ;
3048
3045
} else if (const auto *bindClause =
3049
3046
std::get_if<Fortran::parser::AccClause::Bind>(&clause.u )) {
3050
3047
if (const auto *name =
3051
3048
std::get_if<Fortran::parser::Name>(&bindClause->v .u )) {
3052
- routineOp.setBindName (
3053
- builder.getStringAttr (converter.mangleName (*name->symbol )));
3049
+ bindName = converter.mangleName (*name->symbol );
3054
3050
} else if (const auto charExpr =
3055
3051
std::get_if<Fortran::parser::ScalarDefaultCharExpr>(
3056
3052
&bindClause->v .u )) {
3057
- const std::optional<std::string> bindName =
3053
+ const std::optional<std::string> name =
3058
3054
Fortran::semantics::GetConstExpr<std::string>(semanticsContext,
3059
3055
*charExpr);
3060
- if (!bindName )
3061
- routineOp. emitError (" Could not retrieve the bind name" );
3062
- routineOp. setBindName (builder. getStringAttr (* bindName)) ;
3056
+ if (!name )
3057
+ mlir:: emitError (loc, " Could not retrieve the bind name" );
3058
+ bindName = *name ;
3063
3059
}
3064
3060
}
3065
3061
}
3066
3062
3063
+ mlir::OpBuilder modBuilder (mod.getBodyRegion ());
3064
+ std::stringstream routineOpName;
3065
+ routineOpName << accRoutinePrefix.str () << routineCounter++;
3066
+
3067
+ for (auto routineOp : mod.getOps <mlir::acc::RoutineOp>()) {
3068
+ if (routineOp.getFuncName ().str ().compare (funcName) == 0 ) {
3069
+ // If the routine is already specified with the same clauses, just skip
3070
+ // the operation creation.
3071
+ if (routineOp.getBindName () == bindName &&
3072
+ routineOp.getGang () == hasGang &&
3073
+ routineOp.getWorker () == hasWorker &&
3074
+ routineOp.getVector () == hasVector && routineOp.getSeq () == hasSeq &&
3075
+ routineOp.getNohost () == hasNohost &&
3076
+ routineOp.getGangDim () == gangDim)
3077
+ return ;
3078
+ mlir::emitError (loc, " Routine already specified with different clauses" );
3079
+ }
3080
+ }
3081
+
3082
+ modBuilder.create <mlir::acc::RoutineOp>(
3083
+ loc, routineOpName.str (), funcName,
3084
+ bindName ? builder.getStringAttr (*bindName) : mlir::StringAttr{}, hasGang,
3085
+ hasWorker, hasVector, hasSeq, hasNohost, /* implicit=*/ false ,
3086
+ gangDim ? builder.getIntegerAttr (builder.getIntegerType (32 ), *gangDim)
3087
+ : mlir::IntegerAttr{});
3088
+
3067
3089
if (funcOp)
3068
3090
attachRoutineInfo (funcOp, builder.getSymbolRefAttr (routineOpName.str ()));
3069
3091
else
0 commit comments