diff options
author | Yaxun Liu <Yaxun.Liu@amd.com> | 2016-12-09 19:01:11 +0000 |
---|---|---|
committer | Yaxun Liu <Yaxun.Liu@amd.com> | 2016-12-09 19:01:11 +0000 |
commit | b6215483b7c1477237ab48ce5929bad2837b5a13 (patch) | |
tree | a38b34d69b07a308d18447070015390c65fd0e1c /include/clang/AST/APValue.h | |
parent | b40a34debf8e2b14f43ae6703f15229516eb5665 (diff) | |
download | clang-b6215483b7c1477237ab48ce5929bad2837b5a13.tar.gz |
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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@289252 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/AST/APValue.h')
-rw-r--r-- | include/clang/AST/APValue.h | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h index e58c21923f..7c431f3be8 100644 --- a/include/clang/AST/APValue.h +++ b/include/clang/AST/APValue.h @@ -135,14 +135,15 @@ public: } APValue(const APValue &RHS); APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); } - APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex) + APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex, + bool IsNullPtr = false) : Kind(Uninitialized) { - MakeLValue(); setLValue(B, O, N, CallIndex); + MakeLValue(); setLValue(B, O, N, CallIndex, IsNullPtr); } APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path, - bool OnePastTheEnd, unsigned CallIndex) + bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr = false) : Kind(Uninitialized) { - MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex); + MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr); } APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) { MakeArray(InitElts, Size); @@ -254,6 +255,7 @@ public: bool hasLValuePath() const; ArrayRef<LValuePathEntry> getLValuePath() const; unsigned getLValueCallIndex() const; + bool isNullPointer() const; APValue &getVectorElt(unsigned I) { assert(isVector() && "Invalid accessor"); @@ -374,10 +376,10 @@ public: ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I); } void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, - unsigned CallIndex); + unsigned CallIndex, bool IsNullPtr); void setLValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd, - unsigned CallIndex); + unsigned CallIndex, bool IsNullPtr); void setUnion(const FieldDecl *Field, const APValue &Value) { assert(isUnion() && "Invalid accessor"); ((UnionData*)(char*)Data.buffer)->Field = Field; |