diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 13 | ||||
-rw-r--r-- | clang/lib/AST/TypePrinter.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Basic/Targets.cpp | 64 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypeCache.h | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 12 | ||||
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.h | 15 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 5 |
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()) { |