scott.linder created this revision.
scott.linder added reviewers: yaxunl, kzhuravl, arsenm.
Herald added subscribers: cfe-commits, Anastasia, tpr, dstuttard, nhaehnle, 
wdng, jvesely.

Controls the visibility of non-kernel functions when compiling for AMDGPU 
targets. Defaults to the default value visibility (-fvisibility), and is set in 
the AMDGPU toolchain to be "hidden" if not set explicitly.

This is a more fine-grained knob than "-fvisibility hidden", and allows the 
default visibility of functions to be controlled independent of kernels. This 
is useful for languages like OpenCL where kernel symbols are externally 
visible, but function symbols are not.


Repository:
  rC Clang

https://reviews.llvm.org/D52891

Files:
  include/clang/Basic/LangOptions.def
  include/clang/Driver/CC1Options.td
  include/clang/Driver/Options.td
  lib/CodeGen/TargetInfo.cpp
  lib/Driver/ToolChains/AMDGPU.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/visibility-amdgpu-non-kernel-functions.cl
  test/Driver/amdgpu-visibility.cl

Index: test/Driver/amdgpu-visibility.cl
===================================================================
--- test/Driver/amdgpu-visibility.cl
+++ test/Driver/amdgpu-visibility.cl
@@ -1,7 +1,11 @@
 // RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm %s 2>&1 | FileCheck -check-prefix=DEFAULT %s
-// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility=protected  %s 2>&1 | FileCheck -check-prefix=OVERRIDE-PROTECTED  %s
-// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility-ms-compat  %s 2>&1 | FileCheck -check-prefix=OVERRIDE-MS  %s
+// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility=hidden %s 2>&1 | FileCheck -check-prefix=VISIBILITY-HIDDEN %s
+// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility-amdgpu-non-kernel-functions=hidden  %s 2>&1 | FileCheck -check-prefix=AMDGPU-HIDDEN  %s
+// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility-amdgpu-non-kernel-functions=default  %s 2>&1 | FileCheck -check-prefix=AMDGPU-DEFAULT  %s
+// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility=hidden -fvisibility-amdgpu-non-kernel-functions=default  %s 2>&1 | FileCheck -check-prefix=VISIBILITY-HIDDEN-AMDGPU-DEFAULT  %s
 
-// DEFAULT: "-fvisibility" "hidden"
-// OVERRIDE-PROTECTED: "-fvisibility" "protected"
-// OVERRIDE-MS:  "-fvisibility" "hidden" "-ftype-visibility" "default"
+// DEFAULT: "-fvisibility-amdgpu-non-kernel-functions" "hidden"
+// VISIBILITY-HIDDEN: "-fvisibility-amdgpu-non-kernel-functions" "hidden"
+// AMDGPU-HIDDEN: "-fvisibility-amdgpu-non-kernel-functions" "hidden"
+// AMDGPU-DEFAULT: "-fvisibility-amdgpu-non-kernel-functions" "default"
+// VISIBILITY-HIDDEN-AMDGPU-DEFAULT: "-fvisibility-amdgpu-non-kernel-functions" "default"
Index: test/CodeGen/visibility-amdgpu-non-kernel-functions.cl
===================================================================
--- /dev/null
+++ test/CodeGen/visibility-amdgpu-non-kernel-functions.cl
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fvisibility hidden -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck --check-prefix=FVIS_HIDDEN %s
+// RUN: %clang_cc1 -fvisibility-amdgpu-non-kernel-functions hidden -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck --check-prefix=FVIS_AMDGPU_HIDDEN %s
+// RUN: %clang_cc1 -fvisibility-amdgpu-non-kernel-functions default -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck --check-prefix=FVIS_AMDGPU_DEFAULT %s
+// RUN: %clang_cc1 -fvisibility hidden -fvisibility-amdgpu-non-kernel-functions default -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck --check-prefix=FVIS_AMDGPU_OVERRIDE %s
+
+// FVIS_HIDDEN: define hidden amdgpu_kernel void @kern()
+// FVIS_AMDGPU_HIDDEN: define amdgpu_kernel void @kern()
+// FVIS_AMDGPU_DEFAULT: define amdgpu_kernel void @kern()
+// FVIS_AMDGPU_OVERRIDE: define hidden amdgpu_kernel void @kern()
+kernel void kern() {}
+// FVIS_HIDDEN: define amdgpu_kernel void @default_kern()
+// FVIS_AMDGPU_HIDDEN: define amdgpu_kernel void @default_kern()
+// FVIS_AMDGPU_DEFAULT: define amdgpu_kernel void @default_kern()
+// FVIS_AMDGPU_OVERRIDE: define amdgpu_kernel void @default_kern()
+__attribute__((visibility("default"))) kernel void default_kern() {}
+// FVIS_HIDDEN: define hidden amdgpu_kernel void @hidden_kern()
+// FVIS_AMDGPU_HIDDEN: define hidden amdgpu_kernel void @hidden_kern()
+// FVIS_AMDGPU_DEFAULT: define hidden amdgpu_kernel void @hidden_kern()
+// FVIS_AMDGPU_OVERRIDE: define hidden amdgpu_kernel void @hidden_kern()
+__attribute__((visibility("hidden"))) kernel void hidden_kern() {}
+// FVIS_HIDDEN: define protected amdgpu_kernel void @protected_kern()
+// FVIS_AMDGPU_HIDDEN: define protected amdgpu_kernel void @protected_kern()
+// FVIS_AMDGPU_DEFAULT: define protected amdgpu_kernel void @protected_kern()
+// FVIS_AMDGPU_OVERRIDE: define protected amdgpu_kernel void @protected_kern()
+__attribute__((visibility("protected"))) kernel void protected_kern() {}
+
+// FVIS_HIDDEN: define hidden void @func()
+// FVIS_AMDGPU_HIDDEN: define hidden void @func()
+// FVIS_AMDGPU_DEFAULT: define void @func()
+// FVIS_AMDGPU_OVERRIDE: define void @func()
+void func() {}
+// FVIS_HIDDEN: define void @default_func()
+// FVIS_AMDGPU_HIDDEN: define void @default_func()
+// FVIS_AMDGPU_DEFAULT: define void @default_func()
+// FVIS_AMDGPU_OVERRIDE: define void @default_func()
+__attribute__((visibility("default"))) void default_func() {}
+// FVIS_HIDDEN: define hidden void @hidden_func()
+// FVIS_AMDGPU_HIDDEN: define hidden void @hidden_func()
+// FVIS_AMDGPU_DEFAULT: define hidden void @hidden_func()
+// FVIS_AMDGPU_OVERRIDE: define hidden void @hidden_func()
+__attribute__((visibility("hidden"))) void hidden_func() {}
+// FVIS_HIDDEN: define protected void @protected_func()
+// FVIS_AMDGPU_HIDDEN: define protected void @protected_func()
+// FVIS_AMDGPU_DEFAULT: define protected void @protected_func()
+// FVIS_AMDGPU_OVERRIDE: define protected void @protected_func()
+__attribute__((visibility("protected"))) void protected_func() {}
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2310,6 +2310,17 @@
     Opts.setTypeVisibilityMode(Opts.getValueVisibilityMode());
   }
 
+  // The amdgpu-non-kernel-function-visibility mode defaults to the
+  // value-visibility mode.
+  if (Arg *amdgpuVisOpt =
+          Args.getLastArg(OPT_fvisibility_amdgpu_non_kernel_functions)) {
+    Opts.setAMDGPUNonKernelFunctionVisibilityMode(
+        parseVisibility(amdgpuVisOpt, Args, Diags));
+  } else {
+    Opts.setAMDGPUNonKernelFunctionVisibilityMode(
+        Opts.getValueVisibilityMode());
+  }
+
   if (Args.hasArg(OPT_fvisibility_inlines_hidden))
     Opts.InlineVisibilityHidden = 1;
 
Index: lib/Driver/ToolChains/Clang.cpp
===================================================================
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -4167,6 +4167,12 @@
     }
   }
 
+  if (const Arg *A = Args.getLastArg(
+          options::OPT_fvisibility_amdgpu_non_kernel_functions_EQ)) {
+    CmdArgs.push_back("-fvisibility-amdgpu-non-kernel-functions");
+    CmdArgs.push_back(A->getValue());
+  }
+
   Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
 
   Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
Index: lib/Driver/ToolChains/AMDGPU.cpp
===================================================================
--- lib/Driver/ToolChains/AMDGPU.cpp
+++ lib/Driver/ToolChains/AMDGPU.cpp
@@ -105,9 +105,8 @@
     Action::OffloadKind DeviceOffloadingKind) const {
   // Default to "hidden" visibility, as object level linking will not be
   // supported for the forseeable future.
-  if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ,
-                         options::OPT_fvisibility_ms_compat)) {
-    CC1Args.push_back("-fvisibility");
-    CC1Args.push_back("hidden");
+  if (!DriverArgs.hasArg(options::OPT_fvisibility_amdgpu_non_kernel_functions_EQ,
+                         options::OPT_fvisibility_amdgpu_non_kernel_functions)) {
+    CC1Args.append({"-fvisibility-amdgpu-non-kernel-functions", "hidden"});
   }
 }
Index: lib/CodeGen/TargetInfo.cpp
===================================================================
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -7734,6 +7734,13 @@
 
   llvm::Function *F = cast<llvm::Function>(GV);
 
+  if (!FD->getExplicitVisibility(FunctionDecl::VisibilityForValue) &&
+      F->getCallingConv() != llvm::CallingConv::AMDGPU_KERNEL) {
+    GV->setVisibility(M.GetLLVMVisibility(
+        M.getLangOpts().getAMDGPUNonKernelFunctionVisibilityMode()));
+    M.setDSOLocal(GV);
+  }
+
   const auto *ReqdWGS = M.getLangOpts().OpenCL ?
     FD->getAttr<ReqdWorkGroupSizeAttr>() : nullptr;
 
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -1711,6 +1711,8 @@
 def fverbose_asm : Flag<["-"], "fverbose-asm">, Group<f_Group>;
 def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group<f_Group>,
   HelpText<"Set the default symbol visibility for all global declarations">, Values<"hidden,default">;
+def fvisibility_amdgpu_non_kernel_functions_EQ : Joined<["-"], "fvisibility-amdgpu-non-kernel-functions=">, Group<f_Group>,
+  HelpText<"Set the default symbol visibility for non-kernel function declarations">, Values<"hidden,default">;
 def fvisibility_inlines_hidden : Flag<["-"], "fvisibility-inlines-hidden">, Group<f_Group>,
   HelpText<"Give inline C++ member functions hidden visibility by default">,
   Flags<[CC1Option]>;
Index: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td
+++ include/clang/Driver/CC1Options.td
@@ -679,6 +679,8 @@
   HelpText<"Lower bound for a buffer to be considered for stack protection">;
 def fvisibility : Separate<["-"], "fvisibility">,
   HelpText<"Default type and symbol visibility">;
+def fvisibility_amdgpu_non_kernel_functions : Separate<["-"], "fvisibility-amdgpu-non-kernel-functions">,
+  HelpText<"Default non-kernel function symbol visibility">;
 def ftype_visibility : Separate<["-"], "ftype-visibility">,
   HelpText<"Default type visibility">;
 def ftemplate_depth : Separate<["-"], "ftemplate-depth">,
Index: include/clang/Basic/LangOptions.def
===================================================================
--- include/clang/Basic/LangOptions.def
+++ include/clang/Basic/LangOptions.def
@@ -258,6 +258,8 @@
              "value symbol visibility")
 ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility,
              "type symbol visibility")
+ENUM_LANGOPT(AMDGPUNonKernelFunctionVisibilityMode, Visibility, 3,
+             DefaultVisibility, "non-kernel function visibility")
 ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,
              "stack protector mode")
 ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to