[PATCH] D98814: [CUDA][HIP] Mark device var used by host only

2021-04-17 Thread Yaxun Liu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
yaxunl marked 2 inline comments as done.
Closed by commit rGd5c0f00e216a: [CUDA][HIP] Mark device var used by host only 
(authored by yaxunl).
Herald added a project: clang.

Changed prior to commit:
  https://reviews.llvm.org/D98814?vs=332157=338313#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98814/new/

https://reviews.llvm.org/D98814

Files:
  clang/lib/CodeGen/CGCUDANV.cpp
  clang/test/CodeGenCUDA/host-used-device-var.cu


Index: clang/test/CodeGenCUDA/host-used-device-var.cu
===
--- /dev/null
+++ clang/test/CodeGenCUDA/host-used-device-var.cu
@@ -0,0 +1,47 @@
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fcuda-is-device -x hip %s \
+// RUN:   -std=c++11 -O3 -mllvm -amdgpu-internalize-symbols -emit-llvm -o - \
+// RUN:   | FileCheck %s
+
+#include "Inputs/cuda.h"
+
+// Check device variables used by neither host nor device functioins are not 
kept.
+
+// CHECK-NOT: @v1
+__device__ int v1;
+
+// CHECK-NOT: @v2
+__constant__ int v2;
+
+// CHECK-NOT: @_ZL2v3
+static __device__ int v3;
+
+// Check device variables used by host functions are kept.
+
+// CHECK-DAG: @u1
+__device__ int u1;
+
+// CHECK-DAG: @u2
+__constant__ int u2;
+
+// Check host-used static device var is in llvm.compiler.used.
+// CHECK-DAG: @_ZL2u3
+static __device__ int u3;
+
+// Check device-used static device var is emitted but is not in 
llvm.compiler.used.
+// CHECK-DAG: @_ZL2u4
+static __device__ int u4;
+
+// Check device variables with used attribute are always kept.
+// CHECK-DAG: @u5
+__device__ __attribute__((used)) int u5;
+
+int fun1() {
+  return u1 + u2 + u3;
+}
+
+__global__ void kern1(int **x) {
+  *x = 
+}
+// Check the exact list of variables to ensure @_ZL2u4 is not among them.
+// CHECK: @llvm.compiler.used = {{[^@]*}} @_ZL2u3 {{[^@]*}} @u1 {{[^@]*}} @u2 
{{[^@]*}} @u5
Index: clang/lib/CodeGen/CGCUDANV.cpp
===
--- clang/lib/CodeGen/CGCUDANV.cpp
+++ clang/lib/CodeGen/CGCUDANV.cpp
@@ -1089,6 +1089,28 @@
 llvm::Function *CGNVCUDARuntime::finalizeModule() {
   if (CGM.getLangOpts().CUDAIsDevice) {
 transformManagedVars();
+
+// Mark ODR-used device variables as compiler used to prevent it from being
+// eliminated by optimization. This is necessary for device variables
+// ODR-used by host functions. Sema correctly marks them as ODR-used no
+// matter whether they are ODR-used by device or host functions.
+//
+// We do not need to do this if the variable has used attribute since it
+// has already been added.
+//
+// Static device variables have been externalized at this point, therefore
+// variables with LLVM private or internal linkage need not be added.
+for (auto & : DeviceVars) {
+  auto Kind = Info.Flags.getKind();
+  if (!Info.Var->isDeclaration() &&
+  !llvm::GlobalValue::isLocalLinkage(Info.Var->getLinkage()) &&
+  (Kind == DeviceVarFlags::Variable ||
+   Kind == DeviceVarFlags::Surface ||
+   Kind == DeviceVarFlags::Texture) &&
+  Info.D->isUsed() && !Info.D->hasAttr()) {
+CGM.addCompilerUsedGlobal(Info.Var);
+  }
+}
 return nullptr;
   }
   return makeModuleCtorFunction();


Index: clang/test/CodeGenCUDA/host-used-device-var.cu
===
--- /dev/null
+++ clang/test/CodeGenCUDA/host-used-device-var.cu
@@ -0,0 +1,47 @@
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fcuda-is-device -x hip %s \
+// RUN:   -std=c++11 -O3 -mllvm -amdgpu-internalize-symbols -emit-llvm -o - \
+// RUN:   | FileCheck %s
+
+#include "Inputs/cuda.h"
+
+// Check device variables used by neither host nor device functioins are not kept.
+
+// CHECK-NOT: @v1
+__device__ int v1;
+
+// CHECK-NOT: @v2
+__constant__ int v2;
+
+// CHECK-NOT: @_ZL2v3
+static __device__ int v3;
+
+// Check device variables used by host functions are kept.
+
+// CHECK-DAG: @u1
+__device__ int u1;
+
+// CHECK-DAG: @u2
+__constant__ int u2;
+
+// Check host-used static device var is in llvm.compiler.used.
+// CHECK-DAG: @_ZL2u3
+static __device__ int u3;
+
+// Check device-used static device var is emitted but is not in llvm.compiler.used.
+// CHECK-DAG: @_ZL2u4
+static __device__ int u4;
+
+// Check device variables with used attribute are always kept.
+// CHECK-DAG: @u5
+__device__ __attribute__((used)) int u5;
+
+int fun1() {
+  return u1 + u2 + u3;
+}
+
+__global__ void kern1(int **x) {
+  *x = 
+}
+// Check the exact list of variables to ensure @_ZL2u4 is not among them.
+// CHECK: @llvm.compiler.used = {{[^@]*}} @_ZL2u3 {{[^@]*}} @u1 {{[^@]*}} @u2 {{[^@]*}} @u5
Index: clang/lib/CodeGen/CGCUDANV.cpp

[PATCH] D98814: [CUDA][HIP] Mark device var used by host only

2021-04-17 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl marked 2 inline comments as done.
yaxunl added inline comments.



Comment at: clang/test/CodeGenCUDA/host-used-device-var.cu:31-33
+// Check device-used static device var is not in llvm.compiler.used.
+// CHECK-DAG: @_ZL2u4
+static __device__ int u4;

tra wrote:
> I'd rephrase it as 'but is not in llvm.compiler.used'
> 
will do



Comment at: clang/test/CodeGenCUDA/host-used-device-var.cu:46
+}
+// CHECK: @llvm.compiler.used = {{[^@]*}} @_ZL2u3 {{[^@]*}} @u1 {{[^@]*}} @u2 
{{[^@]*}} @u5

tra wrote:
> I'd add a comment that we're effectively matching the exact list of the 
> variables here and that ensures that `@_ZL2u4` is not among them.
> 
will do


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98814/new/

https://reviews.llvm.org/D98814

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98814: [CUDA][HIP] Mark device var used by host only

2021-03-22 Thread Artem Belevich via Phabricator via cfe-commits
tra accepted this revision.
tra added inline comments.
This revision is now accepted and ready to land.



Comment at: clang/test/CodeGenCUDA/host-used-device-var.cu:31-33
+// Check device-used static device var is not in llvm.compiler.used.
+// CHECK-DAG: @_ZL2u4
+static __device__ int u4;

I'd rephrase it as 'but is not in llvm.compiler.used'




Comment at: clang/test/CodeGenCUDA/host-used-device-var.cu:46
+}
+// CHECK: @llvm.compiler.used = {{[^@]*}} @_ZL2u3 {{[^@]*}} @u1 {{[^@]*}} @u2 
{{[^@]*}} @u5

I'd add a comment that we're effectively matching the exact list of the 
variables here and that ensures that `@_ZL2u4` is not among them.



CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98814/new/

https://reviews.llvm.org/D98814

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98814: [CUDA][HIP] Mark device var used by host only

2021-03-21 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl updated this revision to Diff 332157.
yaxunl marked an inline comment as done.
yaxunl added a comment.

revised by Artem's comments


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98814/new/

https://reviews.llvm.org/D98814

Files:
  clang/lib/CodeGen/CGCUDANV.cpp
  clang/test/CodeGenCUDA/host-used-device-var.cu


Index: clang/test/CodeGenCUDA/host-used-device-var.cu
===
--- /dev/null
+++ clang/test/CodeGenCUDA/host-used-device-var.cu
@@ -0,0 +1,46 @@
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fcuda-is-device -x hip %s \
+// RUN:   -std=c++11 -O3 -mllvm -amdgpu-internalize-symbols -emit-llvm -o - \
+// RUN:   | FileCheck %s
+
+#include "Inputs/cuda.h"
+
+// Check device variables used by neither host nor device functioins are not 
kept.
+
+// CHECK-NOT: @v1
+__device__ int v1;
+
+// CHECK-NOT: @v2
+__constant__ int v2;
+
+// CHECK-NOT: @_ZL2v3
+static __device__ int v3;
+
+// Check device variables used by host functions are kept.
+
+// CHECK-DAG: @u1
+__device__ int u1;
+
+// CHECK-DAG: @u2
+__constant__ int u2;
+
+// Check host-used static device var is in llvm.compiler.used.
+// CHECK-DAG: @_ZL2u3
+static __device__ int u3;
+
+// Check device-used static device var is not in llvm.compiler.used.
+// CHECK-DAG: @_ZL2u4
+static __device__ int u4;
+
+// Check device variables with used attribute are always kept.
+// CHECK-DAG: @u5
+__device__ __attribute__((used)) int u5;
+
+int fun1() {
+  return u1 + u2 + u3;
+}
+
+__global__ void kern1(int **x) {
+  *x = 
+}
+// CHECK: @llvm.compiler.used = {{[^@]*}} @_ZL2u3 {{[^@]*}} @u1 {{[^@]*}} @u2 
{{[^@]*}} @u5
Index: clang/lib/CodeGen/CGCUDANV.cpp
===
--- clang/lib/CodeGen/CGCUDANV.cpp
+++ clang/lib/CodeGen/CGCUDANV.cpp
@@ -1084,6 +1084,28 @@
 llvm::Function *CGNVCUDARuntime::finalizeModule() {
   if (CGM.getLangOpts().CUDAIsDevice) {
 transformManagedVars();
+
+// Mark ODR-used device variables as compiler used to prevent it from being
+// eliminated by optimization. This is necessary for device variables
+// ODR-used by host functions. Sema correctly marks them as ODR-used no
+// matter whether they are ODR-used by device or host functions.
+//
+// We do not need to do this if the variable has used attribute since it
+// has already been added.
+//
+// Static device variables have been externalized at this point, therefore
+// variables with LLVM private or internal linkage need not be added.
+for (auto & : DeviceVars) {
+  auto Kind = Info.Flags.getKind();
+  if (!Info.Var->isDeclaration() &&
+  !llvm::GlobalValue::isLocalLinkage(Info.Var->getLinkage()) &&
+  (Kind == DeviceVarFlags::Variable ||
+   Kind == DeviceVarFlags::Surface ||
+   Kind == DeviceVarFlags::Texture) &&
+  Info.D->isUsed() && !Info.D->hasAttr()) {
+CGM.addCompilerUsedGlobal(Info.Var);
+  }
+}
 return nullptr;
   }
   return makeModuleCtorFunction();


Index: clang/test/CodeGenCUDA/host-used-device-var.cu
===
--- /dev/null
+++ clang/test/CodeGenCUDA/host-used-device-var.cu
@@ -0,0 +1,46 @@
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fcuda-is-device -x hip %s \
+// RUN:   -std=c++11 -O3 -mllvm -amdgpu-internalize-symbols -emit-llvm -o - \
+// RUN:   | FileCheck %s
+
+#include "Inputs/cuda.h"
+
+// Check device variables used by neither host nor device functioins are not kept.
+
+// CHECK-NOT: @v1
+__device__ int v1;
+
+// CHECK-NOT: @v2
+__constant__ int v2;
+
+// CHECK-NOT: @_ZL2v3
+static __device__ int v3;
+
+// Check device variables used by host functions are kept.
+
+// CHECK-DAG: @u1
+__device__ int u1;
+
+// CHECK-DAG: @u2
+__constant__ int u2;
+
+// Check host-used static device var is in llvm.compiler.used.
+// CHECK-DAG: @_ZL2u3
+static __device__ int u3;
+
+// Check device-used static device var is not in llvm.compiler.used.
+// CHECK-DAG: @_ZL2u4
+static __device__ int u4;
+
+// Check device variables with used attribute are always kept.
+// CHECK-DAG: @u5
+__device__ __attribute__((used)) int u5;
+
+int fun1() {
+  return u1 + u2 + u3;
+}
+
+__global__ void kern1(int **x) {
+  *x = 
+}
+// CHECK: @llvm.compiler.used = {{[^@]*}} @_ZL2u3 {{[^@]*}} @u1 {{[^@]*}} @u2 {{[^@]*}} @u5
Index: clang/lib/CodeGen/CGCUDANV.cpp
===
--- clang/lib/CodeGen/CGCUDANV.cpp
+++ clang/lib/CodeGen/CGCUDANV.cpp
@@ -1084,6 +1084,28 @@
 llvm::Function *CGNVCUDARuntime::finalizeModule() {
   if (CGM.getLangOpts().CUDAIsDevice) {
 transformManagedVars();
+
+// Mark ODR-used device variables as compiler used to prevent it from being
+// eliminated by optimization. This is necessary for device variables
+// ODR-used by host 

[PATCH] D98814: [CUDA][HIP] Mark device var used by host only

2021-03-21 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl marked an inline comment as done.
yaxunl added inline comments.



Comment at: clang/lib/CodeGen/CGCUDANV.cpp:1102
+  Info.D->isUsed() && !Info.D->hasAttr()) {
+CGM.addCompilerUsedGlobal(Info.Var);
+  }

tra wrote:
> Do we want to limit it further to only externally-visible variables?
> I think we already externalize the variables we want to be visible across 
> host/device boundary.
> If the variable is not visible, there's no point keeping it around as the 
> runtime will not be able to find it in the GPU binary.
Good point. Will do


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98814/new/

https://reviews.llvm.org/D98814

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98814: [CUDA][HIP] Mark device var used by host only

2021-03-17 Thread Artem Belevich via Phabricator via cfe-commits
tra added inline comments.



Comment at: clang/lib/CodeGen/CGCUDANV.cpp:1102
+  Info.D->isUsed() && !Info.D->hasAttr()) {
+CGM.addCompilerUsedGlobal(Info.Var);
+  }

Do we want to limit it further to only externally-visible variables?
I think we already externalize the variables we want to be visible across 
host/device boundary.
If the variable is not visible, there's no point keeping it around as the 
runtime will not be able to find it in the GPU binary.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98814/new/

https://reviews.llvm.org/D98814

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98814: [CUDA][HIP] Mark device var used by host only

2021-03-17 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl created this revision.
yaxunl added a reviewer: tra.
yaxunl requested review of this revision.

Add device variables to llvm.compiler.used if they are
ODR-used by either host or device functions.

This is necessary to prevent them from being
eliminated by whole-program optimization
where the compiler has no way to know a device
variable is used by some host code.


https://reviews.llvm.org/D98814

Files:
  clang/lib/CodeGen/CGCUDANV.cpp
  clang/test/CodeGenCUDA/host-used-device-var.cu


Index: clang/test/CodeGenCUDA/host-used-device-var.cu
===
--- /dev/null
+++ clang/test/CodeGenCUDA/host-used-device-var.cu
@@ -0,0 +1,33 @@
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fcuda-is-device -x hip %s \
+// RUN:   -std=c++11 -O3 -mllvm -amdgpu-internalize-symbols -emit-llvm -o - \
+// RUN:   | FileCheck %s
+
+#include "Inputs/cuda.h"
+
+// Check device variables used by neither host nor device functioins are not 
kept.
+
+// CHECK-NOT: @v1
+__device__ int v1;
+
+// CHECK-NOT: @v2
+__constant__ int v2;
+
+// Check device variables used by host functions are kept.
+
+// CHECK: @u1
+__device__ int u1;
+
+// CHECK: @u2
+__constant__ int u2;
+
+// Check device variables with used attribute are always kept.
+
+// CHECK: @u3
+__device__ __attribute__((used)) int u3;
+
+int fun1() {
+  return u1 + u2;
+}
+
+// CHECK: @llvm.compiler.used = {{[^@]*}} @u1 {{[^@]*}} @u2 {{[^@]*}} @u3
Index: clang/lib/CodeGen/CGCUDANV.cpp
===
--- clang/lib/CodeGen/CGCUDANV.cpp
+++ clang/lib/CodeGen/CGCUDANV.cpp
@@ -1084,6 +1084,24 @@
 llvm::Function *CGNVCUDARuntime::finalizeModule() {
   if (CGM.getLangOpts().CUDAIsDevice) {
 transformManagedVars();
+
+// Mark ODR-used device variables as compiler used to prevent it from being
+// eliminated by optimization. This is necessary for device variables
+// ODR-used by host functions. Sema correctly marks them as ODR-used no
+// matter whether they are ODR-used by device or host functions.
+//
+// We do not need to do this if the variable has used attribute since it
+// has already been added.
+for (auto & : DeviceVars) {
+  auto Kind = Info.Flags.getKind();
+  if (!Info.Var->isDeclaration() &&
+  (Kind == DeviceVarFlags::Variable ||
+   Kind == DeviceVarFlags::Surface ||
+   Kind == DeviceVarFlags::Texture) &&
+  Info.D->isUsed() && !Info.D->hasAttr()) {
+CGM.addCompilerUsedGlobal(Info.Var);
+  }
+}
 return nullptr;
   }
   return makeModuleCtorFunction();


Index: clang/test/CodeGenCUDA/host-used-device-var.cu
===
--- /dev/null
+++ clang/test/CodeGenCUDA/host-used-device-var.cu
@@ -0,0 +1,33 @@
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fcuda-is-device -x hip %s \
+// RUN:   -std=c++11 -O3 -mllvm -amdgpu-internalize-symbols -emit-llvm -o - \
+// RUN:   | FileCheck %s
+
+#include "Inputs/cuda.h"
+
+// Check device variables used by neither host nor device functioins are not kept.
+
+// CHECK-NOT: @v1
+__device__ int v1;
+
+// CHECK-NOT: @v2
+__constant__ int v2;
+
+// Check device variables used by host functions are kept.
+
+// CHECK: @u1
+__device__ int u1;
+
+// CHECK: @u2
+__constant__ int u2;
+
+// Check device variables with used attribute are always kept.
+
+// CHECK: @u3
+__device__ __attribute__((used)) int u3;
+
+int fun1() {
+  return u1 + u2;
+}
+
+// CHECK: @llvm.compiler.used = {{[^@]*}} @u1 {{[^@]*}} @u2 {{[^@]*}} @u3
Index: clang/lib/CodeGen/CGCUDANV.cpp
===
--- clang/lib/CodeGen/CGCUDANV.cpp
+++ clang/lib/CodeGen/CGCUDANV.cpp
@@ -1084,6 +1084,24 @@
 llvm::Function *CGNVCUDARuntime::finalizeModule() {
   if (CGM.getLangOpts().CUDAIsDevice) {
 transformManagedVars();
+
+// Mark ODR-used device variables as compiler used to prevent it from being
+// eliminated by optimization. This is necessary for device variables
+// ODR-used by host functions. Sema correctly marks them as ODR-used no
+// matter whether they are ODR-used by device or host functions.
+//
+// We do not need to do this if the variable has used attribute since it
+// has already been added.
+for (auto & : DeviceVars) {
+  auto Kind = Info.Flags.getKind();
+  if (!Info.Var->isDeclaration() &&
+  (Kind == DeviceVarFlags::Variable ||
+   Kind == DeviceVarFlags::Surface ||
+   Kind == DeviceVarFlags::Texture) &&
+  Info.D->isUsed() && !Info.D->hasAttr()) {
+CGM.addCompilerUsedGlobal(Info.Var);
+  }
+}
 return nullptr;
   }
   return makeModuleCtorFunction();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org