summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp13
-rw-r--r--clang/lib/AST/TypePrinter.cpp4
-rw-r--r--clang/lib/Basic/Targets.cpp64
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp18
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp7
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp1
-rw-r--r--clang/lib/CodeGen/CodeGenTypeCache.h4
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp12
-rw-r--r--clang/lib/CodeGen/TargetInfo.h15
-rw-r--r--clang/lib/Sema/SemaDecl.cpp7
-rw-r--r--clang/lib/Sema/SemaType.cpp5
11 files changed, 103 insertions, 47 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 3b526a23edd..29d970e66d7 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -8730,8 +8730,8 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
char *End;
unsigned AddrSpace = strtoul(Str, &End, 10);
if (End != Str && AddrSpace != 0) {
- Type = Context.getAddrSpaceQualType(Type, AddrSpace +
- LangAS::Count);
+ Type = Context.getAddrSpaceQualType(
+ Type, AddrSpace + LangAS::FirstTargetAddressSpace);
Str = End;
}
if (c == '*')
@@ -9546,13 +9546,8 @@ uint64_t ASTContext::getTargetNullPointerValue(QualType QT) const {
}
unsigned ASTContext::getTargetAddressSpace(unsigned AS) const {
- // For OpenCL, only function local variables are not explicitly marked with
- // an address space in the AST, and these need to be the address space of
- // alloca.
- if (!AS && LangOpts.OpenCL)
- return getTargetInfo().getDataLayout().getAllocaAddrSpace();
- if (AS >= LangAS::Count)
- return AS - LangAS::Count;
+ if (AS >= LangAS::FirstTargetAddressSpace)
+ return AS - LangAS::FirstTargetAddressSpace;
else
return (*AddrSpaceMap)[AS];
}
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 2be14ab6212..0551340c37a 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1668,9 +1668,9 @@ void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
OS << "__shared";
break;
default:
- assert(addrspace >= LangAS::Count);
+ assert(addrspace >= LangAS::FirstTargetAddressSpace);
OS << "__attribute__((address_space(";
- OS << addrspace - LangAS::Count;
+ OS << addrspace - LangAS::FirstTargetAddressSpace;
OS << ")))";
}
}
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 92c561aa941..1b9fbed1773 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -2034,25 +2034,45 @@ ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {
return llvm::makeArrayRef(GCCRegNames);
}
-static const LangAS::Map AMDGPUPrivateIsZeroMap = {
- 4, // Default
- 1, // opencl_global
- 3, // opencl_local
- 2, // opencl_constant
- 4, // opencl_generic
- 1, // cuda_device
- 2, // cuda_constant
- 3 // cuda_shared
+static const LangAS::Map AMDGPUNonOpenCLPrivateIsZeroMap = {
+ 4, // Default
+ 1, // opencl_global
+ 3, // opencl_local
+ 2, // opencl_constant
+ 4, // opencl_generic
+ 1, // cuda_device
+ 2, // cuda_constant
+ 3 // cuda_shared
+};
+static const LangAS::Map AMDGPUNonOpenCLGenericIsZeroMap = {
+ 0, // Default
+ 1, // opencl_global
+ 3, // opencl_local
+ 2, // opencl_constant
+ 0, // opencl_generic
+ 1, // cuda_device
+ 2, // cuda_constant
+ 3 // cuda_shared
};
-static const LangAS::Map AMDGPUGenericIsZeroMap = {
- 0, // Default
- 1, // opencl_global
- 3, // opencl_local
- 2, // opencl_constant
- 0, // opencl_generic
- 1, // cuda_device
- 2, // cuda_constant
- 3 // cuda_shared
+static const LangAS::Map AMDGPUOpenCLPrivateIsZeroMap = {
+ 0, // Default
+ 1, // opencl_global
+ 3, // opencl_local
+ 2, // opencl_constant
+ 4, // opencl_generic
+ 1, // cuda_device
+ 2, // cuda_constant
+ 3 // cuda_shared
+};
+static const LangAS::Map AMDGPUOpenCLGenericIsZeroMap = {
+ 5, // Default
+ 1, // opencl_global
+ 3, // opencl_local
+ 2, // opencl_constant
+ 0, // opencl_generic
+ 1, // cuda_device
+ 2, // cuda_constant
+ 3 // cuda_shared
};
// If you edit the description strings, make sure you update
@@ -2149,8 +2169,12 @@ public:
: DataLayoutStringR600);
assert(DataLayout->getAllocaAddrSpace() == AS.Private);
- AddrSpaceMap = IsGenericZero ? &AMDGPUGenericIsZeroMap :
- &AMDGPUPrivateIsZeroMap;
+ AddrSpaceMap =
+ llvm::StringSwitch<const LangAS::Map *>(Triple.getEnvironmentName())
+ .Case("opencl", &AMDGPUOpenCLPrivateIsZeroMap)
+ .Case("amdgiz", &AMDGPUNonOpenCLGenericIsZeroMap)
+ .Case("amdgizcl", &AMDGPUOpenCLGenericIsZeroMap)
+ .Default(&AMDGPUNonOpenCLPrivateIsZeroMap);
UseAddrSpaceMapMangling = true;
}
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 0fa8eeb1c3e..d6abfa15e54 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -11,14 +11,15 @@
//
//===----------------------------------------------------------------------===//
-#include "CodeGenFunction.h"
#include "CGBlocks.h"
#include "CGCXXABI.h"
#include "CGCleanup.h"
#include "CGDebugInfo.h"
#include "CGOpenCLRuntime.h"
#include "CGOpenMPRuntime.h"
+#include "CodeGenFunction.h"
#include "CodeGenModule.h"
+#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Decl.h"
@@ -1105,6 +1106,21 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
address = Address(vla, alignment);
}
+ // Alloca always returns a pointer in alloca address space, which may
+ // be different from the type defined by the language. For example,
+ // in C++ the auto variables are in the default address space. Therefore
+ // cast alloca to the expected address space when necessary.
+ auto T = D.getType();
+ assert(T.getAddressSpace() == LangAS::Default);
+ if (getASTAllocaAddressSpace() != LangAS::Default) {
+ auto *Addr = getTargetHooks().performAddrSpaceCast(
+ *this, address.getPointer(), getASTAllocaAddressSpace(),
+ T.getAddressSpace(),
+ address.getElementType()->getPointerTo(
+ getContext().getTargetAddressSpace(T.getAddressSpace())),
+ /*non-null*/ true);
+ address = Address(Addr, address.getAlignment());
+ }
setAddrOfLocalVar(&D, address);
emission.Addr = address;
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index b8d830ee9f3..048b50d8261 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -1579,10 +1579,9 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
}
// Since target may map different address spaces in AST to the same address
// space, an address space conversion may end up as a bitcast.
- auto *Src = Visit(E);
- return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast(CGF, Src,
- E->getType(),
- DestTy);
+ return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast(
+ CGF, Visit(E), E->getType()->getPointeeType().getAddressSpace(),
+ DestTy->getPointeeType().getAddressSpace(), ConvertType(DestTy));
}
case CK_AtomicToNonAtomic:
case CK_NonAtomicToAtomic:
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index a0254797ea4..dee4351a51e 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -113,6 +113,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO,
Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
AllocaInt8PtrTy = Int8Ty->getPointerTo(
M.getDataLayout().getAllocaAddrSpace());
+ ASTAllocaAddressSpace = getTargetCodeGenInfo().getASTAllocaAddressSpace();
RuntimeCC = getTargetCodeGenInfo().getABIInfo().getRuntimeCC();
BuiltinCC = getTargetCodeGenInfo().getABIInfo().getBuiltinCC();
diff --git a/clang/lib/CodeGen/CodeGenTypeCache.h b/clang/lib/CodeGen/CodeGenTypeCache.h
index 8ce9860cc63..450eab48a3b 100644
--- a/clang/lib/CodeGen/CodeGenTypeCache.h
+++ b/clang/lib/CodeGen/CodeGenTypeCache.h
@@ -94,6 +94,8 @@ struct CodeGenTypeCache {
unsigned char SizeAlignInBytes;
};
+ unsigned ASTAllocaAddressSpace;
+
CharUnits getSizeSize() const {
return CharUnits::fromQuantity(SizeSizeInBytes);
}
@@ -111,6 +113,8 @@ struct CodeGenTypeCache {
llvm::CallingConv::ID getRuntimeCC() const { return RuntimeCC; }
llvm::CallingConv::ID BuiltinCC;
llvm::CallingConv::ID getBuiltinCC() const { return BuiltinCC; }
+
+ unsigned getASTAllocaAddressSpace() const { return ASTAllocaAddressSpace; }
};
} // end namespace CodeGen
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 18367d1602b..e47b4807245 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -407,12 +407,11 @@ llvm::Constant *TargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &
}
llvm::Value *TargetCodeGenInfo::performAddrSpaceCast(
- CodeGen::CodeGenFunction &CGF, llvm::Value *Src, QualType SrcTy,
- QualType DestTy) const {
+ CodeGen::CodeGenFunction &CGF, llvm::Value *Src, unsigned SrcAddr,
+ unsigned DestAddr, llvm::Type *DestTy, bool isNonNull) const {
// Since target may map different address spaces in AST to the same address
// space, an address space conversion may end up as a bitcast.
- return CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Src,
- CGF.ConvertType(DestTy));
+ return CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DestTy);
}
static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays);
@@ -7292,6 +7291,11 @@ public:
llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM,
llvm::PointerType *T, QualType QT) const override;
+
+ unsigned getASTAllocaAddressSpace() const override {
+ return LangAS::FirstTargetAddressSpace +
+ getABIInfo().getDataLayout().getAllocaAddrSpace();
+ }
};
}
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index 223d6d047af..247d01dcb08 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/lib/CodeGen/TargetInfo.h
@@ -229,13 +229,20 @@ public:
virtual llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM,
llvm::PointerType *T, QualType QT) const;
+ /// Get the AST address space for alloca.
+ virtual unsigned getASTAllocaAddressSpace() const { return LangAS::Default; }
+
/// Perform address space cast of an expression of pointer type.
/// \param V is the LLVM value to be casted to another address space.
- /// \param SrcTy is the QualType of \p V.
- /// \param DestTy is the destination QualType.
+ /// \param SrcAddr is the language address space of \p V.
+ /// \param DestAddr is the targeted language address space.
+ /// \param DestTy is the destination LLVM pointer type.
+ /// \param IsNonNull is the flag indicating \p V is known to be non null.
virtual llvm::Value *performAddrSpaceCast(CodeGen::CodeGenFunction &CGF,
- llvm::Value *V, QualType SrcTy, QualType DestTy) const;
-
+ llvm::Value *V, unsigned SrcAddr,
+ unsigned DestAddr,
+ llvm::Type *DestTy,
+ bool IsNonNull = false) const;
};
} // namespace CodeGen
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 48091728ee3..ba1e97b33d6 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7191,7 +7191,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
// ISO/IEC TR 18037 S5.1.2
if (!getLangOpts().OpenCL
&& NewVD->hasLocalStorage() && T.getAddressSpace() != 0) {
- Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl);
+ Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl) << 0;
NewVD->setInvalidDecl();
return;
}
@@ -7271,6 +7271,11 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
NewVD->setInvalidDecl();
return;
}
+ } else if (T.getAddressSpace() != LangAS::Default) {
+ // Do not allow other address spaces on automatic variable.
+ Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl) << 1;
+ NewVD->setInvalidDecl();
+ return;
}
}
}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 3992179faba..1433607e9c7 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5531,14 +5531,15 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
addrSpace.setIsSigned(false);
}
llvm::APSInt max(addrSpace.getBitWidth());
- max = Qualifiers::MaxAddressSpace - LangAS::Count;
+ max = Qualifiers::MaxAddressSpace - LangAS::FirstTargetAddressSpace;
if (addrSpace > max) {
S.Diag(Attr.getLoc(), diag::err_attribute_address_space_too_high)
<< (unsigned)max.getZExtValue() << ASArgExpr->getSourceRange();
Attr.setInvalid();
return;
}
- ASIdx = static_cast<unsigned>(addrSpace.getZExtValue()) + LangAS::Count;
+ ASIdx = static_cast<unsigned>(addrSpace.getZExtValue()) +
+ LangAS::FirstTargetAddressSpace;
} else {
// The keyword-based type attributes imply which address space to use.
switch (Attr.getKind()) {
OpenPOWER on IntegriCloud