diff options
Diffstat (limited to 'clang/lib/CodeGen')
-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 |
6 files changed, 44 insertions, 13 deletions
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 |