[flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_REDUCTION (#160192)

This commit is contained in:
Krzysztof Parzyszek
2025-09-23 12:06:16 -05:00
committed by GitHub
parent 6ac40aaaf6
commit a4168a6859
11 changed files with 188 additions and 146 deletions

View File

@@ -4962,11 +4962,9 @@ struct OpenMPDeclareMapperConstruct {
// 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
// : combiner) [initializer-clause]
struct OpenMPDeclareReductionConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPDeclareReductionConstruct);
WRAPPER_CLASS_BOILERPLATE(
OpenMPDeclareReductionConstruct, OmpDirectiveSpecification);
CharBlock source;
std::tuple<Verbatim, common::Indirection<OmpReductionSpecifier>,
std::optional<OmpClauseList>>
t;
};
// 2.8.2 declare-simd -> DECLARE SIMD [(proc-name)] [declare-simd-clause[ [,]

View File

@@ -1716,9 +1716,9 @@ TYPE_PARSER(sourced(construct<OmpDeclareVariantDirective>(
// 2.16 Declare Reduction Construct
TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>(
verbatim("DECLARE REDUCTION"_tok) || verbatim("DECLARE_REDUCTION"_tok),
"(" >> indirect(Parser<OmpReductionSpecifier>{}) / ")",
maybe(Parser<OmpClauseList>{}))))
predicated(Parser<OmpDirectiveName>{},
IsDirective(llvm::omp::Directive::OMPD_declare_reduction)) >=
Parser<OmpDirectiveSpecification>{})))
// declare-target with list
TYPE_PARSER(sourced(construct<OmpDeclareTargetWithList>(

View File

@@ -2507,11 +2507,8 @@ public:
}
void Unparse(const OpenMPDeclareReductionConstruct &x) {
BeginOpenMP();
Word("!$OMP DECLARE REDUCTION ");
Put("(");
Walk(std::get<common::Indirection<OmpReductionSpecifier>>(x.t));
Put(")");
Walk(std::get<std::optional<OmpClauseList>>(x.t));
Word("!$OMP ");
Walk(x.v);
Put("\n");
EndOpenMP();
}

View File

@@ -624,11 +624,6 @@ template <typename Checker> struct DirectiveSpellingVisitor {
checker_(std::get<parser::Verbatim>(x.t).source, Directive::OMPD_assumes);
return false;
}
bool Pre(const parser::OpenMPDeclareReductionConstruct &x) {
checker_(std::get<parser::Verbatim>(x.t).source,
Directive::OMPD_declare_reduction);
return false;
}
bool Pre(const parser::OpenMPDeclareSimdConstruct &x) {
checker_(
std::get<parser::Verbatim>(x.t).source, Directive::OMPD_declare_simd);
@@ -1626,9 +1621,21 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareMapperConstruct &) {
void OmpStructureChecker::Enter(
const parser::OpenMPDeclareReductionConstruct &x) {
const auto &dir{std::get<parser::Verbatim>(x.t)};
PushContextAndClauseSets(
dir.source, llvm::omp::Directive::OMPD_declare_reduction);
const parser::OmpDirectiveName &dirName{x.v.DirName()};
PushContextAndClauseSets(dirName.source, dirName.v);
const parser::OmpArgumentList &args{x.v.Arguments()};
if (args.v.size() != 1) {
context_.Say(args.source,
"DECLARE_REDUCTION directive should have a single argument"_err_en_US);
return;
}
const parser::OmpArgument &arg{args.v.front()};
if (!std::holds_alternative<parser::OmpReductionSpecifier>(arg.u)) {
context_.Say(arg.source,
"The argument to the DECLARE_REDUCTION directive should be a reduction-specifier"_err_en_US);
}
}
void OmpStructureChecker::Leave(

View File

@@ -1559,12 +1559,7 @@ public:
bool Pre(const parser::OpenMPDeclareReductionConstruct &x) {
AddOmpSourceRange(x.source);
parser::OmpClauseList empty(std::list<parser::OmpClause>{});
auto &maybeClauses{std::get<std::optional<parser::OmpClauseList>>(x.t)};
ProcessReductionSpecifier(
std::get<Indirection<parser::OmpReductionSpecifier>>(x.t).value(),
maybeClauses ? *maybeClauses : empty, declaratives_.back());
return false;
return true;
}
bool Pre(const parser::OmpMapClause &);
@@ -1697,6 +1692,11 @@ public:
// should not reach a point where it calls this function.
llvm_unreachable("This function should not be reached by AST traversal");
}
bool Pre(const parser::OmpReductionSpecifier &x) {
// OmpReductionSpecifier is handled explicitly, and the AST traversal
// should not reach a point where it calls this function.
llvm_unreachable("This function should not be reached by AST traversal");
}
bool Pre(const parser::OmpDirectiveSpecification &x);
void Post(const parser::OmpDirectiveSpecification &) {
messageHandler().set_currStmtSource(std::nullopt);
@@ -1724,8 +1724,7 @@ private:
void ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
const parser::OmpClauseList &clauses);
void ProcessReductionSpecifier(const parser::OmpReductionSpecifier &spec,
const parser::OmpClauseList &clauses,
const parser::OpenMPDeclarativeConstruct *wholeConstruct);
const parser::OmpClauseList &clauses);
void ResolveCriticalName(const parser::OmpArgument &arg);
@@ -1856,8 +1855,7 @@ std::string MangleDefinedOperator(const parser::CharBlock &name) {
void OmpVisitor::ProcessReductionSpecifier(
const parser::OmpReductionSpecifier &spec,
const parser::OmpClauseList &clauses,
const parser::OpenMPDeclarativeConstruct *construct) {
const parser::OmpClauseList &clauses) {
const parser::Name *name{nullptr};
parser::CharBlock mangledName;
UserReductionDetails reductionDetailsTemp;
@@ -1944,7 +1942,7 @@ void OmpVisitor::ProcessReductionSpecifier(
PopScope();
}
reductionDetails->AddDecl(construct);
reductionDetails->AddDecl(declaratives_.back());
if (!symbol) {
symbol = &MakeSymbol(mangledName, Attrs{}, std::move(*reductionDetails));
@@ -1997,7 +1995,7 @@ bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) {
visitClauses = false;
},
[&](const parser::OmpReductionSpecifier &spec) {
ProcessReductionSpecifier(spec, clauses, declaratives_.back());
ProcessReductionSpecifier(spec, clauses);
visitClauses = false;
},
[&](const parser::OmpLocator &locator) {

View File

@@ -26,111 +26,127 @@ program omp_examples
type(tt) :: values(n), sum, prod, big, small
!$omp declare reduction(+:tt:omp_out%r = omp_out%r + omp_in%r) initializer(omp_priv%r = 0)
!CHECK: !$OMP DECLARE REDUCTION (+:tt: omp_out%r=omp_out%r+omp_in%r
!CHECK: !$OMP DECLARE REDUCTION(+:tt: omp_out%r=omp_out%r+omp_in%r
!CHECK-NEXT: ) INITIALIZER(omp_priv%r=0_4)
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct
!PARSE-TREE: Verbatim
!PARSE-TREE: OmpReductionSpecifier
!PARSE-TREE-NEXT: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE: OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
!PARSE-TREE-NEXT: Name = 'tt'
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=omp_out%r+omp_in%r'
!PARSE-TREE: OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier
!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
!PARSE-TREE: | | | Name = 'tt'
!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=omp_out%r+omp_in%r'
!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4'
!$omp declare reduction(*:tt:omp_out%r = omp_out%r * omp_in%r) initializer(omp_priv%r = 1)
!CHECK-NEXT: !$OMP DECLARE REDUCTION (*:tt: omp_out%r=omp_out%r*omp_in%r
!CHECK-NEXT: !$OMP DECLARE REDUCTION(*:tt: omp_out%r=omp_out%r*omp_in%r
!CHECK-NEXT: ) INITIALIZER(omp_priv%r=1_4)
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct
!PARSE-TREE: Verbatim
!PARSE-TREE: OmpReductionSpecifier
!PARSE-TREE: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply
!PARSE-TREE: OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
!PARSE-TREE-NEXT: Name = 'tt'
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=omp_out%r*omp_in%r'
!PARSE-TREE: OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=1._4'
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier
!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply
!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
!PARSE-TREE: | | | Name = 'tt'
!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=omp_out%r*omp_in%r'
!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=1._4'
!$omp declare reduction(max:tt:omp_out = mymax(omp_out, omp_in)) initializer(omp_priv%r = 0)
!CHECK-NEXT: !$OMP DECLARE REDUCTION (max:tt: omp_out=mymax(omp_out,omp_in)
!CHECK-NEXT: !$OMP DECLARE REDUCTION(max:tt: omp_out=mymax(omp_out,omp_in)
!CHECK-NEXT: ) INITIALIZER(omp_priv%r=0_4)
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct
!PARSE-TREE: Verbatim
!PARSE-TREE: OmpReductionSpecifier
!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'max'
!PARSE-TREE: OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
!PARSE-TREE: Name = 'tt'
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=mymax(omp_out,omp_in)'
!PARSE-TREE: OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4'
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier
!PARSE-TREE: | | OmpReductionIdentifier -> ProcedureDesignator -> Name = 'max'
!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
!PARSE-TREE: | | | Name = 'tt'
!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=mymax(omp_out,omp_in)'
!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4'
!$omp declare reduction(min:tt:omp_out%r = min(omp_out%r, omp_in%r)) initializer(omp_priv%r = 1)
!CHECK-NEXT: !$OMP DECLARE REDUCTION (min:tt: omp_out%r=min(omp_out%r,omp_in%r)
!CHECK-NEXT: !$OMP DECLARE REDUCTION(min:tt: omp_out%r=min(omp_out%r,omp_in%r)
!CHECK-NEXT: ) INITIALIZER(omp_priv%r=1_4)
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct
!PARSE-TREE: Verbatim
!PARSE-TREE: OmpReductionSpecifier
!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'min'
!PARSE-TREE: OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
!PARSE-TREE: Name = 'tt'
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=min(omp_out%r,omp_in%r)'
!PARSE-TREE: OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=1._4'
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier
!PARSE-TREE: | | OmpReductionIdentifier -> ProcedureDesignator -> Name = 'min'
!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
!PARSE-TREE: | | | Name = 'tt'
!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=min(omp_out%r,omp_in%r)'
!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=1._4'
call random_number(values%r)
sum%r = 0
!$omp parallel do reduction(+:sum)
!CHECK: !$OMP PARALLEL DO REDUCTION(+: sum)
!CHECK: !$OMP PARALLEL DO REDUCTION(+: sum)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
!PARSE-TREE: OmpBeginLoopDirective
!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = parallel do
!PARSE-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
!PARSE-TREE: Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'sum
!PARSE-TREE: Flags = None
!PARSE-TREE: DoConstruct
!PARSE-TREE: | OmpBeginLoopDirective
!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = parallel do
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'sum'
!PARSE-TREE: | | Flags = None
!PARSE-TREE: | DoConstruct
do i = 1, n
sum%r = sum%r + values(i)%r
end do
prod%r = 1
!$omp parallel do reduction(*:prod)
!CHECK: !$OMP PARALLEL DO REDUCTION(*: prod)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
!PARSE-TREE: OmpBeginLoopDirective
!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = parallel do
!PARSE-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
!PARSE-TREE: Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply
!PARSE-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'prod'
!PARSE-TREE: Flags = None
!PARSE-TREE: DoConstruct
!CHECK: !$OMP PARALLEL DO REDUCTION(*: prod)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
!PARSE-TREE: | OmpBeginLoopDirective
!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = parallel do
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply
!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'prod'
!PARSE-TREE: | | Flags = None
!PARSE-TREE: | DoConstruct
do i = 1, n
prod%r = prod%r * (values(i)%r+0.6)
end do
big%r = 0
!$omp parallel do reduction(max:big)
!CHECK: $OMP PARALLEL DO REDUCTION(max: big)
!CHECK: $OMP PARALLEL DO REDUCTION(max: big)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
!PARSE-TREE: OmpBeginLoopDirective
!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = parallel do
!PARSE-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
!PARSE-TREE: Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'max'
!PARSE-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'big'
!PARSE-TREE: Flags = None
!PARSE-TREE: DoConstruct
!PARSE-TREE: | OmpBeginLoopDirective
!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = parallel do
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'max'
!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'big'
!PARSE-TREE: | | Flags = None
!PARSE-TREE: | DoConstruct
do i = 1, n
big = mymax(values(i), big)
end do
small%r = 1
!$omp parallel do reduction(min:small)
!CHECK: !$OMP PARALLEL DO REDUCTION(min: small)
!CHECK-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
!CHECK-TREE: OmpBeginLoopDirective
!CHECK-TREE: OmpDirectiveName -> llvm::omp::Directive = parallel do
!CHECK-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
!CHECK-TREE: Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'min'
!CHECK-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'small'
!PARSE-TREE: Flags = None
!CHECK-TREE: DoConstruct
!CHECK: !$OMP PARALLEL DO REDUCTION(min: small)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
!PARSE-TREE: | OmpBeginLoopDirective
!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = parallel do
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'min'
!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'small'
!PARSE-TREE: | | Flags = None
!PARSE-TREE: | DoConstruct
do i = 1, n
small%r = min(values(i)%r, small%r)
end do
print *, values%r
print *, "sum=", sum%r
print *, "prod=", prod%r

View File

@@ -16,27 +16,33 @@ subroutine reduce_1 ( n, tts )
type(tt) :: tts(n)
type(tt2) :: tts2(n)
!CHECK: !$OMP DECLARE REDUCTION (+:tt: omp_out=tt(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)
!CHECK: !$OMP DECLARE REDUCTION(+:tt: omp_out=tt(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)
!CHECK: ) INITIALIZER(omp_priv=tt(x=0_4,y=0_4))
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct
!PARSE-TREE: Verbatim
!PARSE-TREE: OmpReductionSpecifier
!PARSE-TREE: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=tt(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)'
!PARSE-TREE: OmpInitializerClause -> AssignmentStmt = 'omp_priv=tt(x=0_4,y=0_4)'
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier
!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
!PARSE-TREE: | | | Name = 'tt'
!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=tt(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)'
!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv=tt(x=0_4,y=0_4)'
!$omp declare reduction(+ : tt : omp_out = tt(omp_out%x - omp_in%x , omp_out%y - omp_in%y)) initializer(omp_priv = tt(0,0))
!CHECK: !$OMP DECLARE REDUCTION (+:tt2: omp_out=tt2(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)
!CHECK: !$OMP DECLARE REDUCTION(+:tt2: omp_out=tt2(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)
!CHECK: ) INITIALIZER(omp_priv=tt2(x=0._8,y=0._8)
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct
!PARSE-TREE: Verbatim
!PARSE-TREE: OmpReductionSpecifier
!PARSE-TREE: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=tt2(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)'
!PARSE-TREE: OmpInitializerClause -> AssignmentStmt = 'omp_priv=tt2(x=0._8,y=0._8)'
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier
!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
!PARSE-TREE: | | | Name = 'tt2'
!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=tt2(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)'
!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv=tt2(x=0._8,y=0._8)'
!$omp declare reduction(+ :tt2 : omp_out = tt2(omp_out%x - omp_in%x , omp_out%y - omp_in%y)) initializer(omp_priv = tt2(0,0))
type(tt) :: diffp = tt( 0, 0 )

View File

@@ -8,6 +8,6 @@ end
!CHECK: !DEF: /f00 (Subroutine) Subprogram
!CHECK: subroutine f00
!CHECK: !$omp declare reduction (fred:integer,real:omp_out = omp_in+omp_out)
!CHECK: !$omp declare reduction(fred:integer,real:omp_out = omp_in+omp_out)
!CHECK: end subroutine

View File

@@ -18,21 +18,38 @@ function func(x, n, init)
integer x,n
end subroutine initme
end interface
!CHECK: !$OMP DECLARE REDUCTION (red_add:INTEGER(KIND=4_4): omp_out=omp_out+omp_in
!CHECK: ) INITIALIZER(initme(omp_priv, 0_4))
!$omp declare reduction(red_add:integer(4):omp_out=omp_out+omp_in) initializer(initme(omp_priv,0))
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in'
!PARSE-TREE: OmpInitializerClause -> OmpInitializerProc
!PARSE-TREE-NEXT: ProcedureDesignator -> Name = 'initme'
!CHECK: !$OMP DECLARE REDUCTION(red_add:INTEGER(KIND=4_4): omp_out=omp_out+omp_in
!CHECK: ) INITIALIZER(initme(omp_priv, 0_4))
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier
!PARSE-TREE: | | OmpReductionIdentifier -> ProcedureDesignator -> Name = 'red_add'
!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec -> KindSelector -> Scalar -> Integer -> Constant -> Expr = '4_4'
!PARSE-TREE: | | | LiteralConstant -> IntLiteralConstant = '4'
!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in'
!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> OmpInitializerProc
!PARSE-TREE: | | ProcedureDesignator -> Name = 'initme'
res=init
!$omp simd reduction(red_add:res)
!CHECK: !$OMP SIMD REDUCTION(red_add: res)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt = 'res=init'
!PARSE-TREE: | Variable = 'res'
!PARSE-TREE: | | Designator -> DataRef -> Name = 'res'
!PARSE-TREE: | Expr = 'init'
!PARSE-TREE: | | Designator -> DataRef -> Name = 'init'
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
!PARSE-TREE: OmpBeginLoopDirective
!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = simd
!PARSE-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
!PARSE-TREE: Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'red_add
!PARSE-TREE: | OmpBeginLoopDirective
!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = simd
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'red_add'
!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'res'
!PARSE-TREE: | | Flags = None
!PARSE-TREE: | DoConstruct
do i=1,n
res=res+x(i)
enddo
@@ -43,7 +60,7 @@ end function func
!CHECK-LABEL: program main
program main
integer :: my_var
!CHECK: !$OMP DECLARE REDUCTION (my_add_red:INTEGER: omp_out=omp_out+omp_in
!CHECK: !$OMP DECLARE REDUCTION(my_add_red:INTEGER: omp_out=omp_out+omp_in
!CHECK-NEXT: ) INITIALIZER(omp_priv=0_4)
!$omp declare reduction (my_add_red : integer : omp_out = omp_out + omp_in) initializer (omp_priv=0)
@@ -54,8 +71,10 @@ program main
print *, "sum of thread numbers is ", my_var
end program main
!PARSE-TREE: OpenMPDeclareReductionConstruct
!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'my_add_red'
!PARSE-TREE: DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in'
!PARSE-TREE: OmpInitializerClause -> AssignmentStmt = 'omp_priv=0_4'
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier
!PARSE-TREE: | | OmpReductionIdentifier -> ProcedureDesignator -> Name = 'my_add_red'
!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in'
!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv=0_4'

View File

@@ -79,13 +79,13 @@ end
!UNPARSE: TYPE :: t
!UNPARSE: INTEGER :: x
!UNPARSE: END TYPE
!UNPARSE: !$OMP DECLARE REDUCTION (+:t: omp_out%x=omp_out%x+omp_in%x
!UNPARSE: !$OMP DECLARE_REDUCTION(+:t: omp_out%x=omp_out%x+omp_in%x
!UNPARSE: )
!UNPARSE: END SUBROUTINE
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct
!PARSE-TREE: | Verbatim
!PARSE-TREE: | OmpReductionSpecifier
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier
!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
!PARSE-TREE: | | | Name = 't'
@@ -105,6 +105,7 @@ end
!PARSE-TREE: | | | | | | | DataRef -> Name = 'omp_in'
!PARSE-TREE: | | | | | | | Name = 'x'
!PARSE-TREE: | OmpClauseList ->
!PARSE-TREE: | Flags = None
subroutine f03
!$omp declare_simd

View File

@@ -6,13 +6,13 @@
!type::t1
!integer(4)::val
!endtype
!!$OMP DECLARE REDUCTION (*:t1:omp_out = omp_out*omp_in) INITIALIZER(omp_priv=t&
!!$OMP&1(1))
!!$OMP DECLARE REDUCTION(*:t1:omp_out = omp_out*omp_in) INITIALIZER(omp_priv=t1&
!!$OMP&(1))
!!$OMP METADIRECTIVE OTHERWISE(DECLARE REDUCTION(+:INTEGER))
!!$OMP DECLARE REDUCTION (.fluffy.:t1:omp_out = omp_out.fluffy.omp_in) INITIALI&
!!$OMP&ZER(omp_priv=t1(0))
!!$OMP DECLARE REDUCTION (.mul.:t1:omp_out = omp_out.mul.omp_in) INITIALIZER(om&
!!$OMP&p_priv=t1(1))
!!$OMP DECLARE REDUCTION(.fluffy.:t1:omp_out = omp_out.fluffy.omp_in) INITIALIZ&
!!$OMP&ER(omp_priv=t1(0))
!!$OMP DECLARE REDUCTION(.mul.:t1:omp_out = omp_out.mul.omp_in) INITIALIZER(omp&
!!$OMP&_priv=t1(1))
!interface operator(.mul.)
!procedure::mul
!end interface