Skip to content

Commit f3bfc56

Browse files
authored
[Offload][OpenMP] Prettify error messages by "demangling" the kernel name (#101400)
The kernel names for OpenMP are manually mangled and not ideal when we report something to the user. We demangle them now, providing the function and line number of the target region, together with the actual kernel name.
1 parent 7471387 commit f3bfc56

File tree

15 files changed

+145
-24
lines changed

15 files changed

+145
-24
lines changed

llvm/include/llvm/Frontend/OpenMP/OMP.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "llvm/ADT/ArrayRef.h"
1919
#include "llvm/ADT/SmallVector.h"
20+
#include "llvm/ADT/StringRef.h"
2021

2122
namespace llvm::omp {
2223
ArrayRef<Directive> getLeafConstructs(Directive D);
@@ -30,6 +31,14 @@ Directive getCompoundConstruct(ArrayRef<Directive> Parts);
3031
bool isLeafConstruct(Directive D);
3132
bool isCompositeConstruct(Directive D);
3233
bool isCombinedConstruct(Directive D);
34+
35+
/// Create a nicer version of a function name for humans to look at.
36+
std::string prettifyFunctionName(StringRef FunctionName);
37+
38+
/// Deconstruct an OpenMP kernel name into the parent function name and the line
39+
/// number.
40+
std::string deconstructOpenMPKernelName(StringRef KernelName, unsigned &LineNo);
41+
3342
} // namespace llvm::omp
3443

3544
#endif // LLVM_FRONTEND_OPENMP_OMP_H

llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ class OpenMPIRBuilderConfig {
196196
/// Data structure to contain the information needed to uniquely identify
197197
/// a target entry.
198198
struct TargetRegionEntryInfo {
199+
/// The prefix used for kernel names.
200+
static constexpr const char *KernelNamePrefix = "__omp_offloading_";
201+
199202
std::string ParentName;
200203
unsigned DeviceID;
201204
unsigned FileID;

llvm/lib/Frontend/OpenMP/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ add_llvm_component_library(LLVMFrontendOpenMP
1717
TargetParser
1818
TransformUtils
1919
Analysis
20+
Demangle
2021
MC
2122
Scalar
2223
BitReader

llvm/lib/Frontend/OpenMP/OMP.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,19 @@
1010

1111
#include "llvm/ADT/ArrayRef.h"
1212
#include "llvm/ADT/STLExtras.h"
13+
#include "llvm/ADT/SmallString.h"
1314
#include "llvm/ADT/SmallVector.h"
1415
#include "llvm/ADT/StringRef.h"
1516
#include "llvm/ADT/StringSwitch.h"
17+
#include "llvm/Demangle/Demangle.h"
18+
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
1619
#include "llvm/Support/ErrorHandling.h"
20+
#include "llvm/Support/StringSaver.h"
1721

1822
#include <algorithm>
23+
#include <cstdio>
1924
#include <iterator>
25+
#include <string>
2026
#include <type_traits>
2127

2228
using namespace llvm;
@@ -186,4 +192,42 @@ bool isCombinedConstruct(Directive D) {
186192
// Otherwise directive-name is a combined construct.
187193
return !getLeafConstructs(D).empty() && !isCompositeConstruct(D);
188194
}
195+
196+
std::string prettifyFunctionName(StringRef FunctionName) {
197+
// Internalized functions have the right name, but simply a suffix.
198+
if (FunctionName.ends_with(".internalized"))
199+
return FunctionName.drop_back(sizeof("internalized")).str() +
200+
" (internalized)";
201+
unsigned LineNo = 0;
202+
auto ParentName = deconstructOpenMPKernelName(FunctionName, LineNo);
203+
if (LineNo == 0)
204+
return FunctionName.str();
205+
return ("omp target in " + ParentName + " @ " + std::to_string(LineNo) +
206+
" (" + FunctionName + ")")
207+
.str();
208+
}
209+
210+
std::string deconstructOpenMPKernelName(StringRef KernelName,
211+
unsigned &LineNo) {
212+
213+
// Only handle functions with an OpenMP kernel prefix for now. Naming scheme:
214+
// __omp_offloading_<hex_hash1>_<hex_hash2>_<name>_l<line>_[<count>_]<suffix>
215+
if (!KernelName.starts_with(TargetRegionEntryInfo::KernelNamePrefix))
216+
return "";
217+
218+
auto PrettyName = KernelName.drop_front(
219+
sizeof(TargetRegionEntryInfo::KernelNamePrefix) - /*'\0'*/ 1);
220+
for (int I = 0; I < 3; ++I) {
221+
PrettyName = PrettyName.drop_while([](char c) { return c != '_'; });
222+
PrettyName = PrettyName.drop_front();
223+
}
224+
225+
// Look for the last '_l<line>'.
226+
size_t LineIdx = PrettyName.rfind("_l");
227+
if (LineIdx == StringRef::npos)
228+
return "";
229+
if (PrettyName.drop_front(LineIdx + 2).consumeInteger(10, LineNo))
230+
return "";
231+
return demangle(PrettyName.take_front(LineIdx));
232+
}
189233
} // namespace llvm::omp

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8581,7 +8581,7 @@ void TargetRegionEntryInfo::getTargetRegionEntryFnName(
85818581
SmallVectorImpl<char> &Name, StringRef ParentName, unsigned DeviceID,
85828582
unsigned FileID, unsigned Line, unsigned Count) {
85838583
raw_svector_ostream OS(Name);
8584-
OS << "__omp_offloading" << llvm::format("_%x", DeviceID)
8584+
OS << KernelNamePrefix << llvm::format("%x", DeviceID)
85858585
<< llvm::format("_%x_", FileID) << ParentName << "_l" << Line;
85868586
if (Count)
85878587
OS << "_" << Count;

offload/plugins-nextgen/common/include/ErrorReporting.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/ADT/STLExtras.h"
1818
#include "llvm/ADT/SmallString.h"
1919
#include "llvm/ADT/StringRef.h"
20+
#include "llvm/Frontend/OpenMP/OMP.h"
2021
#include "llvm/Support/ErrorHandling.h"
2122
#include "llvm/Support/WithColor.h"
2223
#include "llvm/Support/raw_ostream.h"
@@ -237,8 +238,11 @@ class ErrorReporter {
237238
}
238239

239240
auto KTI = KTIR.getKernelTraceInfo(Idx);
240-
if (KTI.AsyncInfo && (AsyncInfoWrapperMatcher(*KTI.AsyncInfo)))
241-
reportError("Kernel '%s'", KTI.Kernel->getName());
241+
if (KTI.AsyncInfo && (AsyncInfoWrapperMatcher(*KTI.AsyncInfo))) {
242+
auto PrettyKernelName =
243+
llvm::omp::prettifyFunctionName(KTI.Kernel->getName());
244+
reportError("Kernel '%s'", PrettyKernelName.c_str());
245+
}
242246
reportError("execution interrupted by hardware trap instruction");
243247
if (KTI.AsyncInfo && (AsyncInfoWrapperMatcher(*KTI.AsyncInfo))) {
244248
if (!KTI.LaunchTrace.empty())
@@ -284,10 +288,13 @@ class ErrorReporter {
284288

285289
for (uint32_t Idx = 0, I = 0; I < NumKTIs; ++Idx) {
286290
auto KTI = KTIR.getKernelTraceInfo(Idx);
291+
auto PrettyKernelName =
292+
llvm::omp::prettifyFunctionName(KTI.Kernel->getName());
287293
if (NumKTIs == 1)
288-
print(BoldLightPurple, "Kernel '%s'\n", KTI.Kernel->getName());
294+
print(BoldLightPurple, "Kernel '%s'\n", PrettyKernelName.c_str());
289295
else
290-
print(BoldLightPurple, "Kernel %d: '%s'\n", I, KTI.Kernel->getName());
296+
print(BoldLightPurple, "Kernel %d: '%s'\n", I,
297+
PrettyKernelName.c_str());
291298
reportStackTrace(KTI.LaunchTrace);
292299
++I;
293300
}

offload/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ add_llvm_library(omptarget
2828
${LIBOMPTARGET_BINARY_INCLUDE_DIR}
2929

3030
LINK_COMPONENTS
31+
FrontendOpenMP
3132
Support
3233
Object
3334

offload/test/sanitizer/kernel_crash.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ int main(void) {
3636
}
3737
}
3838
// TRACE: Display 1 of the 3 last kernel launch traces
39-
// TRACE: Kernel 0: '__omp_offloading_{{.*}}_main_l30'
39+
// TRACE: Kernel 0: {{.*}} (__omp_offloading_{{.*}}_main_l30)
4040
// TRACE: launchKernel
4141
// NDEBG: main
4242
// DEBUG: main {{.*}}kernel_crash.c:30
4343
//
4444
// CHECK: Display last 3 kernels launched:
45-
// CHECK: Kernel 0: '__omp_offloading_{{.*}}_main_l30'
46-
// CHECK: Kernel 1: '__omp_offloading_{{.*}}_main_l27'
47-
// CHECK: Kernel 2: '__omp_offloading_{{.*}}_main_l24'
45+
// CHECK: Kernel 0: {{.*}} (__omp_offloading_{{.*}}_main_l30)
46+
// CHECK: Kernel 1: {{.*}} (__omp_offloading_{{.*}}_main_l27)
47+
// CHECK: Kernel 2: {{.*}} (__omp_offloading_{{.*}}_main_l24)

offload/test/sanitizer/kernel_crash_async.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ int main(void) {
3434
#pragma omp taskwait
3535
}
3636

37-
// TRACE: Kernel {{.*}}'__omp_offloading_{{.*}}_main_
37+
// TRACE: Kernel {{.*}} (__omp_offloading_{{.*}}_main_l30)
3838
// TRACE: launchKernel
3939
//
40-
// CHECK-DAG: Kernel {{[0-9]}}: '__omp_offloading_{{.*}}_main_l30'
40+
// CHECK: Kernel {{[0-9]}}: {{.*}} (__omp_offloading_{{.*}}_main_l30)

offload/test/sanitizer/kernel_crash_many.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,42 +30,42 @@ int main(void) {
3030
}
3131
}
3232
// CHECK: Display 8 of the 8 last kernel launch traces
33-
// CHECK: Kernel 0: '__omp_offloading_{{.*}}_main_l27'
33+
// CHECK: Kernel 0: {{.*}} (__omp_offloading_{{.*}}_main_l27)
3434
// CHECK: launchKernel
3535
// NDEBG: main
3636
// DEBUG: main {{.*}}kernel_crash_many.c:27
3737
//
38-
// CHECK: Kernel 1: '__omp_offloading_{{.*}}_main_l23'
38+
// CHECK: Kernel 1: {{.*}} (__omp_offloading_{{.*}}_main_l23)
3939
// CHECK: launchKernel
4040
// NDEBG: main
4141
// DEBUG: main {{.*}}kernel_crash_many.c:
4242
//
43-
// CHECK: Kernel 2: '__omp_offloading_{{.*}}_main_l23'
43+
// CHECK: Kernel 2: {{.*}} (__omp_offloading_{{.*}}_main_l23)
4444
// CHECK: launchKernel
4545
// NDEBG: main
4646
// DEBUG: main {{.*}}kernel_crash_many.c:
4747
//
48-
// CHECK: Kernel 3: '__omp_offloading_{{.*}}_main_l23'
48+
// CHECK: Kernel 3: {{.*}} (__omp_offloading_{{.*}}_main_l23)
4949
// CHECK: launchKernel
5050
// NDEBG: main
5151
// DEBUG: main {{.*}}kernel_crash_many.c:
5252
//
53-
// CHECK: Kernel 4: '__omp_offloading_{{.*}}_main_l23'
53+
// CHECK: Kernel 4: {{.*}} (__omp_offloading_{{.*}}_main_l23)
5454
// CHECK: launchKernel
5555
// NDEBG: main
5656
// DEBUG: main {{.*}}kernel_crash_many.c:
5757
//
58-
// CHECK: Kernel 5: '__omp_offloading_{{.*}}_main_l23'
58+
// CHECK: Kernel 5: {{.*}} (__omp_offloading_{{.*}}_main_l23)
5959
// CHECK: launchKernel
6060
// NDEBG: main
6161
// DEBUG: main {{.*}}kernel_crash_many.c:
6262
//
63-
// CHECK: Kernel 6: '__omp_offloading_{{.*}}_main_l23'
63+
// CHECK: Kernel 6: {{.*}} (__omp_offloading_{{.*}}_main_l23)
6464
// CHECK: launchKernel
6565
// NDEBG: main
6666
// DEBUG: main {{.*}}kernel_crash_many.c:
6767
//
68-
// CHECK: Kernel 7: '__omp_offloading_{{.*}}_main_l23'
68+
// CHECK: Kernel 7: {{.*}} (__omp_offloading_{{.*}}_main_l23)
6969
// CHECK: launchKernel
7070
// NDEBG: main
7171
// DEBUG: main {{.*}}kernel_crash_many.c:

offload/test/sanitizer/kernel_crash_single.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ int main(void) {
2727
}
2828
}
2929
// TRACE: Display kernel launch trace
30-
// TRACE: Kernel '__omp_offloading_{{.*}}_main_l24'
30+
// TRACE: Kernel {{.*}} (__omp_offloading_{{.*}}_main_l24)
3131
// TRACE: launchKernel
3232
// NDEBG: main
3333
// DEBUG: main {{.*}}kernel_crash_single.c:24
3434
//
3535
// CHECK: Display only launched kernel:
36-
// CHECK: Kernel '__omp_offloading_{{.*}}_main_l24'
36+
// CHECK: Kernel {{.*}} (__omp_offloading_{{.*}}_main_l24)

offload/test/sanitizer/kernel_trap.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ int main(void) {
3535
{
3636
}
3737
}
38-
// CHECK: OFFLOAD ERROR: Kernel '__omp_offloading_{{.*}}_main_l30'
38+
// clang-format off
39+
// CHECK: OFFLOAD ERROR: Kernel 'omp target in main @ 30 (__omp_offloading_{{.*}}_main_l30)'
3940
// CHECK: OFFLOAD ERROR: execution interrupted by hardware trap instruction
4041
// TRACE: launchKernel
4142
// NDEBG: main
4243
// DEBUG: main {{.*}}kernel_trap.c:
44+
// clang-format on
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
2+
// clang-format off
3+
// RUN: %libomptarget-compilexx-generic
4+
// RUN: %not --crash env -u LLVM_DISABLE_SYMBOLIZATION OFFLOAD_TRACK_NUM_KERNEL_LAUNCH_TRACES=1 %libomptarget-run-generic 2>&1 | %fcheck-generic --check-prefixes=CHECK,TRACE,NDEBG
5+
// RUN: %not --crash %libomptarget-run-generic 2>&1 | %fcheck-generic --check-prefixes=CHECK
6+
// RUN: %libomptarget-compilexx-generic -g
7+
// RUN: %not --crash env -u LLVM_DISABLE_SYMBOLIZATION OFFLOAD_TRACK_NUM_KERNEL_LAUNCH_TRACES=1 %libomptarget-run-generic 2>&1 | %fcheck-generic --check-prefixes=CHECK,TRACE,DEBUG
8+
// RUN: %not --crash %libomptarget-run-generic 2>&1 | %fcheck-generic --check-prefixes=CHECK
9+
// clang-format on
10+
11+
// UNSUPPORTED: nvptx64-nvidia-cuda
12+
// UNSUPPORTED: nvptx64-nvidia-cuda-LTO
13+
// UNSUPPORTED: aarch64-unknown-linux-gnu
14+
// UNSUPPORTED: aarch64-unknown-linux-gnu-LTO
15+
// UNSUPPORTED: x86_64-pc-linux-gnu
16+
// UNSUPPORTED: x86_64-pc-linux-gnu-LTO
17+
// UNSUPPORTED: s390x-ibm-linux-gnu
18+
// UNSUPPORTED: s390x-ibm-linux-gnu-LTO
19+
20+
struct S {};
21+
22+
template <typename T> void cxx_function_name(int I, T *) {
23+
24+
#pragma omp target
25+
{
26+
}
27+
#pragma omp target
28+
{
29+
}
30+
#pragma omp target
31+
{
32+
__builtin_trap();
33+
}
34+
#pragma omp target
35+
{
36+
}
37+
}
38+
39+
int main(void) {
40+
struct S s;
41+
cxx_function_name(1, &s);
42+
}
43+
44+
// clang-format off
45+
// CHECK: OFFLOAD ERROR: Kernel 'omp target in void cxx_function_name<S>(int, S*) @ [[LINE:[0-9]+]] (__omp_offloading_{{.*}}__Z17cxx_function_nameI1SEviPT__l[[LINE]])'
46+
// CHECK: OFFLOAD ERROR: execution interrupted by hardware trap instruction
47+
// TRACE: launchKernel
48+
// NDEBG: cxx_function_name<S>(int, S*)
49+
// NDEBG: main
50+
// DEBUG: cxx_function_name<S>(int, S*) {{.*}}kernel_trap.cpp:
51+
// DEBUG: main {{.*}}kernel_trap.cpp:
52+
// clang-format on

offload/test/sanitizer/kernel_trap_async.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ int main(void) {
3434
#pragma omp taskwait
3535
}
3636

37-
// CHECK: OFFLOAD ERROR: Kernel '__omp_offloading_{{.*}}_main_l30'
37+
// clang-format off
38+
// CHECK: OFFLOAD ERROR: Kernel {{.*}} (__omp_offloading_{{.*}}_main_l30)
3839
// CHECK: OFFLOAD ERROR: execution interrupted by hardware trap instruction
3940
// TRACE: launchKernel
4041
// DEBUG: kernel_trap_async.c:
42+
// clang-format on

offload/test/sanitizer/kernel_trap_many.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ int main(void) {
2929
__builtin_trap();
3030
}
3131
}
32-
// TRACE: OFFLOAD ERROR: Kernel '__omp_offloading_{{.*}}_main_l27'
32+
// TRACE: OFFLOAD ERROR: Kernel {{.*}} (__omp_offloading_{{.*}}_main_l27)
3333
// TRACE: OFFLOAD ERROR: execution interrupted by hardware trap instruction
3434
// TRACE: launchKernel
3535
// NDEBG: main

0 commit comments

Comments
 (0)