[clang] [openmp] [Clang][OpenMP] Use loop as ident flag for sections (PR #210038)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 16 05:54:59 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
Author: Jan André Reuter (Thyre)
<details>
<summary>Changes</summary>
For the OpenMP Tools Interface, a number of callbacks should get dispatched for the `sections` construct, and the `section` directive. For each _sections-begin_ event, a work callback with `ompt_scope_begin` as the endpoint and `ompt_work_sections` as the work_type dispatched. For each _section-begin_, a dispatch callback with the kind set to `ompt_dispatch_section` is dispatched. And finally, on _sections-end_, another work callback with `ompt_scope_end` is emitted.
In Clang and Flang, the `sections` construct and `section` directive is rewritten during code generation. A user code such as:
```
#pragma omp sections
{
#pragma omp section
{}
#pragma omp section
{}
}
```
is transformed to:
```
[...]
omp.inner.for.cond:
%6 = load i32, ptr %.omp.sections.iv., align 4
%7 = load i32, ptr %.omp.sections.ub., align 4
%cmp = icmp sle i32 %6, %7
br i1 %cmp, label %omp.inner.for.body, label %omp.inner.for.end
omp.inner.for.body:
%8 = load i32, ptr %.omp.sections.iv., align 4
switch i32 %8, label %.omp.sections.exit [
i32 0, label %.omp.sections.case
i32 1, label %.omp.sections.case1
]
.omp.sections.case:
br label %.omp.sections.exit
.omp.sections.case1:
br label %.omp.sections.exit
.omp.sections.exit:
br label %omp.inner.for.inc
[...]
```
Clang and Flang both use a static loop, splitting work across threads in the team, with a switch-case to select the correct `section` directive. On the call to `__kmpc_for_static_init`, Clang passes `OMP_IDENT_WORK_SECTIONS` as part of the ident flags. As such, the OpenMP runtime identifies the transformed construct as a `sections` construct with one or more `section` directives.
In #<!-- -->207746, it was found that this handling can lead to an incorrect event sequence emitted to tools. Since `__kmpc_for_static_init` is only called _once_ at the beginning of the loop for each thread in the team, and each thread dispatches one work and dispatch callback to an attached tool, regardless of the actual number of section directives handles, a tool might therefore incorrectly assume that the number of `section` directives matches the number of threads.
To improve the dispatched events to an attached tool, use `OMP_IDENT_WORK_LOOP` for the `sections` construct and `section` directives as well. With this, the behavior of Clang is consistent with the behavior of Flang. A tool is able to identify the number of loop iterations done per thread, hence is able to filter threads not executing any `section` directive.
Closes #<!-- -->207746
---
Full diff: https://github.com/llvm/llvm-project/pull/210038.diff
4 Files Affected:
- (modified) clang/lib/CodeGen/CGOpenMPRuntime.cpp (+3-7)
- (modified) clang/test/OpenMP/sections_codegen.cpp (+1-1)
- (modified) openmp/runtime/test/ompt/worksharing/sections.c (+4-4)
- (modified) openmp/runtime/test/ompt/worksharing/sections_dispatch.c (+6-8)
``````````diff
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index eb2f92cdbf972..f68fbb8b50824 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -2752,10 +2752,8 @@ void CGOpenMPRuntime::emitForStaticInit(CodeGenFunction &CGF,
Values.Ordered);
assert((isOpenMPWorksharingDirective(DKind) || (DKind == OMPD_loop)) &&
"Expected loop-based or sections-based directive.");
- llvm::Value *UpdatedLocation = emitUpdateLocation(CGF, Loc,
- isOpenMPLoopDirective(DKind)
- ? OMP_IDENT_WORK_LOOP
- : OMP_IDENT_WORK_SECTIONS);
+ llvm::Value *UpdatedLocation =
+ emitUpdateLocation(CGF, Loc, OMP_IDENT_WORK_LOOP);
llvm::Value *ThreadId = getThreadID(CGF, Loc);
llvm::FunctionCallee StaticInitFunction =
OMPBuilder.createForStaticInitFunction(Values.IVSize, Values.IVSigned,
@@ -2799,9 +2797,7 @@ void CGOpenMPRuntime::emitForStaticFinish(CodeGenFunction &CGF,
isOpenMPDistributeDirective(DKind) ||
(DKind == OMPD_target_teams_loop)
? OMP_IDENT_WORK_DISTRIBUTE
- : isOpenMPLoopDirective(DKind)
- ? OMP_IDENT_WORK_LOOP
- : OMP_IDENT_WORK_SECTIONS),
+ : OMP_IDENT_WORK_LOOP),
getThreadID(CGF, Loc)};
auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc);
if (isOpenMPDistributeDirective(DKind) &&
diff --git a/clang/test/OpenMP/sections_codegen.cpp b/clang/test/OpenMP/sections_codegen.cpp
index 5a5e32751c677..957833e60daaa 100644
--- a/clang/test/OpenMP/sections_codegen.cpp
+++ b/clang/test/OpenMP/sections_codegen.cpp
@@ -10,7 +10,7 @@
#ifndef HEADER
#define HEADER
// CHECK-DAG: [[IMPLICIT_BARRIER_SECTIONS_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 194, i32 0, i32 {{[0-9]+}}, ptr
-// CHECK-DAG: [[SECTIONS_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 1026, i32 0, i32 {{[0-9]+}}, ptr
+// CHECK-DAG: [[SECTIONS_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 514, i32 0, i32 {{[0-9]+}}, ptr
// CHECK-LABEL: foo
void foo() { extern void mayThrow(); mayThrow(); };
// CHECK-LABEL: bar
diff --git a/openmp/runtime/test/ompt/worksharing/sections.c b/openmp/runtime/test/ompt/worksharing/sections.c
index 5cf927def6905..b319a0f1a9a3f 100644
--- a/openmp/runtime/test/ompt/worksharing/sections.c
+++ b/openmp/runtime/test/ompt/worksharing/sections.c
@@ -28,11 +28,11 @@ int main() {
// CHECK: 0: NULL_POINTER=[[NULL:.*$]]
- // CHECK: {{^}}[[MASTER_ID:[0-9]+]]: ompt_event_sections_begin: parallel_id=[[PARALLEL_ID:[0-f]+]], task_id=[[TASK_ID:[0-f]+]], codeptr_ra=[[SECT_BEGIN:(0x)?[0-f]+]], count=2
- // CHECK: {{^}}[[MASTER_ID]]: ompt_event_sections_end: parallel_id=[[PARALLEL_ID]], task_id={{[0-f]+}}, codeptr_ra=[[SECT_END:(0x)?[0-f]+]]
+ // CHECK: {{^}}[[MASTER_ID:[0-9]+]]: ompt_event_loop_static_begin: parallel_id=[[PARALLEL_ID:[0-f]+]], task_id=[[TASK_ID:[0-f]+]], codeptr_ra=[[SECT_BEGIN:(0x)?[0-f]+]], count=2
+ // CHECK: {{^}}[[MASTER_ID]]: ompt_event_loop_static_end: parallel_id=[[PARALLEL_ID]], task_id={{[0-f]+}}, codeptr_ra=[[SECT_END:(0x)?[0-f]+]]
- // CHECK: {{^}}[[THREAD_ID:[0-9]+]]: ompt_event_sections_begin: parallel_id=[[PARALLEL_ID]], task_id=[[TASK_ID:[0-f]+]], codeptr_ra=[[SECT_BEGIN]], count=2
- // CHECK: {{^}}[[THREAD_ID]]: ompt_event_sections_end: parallel_id=[[PARALLEL_ID]], task_id={{[0-f]+}}, codeptr_ra=[[SECT_END]]
+ // CHECK: {{^}}[[THREAD_ID:[0-9]+]]: ompt_event_loop_static_begin: parallel_id=[[PARALLEL_ID]], task_id=[[TASK_ID:[0-f]+]], codeptr_ra=[[SECT_BEGIN]], count=2
+ // CHECK: {{^}}[[THREAD_ID]]: ompt_event_loop_static_end: parallel_id=[[PARALLEL_ID]], task_id={{[0-f]+}}, codeptr_ra=[[SECT_END]]
// clang-format on
return 0;
diff --git a/openmp/runtime/test/ompt/worksharing/sections_dispatch.c b/openmp/runtime/test/ompt/worksharing/sections_dispatch.c
index ec3bb5bd7552d..fc573ee5ae971 100644
--- a/openmp/runtime/test/ompt/worksharing/sections_dispatch.c
+++ b/openmp/runtime/test/ompt/worksharing/sections_dispatch.c
@@ -29,24 +29,22 @@ int main() {
// CHECK: 0: NULL_POINTER=[[NULL:.*$]]
- // CHECK: {{^}}[[MASTER_ID:[0-9]+]]: ompt_event_sections_begin:
+ // CHECK: {{^}}[[MASTER_ID:[0-9]+]]: ompt_event_loop_static_begin:
// CHECK-SAME: parallel_id=[[PARALLEL_ID:[0-f]+]],
// CHECK-SAME: task_id=[[TASK_ID:[0-f]+]],
// CHECK-SAME: codeptr_ra=[[SECT_BEGIN:(0x)?[0-f]+]], count=2
- // CHECK: {{^}}[[MASTER_ID]]: ompt_event_section_begin:
+ // CHECK: {{^}}[[MASTER_ID]]: ompt_event_ws_loop_chunk_begin:
// CHECK-SAME: parallel_id=[[PARALLEL_ID]], task_id=[[TASK_ID]]
- // CHECK-SAME: codeptr_ra=[[SECT_BEGIN]]
- // CHECK: {{^}}[[MASTER_ID]]: ompt_event_sections_end:
+ // CHECK: {{^}}[[MASTER_ID]]: ompt_event_loop_static_end:
// CHECK-SAME: parallel_id=[[PARALLEL_ID]], task_id={{[0-f]+}},
// CHECK-SAME: codeptr_ra=[[SECT_END:(0x)?[0-f]+]]
- // CHECK: {{^}}[[THREAD_ID:[0-9]+]]: ompt_event_sections_begin:
+ // CHECK: {{^}}[[THREAD_ID:[0-9]+]]: ompt_event_loop_static_begin:
// CHECK-SAME: parallel_id=[[PARALLEL_ID]], task_id=[[TASK_ID:[0-f]+]],
// CHECK-SAME: codeptr_ra=[[SECT_BEGIN]], count=2
- // CHECK: {{^}}[[THREAD_ID]]: ompt_event_section_begin:
+ // CHECK: {{^}}[[THREAD_ID]]: ompt_event_ws_loop_chunk_begin:
// CHECK-SAME: parallel_id=[[PARALLEL_ID]], task_id=[[TASK_ID]]
- // CHECK-SAME: codeptr_ra=[[SECT_BEGIN]]
- // CHECK: {{^}}[[THREAD_ID]]: ompt_event_sections_end:
+ // CHECK: {{^}}[[THREAD_ID]]: ompt_event_loop_static_end:
// CHECK-SAME: parallel_id=[[PARALLEL_ID]], task_id={{[0-f]+}},
// CHECK-SAME: codeptr_ra=[[SECT_END]]
// clang-format on
``````````
</details>
https://github.com/llvm/llvm-project/pull/210038
More information about the cfe-commits
mailing list