[clang] bb3c90d - [OpenMP] Make device functions have hidden visibility

Joseph Huber via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 18 06:15:46 PDT 2022


Author: Joseph Huber
Date: 2022-10-18T08:15:39-05:00
New Revision: bb3c90d3ecd142e60cf994338bdd4b59d8788cd3

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

LOG: [OpenMP] Make device functions have hidden visibility

In OpenMP target offloading an in other offloading languages, we
maintain a difference between device functions and kernel functions.
Kernel functions must be visible to the host and act as the entry point
to the target device. Device functions however cannot be called directly
by the host and must be called by a kernel function. Currently, we make
all definitions on the device protected by default. Because device
functions cannot be called or used by the host they should have hidden
visibility. This allows for the definitions to be better optimized via
LTO or other passes.

This patch marks every device function in the AST as having `hidden`
visibility. The kernel function is generated later at code-gen and we
set its visibility explicitly so it should not be affected. This
prevents the user from overriding the visibility, but since the user
can't do anything with these symbols anyway there is no point exporting
them right now.

Reviewed By: jdoerfert

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

Added: 
    

Modified: 
    clang/lib/AST/Decl.cpp
    clang/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp
    clang/test/OpenMP/nvptx_unsupported_type_codegen.cpp
    clang/test/OpenMP/target_attribute_convergent.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index d1dd93b0a5b6b..510910b34fadc 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -835,6 +835,15 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
     if (Function->getStorageClass() == SC_PrivateExtern)
       LV.mergeVisibility(HiddenVisibility, true);
 
+    // OpenMP target declare device functions are not callable from the host so
+    // they should not be exported from the device image. This applies to all
+    // functions as the host-callable kernel functions are emitted at codegen.
+    if (Context.getLangOpts().OpenMP && Context.getLangOpts().OpenMPIsDevice &&
+        ((Context.getTargetInfo().getTriple().isAMDGPU() ||
+          Context.getTargetInfo().getTriple().isNVPTX()) ||
+         OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(Function)))
+      LV.mergeVisibility(HiddenVisibility, /*newExplicit=*/false);
+
     // Note that Sema::MergeCompatibleFunctionDecls already takes care of
     // merging storage classes and visibility attributes, so we don't have to
     // look at previous decls in here.

diff  --git a/clang/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp b/clang/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp
index 7f6f9a0bc5b9a..c38e958f74f36 100644
--- a/clang/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp
+++ b/clang/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp
@@ -34,12 +34,12 @@ int car() { return 0; }
 #pragma omp declare target (bar)
 int caz() { return 0; }
 
-// DEVICE-DAG: define{{ protected | }}noundef i32 [[FOO:@.*foo.*]]()
-// DEVICE-DAG: define{{ protected | }}noundef i32 [[BAR:@.*bar.*]]()
-// DEVICE-DAG: define{{ protected | }}noundef i32 [[BAZ:@.*baz.*]]()
-// DEVICE-DAG: define{{ protected | }}noundef i32 [[DOO:@.*doo.*]]()
-// DEVICE-DAG: define{{ protected | }}noundef i32 [[CAR:@.*car.*]]()
-// DEVICE-DAG: define{{ protected | }}noundef i32 [[CAZ:@.*caz.*]]()
+// DEVICE-DAG: define hidden noundef i32 [[FOO:@.*foo.*]]()
+// DEVICE-DAG: define hidden noundef i32 [[BAR:@.*bar.*]]()
+// DEVICE-DAG: define hidden noundef i32 [[BAZ:@.*baz.*]]()
+// DEVICE-DAG: define hidden noundef i32 [[DOO:@.*doo.*]]()
+// DEVICE-DAG: define hidden noundef i32 [[CAR:@.*car.*]]()
+// DEVICE-DAG: define hidden noundef i32 [[CAZ:@.*caz.*]]()
 
 static int c = foo() + bar() + baz();
 #pragma omp declare target (c)

diff  --git a/clang/test/OpenMP/nvptx_unsupported_type_codegen.cpp b/clang/test/OpenMP/nvptx_unsupported_type_codegen.cpp
index cfc86359de947..1db4f26f0c811 100644
--- a/clang/test/OpenMP/nvptx_unsupported_type_codegen.cpp
+++ b/clang/test/OpenMP/nvptx_unsupported_type_codegen.cpp
@@ -34,18 +34,18 @@ struct T1 {
 #pragma omp declare target
 T a = T();
 T f = a;
-// CHECK: define{{ protected | }}void @{{.+}}foo{{.+}}([[T]]* noundef byval([[T]]) align {{.+}})
+// CHECK: define{{ hidden | }}void @{{.+}}foo{{.+}}([[T]]* noundef byval([[T]]) align {{.+}})
 void foo(T a = T()) {
   return;
 }
-// CHECK: define{{ protected | }}[6 x i64] @{{.+}}bar{{.+}}()
+// CHECK: define{{ hidden | }}[6 x i64] @{{.+}}bar{{.+}}()
 T bar() {
 // CHECK:      bitcast [[T]]* %{{.+}} to [6 x i64]*
 // CHECK-NEXT: load [6 x i64], [6 x i64]* %{{.+}},
 // CHECK-NEXT: ret [6 x i64]
   return T();
 }
-// CHECK: define{{ protected | }}void @{{.+}}baz{{.+}}()
+// CHECK: define{{ hidden | }}void @{{.+}}baz{{.+}}()
 void baz() {
 // CHECK:      call [6 x i64] @{{.+}}bar{{.+}}()
 // CHECK-NEXT: bitcast [[T]]* %{{.+}} to [6 x i64]*
@@ -54,17 +54,17 @@ void baz() {
 }
 T1 a1 = T1();
 T1 f1 = a1;
-// CHECK: define{{ protected | }}void @{{.+}}foo1{{.+}}([[T1]]* noundef byval([[T1]]) align {{.+}})
+// CHECK: define{{ hidden | }}void @{{.+}}foo1{{.+}}([[T1]]* noundef byval([[T1]]) align {{.+}})
 void foo1(T1 a = T1()) {
   return;
 }
-// CHECK: define{{ protected | }}[[T1]] @{{.+}}bar1{{.+}}()
+// CHECK: define{{ hidden | }}[[T1]] @{{.+}}bar1{{.+}}()
 T1 bar1() {
 // CHECK:      load [[T1]], [[T1]]*
 // CHECK-NEXT: ret [[T1]]
   return T1();
 }
-// CHECK: define{{ protected | }}void @{{.+}}baz1{{.+}}()
+// CHECK: define{{ hidden | }}void @{{.+}}baz1{{.+}}()
 void baz1() {
 // CHECK: call [[T1]] @{{.+}}bar1{{.+}}()
   T1 t = bar1();

diff  --git a/clang/test/OpenMP/target_attribute_convergent.cpp b/clang/test/OpenMP/target_attribute_convergent.cpp
index 7a3a87c10049b..107436ae37eb1 100644
--- a/clang/test/OpenMP/target_attribute_convergent.cpp
+++ b/clang/test/OpenMP/target_attribute_convergent.cpp
@@ -9,5 +9,5 @@ void foo() {}
 #pragma omp end declare target
 
 // CHECK: Function Attrs: {{.*}}convergent{{.*}}
-// CHECK: define protected void @_Z3foov() [[ATTRIBUTE_NUMBER:#[0-9]+]]
+// CHECK: define hidden void @_Z3foov() [[ATTRIBUTE_NUMBER:#[0-9]+]]
 // CHECK: attributes [[ATTRIBUTE_NUMBER]] = { {{.*}}convergent{{.*}} }


        


More information about the cfe-commits mailing list