summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorYaxun Liu <Yaxun.Liu@amd.com>2016-12-09 19:01:11 +0000
committerYaxun Liu <Yaxun.Liu@amd.com>2016-12-09 19:01:11 +0000
commit8f66b4b44a3de6215c83dfc47ec4158578fb4668 (patch)
treedd42c649814f8be950985675bf91aec4ae79bc4b /clang/lib/CodeGen/CodeGenModule.cpp
parentdf41b13b09cef3916f97db33122f18d5cef17209 (diff)
downloadbcm5719-llvm-8f66b4b44a3de6215c83dfc47ec4158578fb4668.tar.gz
bcm5719-llvm-8f66b4b44a3de6215c83dfc47ec4158578fb4668.zip
Add support for non-zero null pointer for C and OpenCL
In amdgcn target, null pointers in global, constant, and generic address space take value 0 but null pointers in private and local address space take value -1. Currently LLVM assumes all null pointers take value 0, which results in incorrectly translated IR. To workaround this issue, instead of emit null pointers in local and private address space, a null pointer in generic address space is emitted and casted to local and private address space. Tentative definition of global variables with non-zero initializer will have weak linkage instead of common linkage since common linkage requires zero initializer and does not have explicit section to hold the non-zero value. Virtual member functions getNullPointer and performAddrSpaceCast are added to TargetCodeGenInfo which by default returns ConstantPointerNull and emitting addrspacecast instruction. A virtual member function getNullPointerValue is added to TargetInfo which by default returns 0. Each target can override these virtual functions to get target specific null pointer and the null pointer value for specific address space, and perform specific translations for addrspacecast. Wrapper functions getNullPointer is added to CodegenModule and getTargetNullPointerValue is added to ASTContext to facilitate getting the target specific null pointers and their values. This change has no effect on other targets except amdgcn target. Other targets can provide support of non-zero null pointer in a similar way. This change only provides support for non-zero null pointer for C and OpenCL. Supporting for other languages will be added later incrementally. Differential Revision: https://reviews.llvm.org/D26196 llvm-svn: 289252
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp9
1 files changed, 8 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 78f43bdef99..98b6215d0b4 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2611,9 +2611,16 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
else
GV->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass);
- if (Linkage == llvm::GlobalVariable::CommonLinkage)
+ if (Linkage == llvm::GlobalVariable::CommonLinkage) {
// common vars aren't constant even if declared const.
GV->setConstant(false);
+ // Tentative definition of global variables may be initialized with
+ // non-zero null pointers. In this case they should have weak linkage
+ // since common linkage must have zero initializer and must not have
+ // explicit section therefore cannot have non-zero initial value.
+ if (!GV->getInitializer()->isNullValue())
+ GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage);
+ }
setNonAliasAttributes(D, GV);
OpenPOWER on IntegriCloud