[clang] a48300a - [clang][OpenMP][DebugInfo] Debug support for TLS variables present in OpenMP consruct

Alok Kumar Sharma via cfe-commits cfe-commits at lists.llvm.org
Sat Apr 23 00:00:21 PDT 2022


Author: Alok Kumar Sharma
Date: 2022-04-23T12:29:32+05:30
New Revision: a48300aee570f8eea4ec0b03e2d176aab648afb0

URL: https://github.com/llvm/llvm-project/commit/a48300aee570f8eea4ec0b03e2d176aab648afb0
DIFF: https://github.com/llvm/llvm-project/commit/a48300aee570f8eea4ec0b03e2d176aab648afb0.diff

LOG: [clang][OpenMP][DebugInfo] Debug support for TLS variables present in OpenMP consruct

In case of OpenMP programs, thread local variables can be present in
any clause pertaining to OpenMP constructs, as we know that compiler
generates artificial functions and in some cases values are passed to
those artificial functions thru parameters. For an example, if thread
local variable is present in copyin clause (testcase attached with the
patch), parameter with same name is generated as parameter to artificial
function. When user inquires the thread Local variable, its debug info
is hidden by the parameter. User never gets the actual TLS variable
when inquires it, instead gets the artificial parameter.

Current patch suppresses the debug info for such artificial parameter to
enable correct debugging of TLS variables.

Reviewed By: aprantl

Differential Revision: https://reviews.llvm.org/D123787

Added: 
    clang/test/OpenMP/debug_threadprivate_copyin.c

Modified: 
    clang/include/clang/AST/Decl.h
    clang/lib/CodeGen/CGDecl.cpp
    clang/lib/CodeGen/CGStmtOpenMP.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index f93008cdd322d..04101c3218d71 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -1633,6 +1633,9 @@ class ImplicitParamDecl : public VarDecl {
     /// Parameter for captured context
     CapturedContext,
 
+    /// Parameter for Thread private variable
+    ThreadPrivateVar,
+
     /// Other implicit parameter
     Other,
   };

diff  --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index e47450f2ba8fe..0f16c7f50a003 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -2442,6 +2442,7 @@ namespace {
 /// for the specified parameter and set up LocalDeclMap.
 void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
                                    unsigned ArgNo) {
+  bool NoDebugInfo = false;
   // FIXME: Why isn't ImplicitParamDecl a ParmVarDecl?
   assert((isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)) &&
          "Invalid argument to EmitParmDecl");
@@ -2461,6 +2462,10 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
       setBlockContextParameter(IPD, ArgNo, V);
       return;
     }
+    // Suppressing debug info for ThreadPrivateVar parameters, else it hides
+    // debug info of TLS variables.
+    NoDebugInfo =
+        (IPD->getParameterKind() == ImplicitParamDecl::ThreadPrivateVar);
   }
 
   Address DeclPtr = Address::invalid();
@@ -2591,7 +2596,8 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
 
   // Emit debug info for param declarations in non-thunk functions.
   if (CGDebugInfo *DI = getDebugInfo()) {
-    if (CGM.getCodeGenOpts().hasReducedDebugInfo() && !CurFuncIsThunk) {
+    if (CGM.getCodeGenOpts().hasReducedDebugInfo() && !CurFuncIsThunk &&
+        !NoDebugInfo) {
       llvm::DILocalVariable *DILocalVar = DI->EmitDeclareOfArgVariable(
           &D, AllocaPtr.getPointer(), ArgNo, Builder);
       if (const auto *Var = dyn_cast_or_null<ParmVarDecl>(&D))

diff  --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index a249ef9d58d97..7c0001594a33e 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -481,7 +481,11 @@ static llvm::Function *emitOutlinedFunctionPrologue(
     if (ArgType->isVariablyModifiedType())
       ArgType = getCanonicalParamType(Ctx, ArgType);
     VarDecl *Arg;
-    if (DebugFunctionDecl && (CapVar || I->capturesThis())) {
+    if (CapVar && (CapVar->getTLSKind() != clang::VarDecl::TLS_None)) {
+      Arg = ImplicitParamDecl::Create(Ctx, /*DC=*/nullptr, FD->getLocation(),
+                                      II, ArgType,
+                                      ImplicitParamDecl::ThreadPrivateVar);
+    } else if (DebugFunctionDecl && (CapVar || I->capturesThis())) {
       Arg = ParmVarDecl::Create(
           Ctx, DebugFunctionDecl,
           CapVar ? CapVar->getBeginLoc() : FD->getBeginLoc(),

diff  --git a/clang/test/OpenMP/debug_threadprivate_copyin.c b/clang/test/OpenMP/debug_threadprivate_copyin.c
new file mode 100644
index 0000000000000..bb0b76d5242a4
--- /dev/null
+++ b/clang/test/OpenMP/debug_threadprivate_copyin.c
@@ -0,0 +1,59 @@
+// This testcase checks emission of debug info for threadprivate variables
+// present in any clause of OpenMP construct.
+
+// REQUIRES: x86_64-linux
+
+// RUN: %clang_cc1 -debug-info-kind=constructor -x c -verify -triple x86_64-pc-linux-gnu -fopenmp -emit-llvm %s -o - | FileCheck %s
+// expected-no-diagnostics
+
+// CHECK: define internal void @.omp_outlined._debug__(
+// CHECK: call void @llvm.dbg.declare(metadata ptr %.global_tid..addr,
+// CHECK: call void @llvm.dbg.declare(metadata ptr %.bound_tid..addr,
+// CHECK: call void @llvm.dbg.declare(metadata ptr %nt.addr
+// CHECK: store ptr %gbl_dynamic_int, ptr %gbl_dynamic_int.addr, align 8
+// CHECK-NOT: call void @llvm.dbg.declare(metadata ptr %gbl_dynamic_int.addr
+// CHECK-NOT: call void @llvm.dbg.declare(metadata ptr %gbl_static_int.addr
+
+extern int printf(const char *, ...);
+extern void omp_set_num_threads(int);
+extern int omp_get_num_threads(void);
+extern int omp_get_thread_num(void);
+
+int gbl_dynamic_int;
+__thread int gbl_static_int;
+
+#pragma omp threadprivate(gbl_dynamic_int)
+
+int main() {
+  int nt = 0;
+  int offset = 10;
+  gbl_dynamic_int = 55;
+  gbl_static_int = 77;
+
+  omp_set_num_threads(4);
+#pragma omp parallel copyin(gbl_dynamic_int, gbl_static_int)
+  {
+    int data;
+    int tid;
+    nt = omp_get_num_threads();
+    tid = omp_get_thread_num();
+    data = gbl_dynamic_int + gbl_static_int;
+    gbl_dynamic_int += 10;
+    gbl_static_int += 20;
+#pragma omp barrier
+    if (tid == 0)
+      printf("In parallel region total threads = %d, thread id = %d data=%d gbl_dyn_addr = %p, gbl_static_addr = %p\n",
+             nt, tid, data, &gbl_dynamic_int, &gbl_static_int);
+    if (tid == 1)
+      printf("In parallel region total threads = %d, thread id = %d data=%d gbl_dyn_addr = %p, gbl_static_addr = %p\n",
+             nt, tid, data, &gbl_dynamic_int, &gbl_static_int);
+    if (tid == 2)
+      printf("In parallel region total threads = %d, thread id = %d data=%d gbl_dyn_addr = %p, gbl_static_addr = %p\n",
+             nt, tid, data, &gbl_dynamic_int, &gbl_static_int);
+    if (tid == 3)
+      printf("In parallel region total threads = %d, thread id = %d data=%d gbl_dyn_addr = %p, gbl_static_addr = %p\n",
+             nt, tid, data, &gbl_dynamic_int, &gbl_static_int);
+  }
+
+  return 0;
+}


        


More information about the cfe-commits mailing list