llvm-project/clang/test/OpenMP/generic_loop_ast_print.cpp
Krzysztof Parzyszek c74730070a
[clang][OpenMP] Move "loop" directive mapping from sema to codegen (#99905)
Given "loop" construct, clang will try to treat it as "for",
"distribute" or "simd", depending on either the implied binding, or the
bind clause if present. This patch moves the code that performs this
construct remapping from sema to codegen.

For a "loop" construct without a bind clause, this patch will create an
implicit bind clause based on implied binding to simplify further
analysis.

During codegen the function `EmitOMPGenericLoopDirective` (i.e. "loop")
will invoke the "emit" functions for "for", "distribute" or "simd",
depending on the bind clause.

---------

Co-authored-by: Alexey Bataev <a.bataev@gmx.com>
2024-07-23 07:31:42 -05:00

168 lines
4.6 KiB
C++

// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp \
// RUN: -fsyntax-only -verify %s
// expected-no-diagnostics
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp \
// RUN: -ast-print %s | FileCheck %s --check-prefix=PRINT
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp \
// RUN: -ast-dump %s | FileCheck %s --check-prefix=DUMP
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp \
// RUN: -emit-pch -o %t %s
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp \
// RUN: -include-pch %t -ast-dump-all %s | FileCheck %s --check-prefix=DUMP
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp \
// RUN: -include-pch %t -ast-print %s | FileCheck %s --check-prefix=PRINT
#ifndef HEADER
#define HEADER
//PRINT: template <typename T, int C> void templ_foo(T t) {
//PRINT: T j, z;
//PRINT: #pragma omp loop collapse(C) reduction(+: z) lastprivate(j) bind(thread)
//PRINT: for (T i = 0; i < t; ++i)
//PRINT: for (j = 0; j < t; ++j)
//PRINT: z += i + j;
//PRINT: }
//DUMP: FunctionTemplateDecl{{.*}}templ_foo
//DUMP: TemplateTypeParmDecl{{.*}}T
//DUMP: NonTypeTemplateParmDecl{{.*}}C
//DUMP: OMPGenericLoopDirective
//DUMP: OMPCollapseClause
//DUMP: DeclRefExpr{{.*}}'C' 'int'
//DUMP: OMPReductionClause
//DUMP: DeclRefExpr{{.*}}'z' 'T'
//DUMP: OMPLastprivateClause
//DUMP: DeclRefExpr{{.*}}'j' 'T'
//DUMP: OMPBindClause
//DUMP: ForStmt
//DUMP: ForStmt
//PRINT: template<> void templ_foo<int, 2>(int t) {
//PRINT: int j, z;
//PRINT: #pragma omp loop collapse(2) reduction(+: z) lastprivate(j) bind(thread)
//PRINT: for (int i = 0; i < t; ++i)
//PRINT: for (j = 0; j < t; ++j)
//PRINT: z += i + j;
//PRINT: }
//DUMP: FunctionDecl{{.*}}templ_foo 'void (int)'
//DUMP: TemplateArgument type 'int'
//DUMP: TemplateArgument integral '2'
//DUMP: ParmVarDecl{{.*}}'int'
//DUMP: OMPGenericLoopDirective
//DUMP: OMPCollapseClause
//DUMP: ConstantExpr{{.*}}'int'
//DUMP: value: Int 2
//DUMP: OMPReductionClause
//DUMP: DeclRefExpr{{.*}}'z' 'int'
//DUMP: OMPLastprivateClause
//DUMP: DeclRefExpr{{.*}}'j' 'int'
//DUMP: OMPBindClause
//DUMP: ForStmt
template <typename T, int C>
void templ_foo(T t) {
T j,z;
#pragma omp loop collapse(C) reduction(+:z) lastprivate(j) bind(thread)
for (T i = 0; i<t; ++i)
for (j = 0; j<t; ++j)
z += i+j;
}
//PRINT: void test() {
//DUMP: FunctionDecl {{.*}}test 'void ()'
void test() {
constexpr int N = 100;
float MTX[N][N];
int aaa[1000];
//PRINT: #pragma omp target teams distribute parallel for map(tofrom: MTX)
//PRINT: #pragma omp loop
//DUMP: OMPTargetTeamsDistributeParallelForDirective
//DUMP: CapturedStmt
//DUMP: ForStmt
//DUMP: CompoundStmt
//DUMP: OMPGenericLoopDirective
#pragma omp target teams distribute parallel for map(MTX)
for (auto i = 0; i < N; ++i) {
#pragma omp loop
for (auto j = 0; j < N; ++j) {
MTX[i][j] = 0;
}
}
//PRINT: #pragma omp target teams
//PRINT: #pragma omp loop
//DUMP: OMPTargetTeamsDirective
//DUMP: CapturedStmt
//DUMP: ForStmt
//DUMP: OMPGenericLoopDirective
#pragma omp target teams
for (int i=0; i<1000; ++i) {
#pragma omp loop
for (int j=0; j<100; j++) {
aaa[i] += i + j;
}
}
int j, z, z1;
//PRINT: #pragma omp loop collapse(2) private(z) lastprivate(j) order(concurrent) reduction(+: z1) bind(parallel)
//DUMP: OMPGenericLoopDirective
//DUMP: OMPCollapseClause
//DUMP: IntegerLiteral{{.*}}2
//DUMP: OMPPrivateClause
//DUMP-NEXT: DeclRefExpr{{.*}}'z'
//DUMP: OMPLastprivateClause
//DUMP-NEXT: DeclRefExpr{{.*}}'j'
//DUMP: OMPOrderClause
//DUMP: OMPReductionClause
//DUMP-NEXT: DeclRefExpr{{.*}}'z1'
//DUMP: OMPBindClause
//DUMP: ForStmt
//DUMP: ForStmt
#pragma omp loop collapse(2) private(z) lastprivate(j) order(concurrent) \
reduction(+:z1) bind(parallel)
for (auto i = 0; i < N; ++i) {
for (j = 0; j < N; ++j) {
z = i+j;
MTX[i][j] = z;
z1 += z;
}
}
//PRINT: #pragma omp target teams
//PRINT: #pragma omp loop bind(teams)
//DUMP: OMPTargetTeamsDirective
//DUMP: OMPGenericLoopDirective
//DUMP: OMPBindClause
//DUMP: ForStmt
#pragma omp target teams
#pragma omp loop bind(teams)
for (auto i = 0; i < N; ++i) { }
//PRINT: #pragma omp target
//PRINT: #pragma omp teams
//PRINT: #pragma omp loop bind(teams)
//DUMP: OMPTargetDirective
//DUMP: OMPTeamsDirective
//DUMP: OMPGenericLoopDirective
//DUMP: OMPBindClause
//DUMP: ForStmt
#pragma omp target
#pragma omp teams
#pragma omp loop bind(teams)
for (auto i = 0; i < N; ++i) { }
}
void bar()
{
templ_foo<int,2>(8);
}
#endif // HEADER