From: John McCall Date: Tue, 8 Feb 2011 08:22:06 +0000 (+0000) Subject: Reorganize CodeGen{Function,Module} to eliminate the unfortunate X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d16c2cf1cafa413709aa487cbbd5dc392f1ba1ff;p=clang Reorganize CodeGen{Function,Module} to eliminate the unfortunate Block{Function,Module} base class. Minor other refactorings. Fixed a few address-space bugs while I was there. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125085 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index e78e175a5a..76a68b1526 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -15,6 +15,7 @@ #include "CodeGenFunction.h" #include "CGObjCRuntime.h" #include "CodeGenModule.h" +#include "CGBlocks.h" #include "clang/AST/DeclObjC.h" #include "llvm/Module.h" #include "llvm/ADT/SmallSet.h" @@ -104,18 +105,20 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM, return llvm::ConstantExpr::getBitCast(global, CGM.getBlockDescriptorType()); } -static unsigned computeBlockFlag(CodeGenModule &CGM, - const BlockExpr *BE, unsigned flags) { - QualType BPT = BE->getType(); - const FunctionType *ftype = BPT->getPointeeType()->getAs(); - QualType ResultType = ftype->getResultType(); +static BlockFlags computeBlockFlag(CodeGenModule &CGM, + const BlockExpr *BE, + BlockFlags flags) { + const FunctionType *ftype = BE->getFunctionType(); - CallArgList Args; - CodeGenTypes &Types = CGM.getTypes(); - const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, Args, - FunctionType::ExtInfo()); - if (CGM.ReturnTypeUsesSRet(FnInfo)) - flags |= CodeGenFunction::BLOCK_USE_STRET; + // This is a bit overboard. + CallArgList args; + const CGFunctionInfo &fnInfo = + CGM.getTypes().getFunctionInfo(ftype->getResultType(), args, + ftype->getExtInfo()); + + if (CGM.ReturnTypeUsesSRet(fnInfo)) + flags |= BLOCK_USE_STRET; + return flags; } @@ -514,7 +517,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) { llvm::Constant *blockFn = CodeGenFunction(CGM).GenerateBlockFunction(CurGD, blockInfo, CurFuncDecl, LocalDeclMap); - blockFn = llvm::ConstantExpr::getBitCast(blockFn, PtrToInt8Ty); + blockFn = llvm::ConstantExpr::getBitCast(blockFn, Int8PtrTy); // If there is nothing to capture, we can emit this as a global block. if (blockInfo.CanBeGlobal) @@ -523,7 +526,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) { // Otherwise, we have to emit this as a local block. llvm::Constant *isa = CGM.getNSConcreteStackBlock(); - isa = llvm::ConstantExpr::getBitCast(isa, PtrToInt8Ty); + isa = llvm::ConstantExpr::getBitCast(isa, Int8PtrTy); // Build the block descriptor. llvm::Constant *descriptor = buildBlockDescriptor(CGM, blockInfo); @@ -535,14 +538,14 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) { blockAddr->setAlignment(blockInfo.BlockAlign.getQuantity()); // Compute the initial on-stack block flags. - unsigned int flags = BLOCK_HAS_SIGNATURE; + BlockFlags flags = BLOCK_HAS_SIGNATURE; if (blockInfo.NeedsCopyDispose) flags |= BLOCK_HAS_COPY_DISPOSE; if (blockInfo.HasCXXObject) flags |= BLOCK_HAS_CXX_OBJ; flags = computeBlockFlag(CGM, blockInfo.getBlockExpr(), flags); // Initialize the block literal. Builder.CreateStore(isa, Builder.CreateStructGEP(blockAddr, 0, "block.isa")); - Builder.CreateStore(llvm::ConstantInt::get(intTy, flags), + Builder.CreateStore(llvm::ConstantInt::get(intTy, flags.getBitMask()), Builder.CreateStructGEP(blockAddr, 1, "block.flags")); Builder.CreateStore(llvm::ConstantInt::get(intTy, 0), Builder.CreateStructGEP(blockAddr, 2, "block.reserved")); @@ -605,7 +608,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) { if (ci->isNested()) src = Builder.CreateLoad(src, "byref.capture"); else - src = Builder.CreateBitCast(src, PtrToInt8Ty); + src = Builder.CreateBitCast(src, Int8PtrTy); // Write that i8* into the capture field. Builder.CreateStore(src, blockField); @@ -667,7 +670,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) { } -const llvm::Type *BlockModule::getBlockDescriptorType() { +const llvm::Type *CodeGenModule::getBlockDescriptorType() { if (BlockDescriptorType) return BlockDescriptorType; @@ -701,7 +704,7 @@ const llvm::Type *BlockModule::getBlockDescriptorType() { return BlockDescriptorType; } -const llvm::Type *BlockModule::getGenericBlockLiteralType() { +const llvm::Type *CodeGenModule::getGenericBlockLiteralType() { if (GenericBlockLiteralType) return GenericBlockLiteralType; @@ -718,10 +721,10 @@ const llvm::Type *BlockModule::getGenericBlockLiteralType() { // struct __block_descriptor *__descriptor; // }; GenericBlockLiteralType = llvm::StructType::get(IntTy->getContext(), - PtrToInt8Ty, + Int8PtrTy, IntTy, IntTy, - PtrToInt8Ty, + Int8PtrTy, BlockDescPtrTy, NULL); @@ -750,10 +753,7 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E, // Get the function pointer from the literal. llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp"); - BlockLiteral = - Builder.CreateBitCast(BlockLiteral, - llvm::Type::getInt8PtrTy(VMContext), - "tmp"); + BlockLiteral = Builder.CreateBitCast(BlockLiteral, Int8PtrTy, "tmp"); // Add the block literal. QualType VoidPtrTy = getContext().getPointerType(getContext().VoidTy); @@ -826,24 +826,24 @@ llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable, } llvm::Constant * -BlockModule::GetAddrOfGlobalBlock(const BlockExpr *blockExpr, +CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *blockExpr, const char *name) { CGBlockInfo blockInfo(blockExpr, name); // Compute information about the layout, etc., of this block. - computeBlockInfo(CGM, blockInfo); + computeBlockInfo(*this, blockInfo); // Using that metadata, generate the actual block function. llvm::Constant *blockFn; { llvm::DenseMap LocalDeclMap; - blockFn = CodeGenFunction(CGM).GenerateBlockFunction(GlobalDecl(), - blockInfo, - 0, LocalDeclMap); + blockFn = CodeGenFunction(*this).GenerateBlockFunction(GlobalDecl(), + blockInfo, + 0, LocalDeclMap); } - blockFn = llvm::ConstantExpr::getBitCast(blockFn, PtrToInt8Ty); + blockFn = llvm::ConstantExpr::getBitCast(blockFn, Int8PtrTy); - return buildGlobalBlock(CGM, blockInfo, blockFn); + return buildGlobalBlock(*this, blockInfo, blockFn); } static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM, @@ -858,11 +858,10 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM, fields[0] = CGM.getNSConcreteGlobalBlock(); // __flags - unsigned flags = computeBlockFlag(CGM, blockInfo.getBlockExpr(), - BlockBase::BLOCK_IS_GLOBAL | - BlockBase::BLOCK_HAS_SIGNATURE); + BlockFlags flags = computeBlockFlag(CGM, blockInfo.getBlockExpr(), + BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE); const llvm::Type *intTy = CGM.getTypes().ConvertType(CGM.getContext().IntTy); - fields[1] = llvm::ConstantInt::get(intTy, flags); + fields[1] = llvm::ConstantInt::get(intTy, flags.getBitMask()); // Reserved fields[2] = llvm::Constant::getNullValue(intTy); @@ -1075,7 +1074,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, llvm::Constant * -BlockFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { +CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { ASTContext &C = getContext(); FunctionArgList args; @@ -1108,17 +1107,17 @@ BlockFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { SC_None, false, true); - CGF.StartFunction(FD, C.VoidTy, Fn, args, SourceLocation()); + StartFunction(FD, C.VoidTy, Fn, args, SourceLocation()); const llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); - llvm::Value *src = CGF.GetAddrOfLocalVar(srcDecl); - src = CGF.Builder.CreateLoad(src); - src = CGF.Builder.CreateBitCast(src, structPtrTy, "block.source"); + llvm::Value *src = GetAddrOfLocalVar(srcDecl); + src = Builder.CreateLoad(src); + src = Builder.CreateBitCast(src, structPtrTy, "block.source"); - llvm::Value *dst = CGF.GetAddrOfLocalVar(dstDecl); - dst = CGF.Builder.CreateLoad(dst); - dst = CGF.Builder.CreateBitCast(dst, structPtrTy, "block.dest"); + llvm::Value *dst = GetAddrOfLocalVar(dstDecl); + dst = Builder.CreateLoad(dst); + dst = Builder.CreateBitCast(dst, structPtrTy, "block.dest"); const BlockDecl *blockDecl = blockInfo.getBlockDecl(); @@ -1148,28 +1147,28 @@ BlockFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { if (!copyExpr && !flags) continue; unsigned index = capture.getIndex(); - llvm::Value *srcField = CGF.Builder.CreateStructGEP(src, index); - llvm::Value *dstField = CGF.Builder.CreateStructGEP(dst, index); + llvm::Value *srcField = Builder.CreateStructGEP(src, index); + llvm::Value *dstField = Builder.CreateStructGEP(dst, index); // If there's an explicit copy expression, we do that. if (copyExpr) { - CGF.EmitSynthesizedCXXCopyCtor(dstField, srcField, copyExpr); + EmitSynthesizedCXXCopyCtor(dstField, srcField, copyExpr); } else { llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src"); - srcValue = Builder.CreateBitCast(srcValue, PtrToInt8Ty); - llvm::Value *dstAddr = Builder.CreateBitCast(dstField, PtrToInt8Ty); + srcValue = Builder.CreateBitCast(srcValue, Int8PtrTy); + llvm::Value *dstAddr = Builder.CreateBitCast(dstField, Int8PtrTy); Builder.CreateCall3(CGM.getBlockObjectAssign(), dstAddr, srcValue, - llvm::ConstantInt::get(CGF.Int32Ty, flags)); + llvm::ConstantInt::get(Int32Ty, flags)); } } - CGF.FinishFunction(); + FinishFunction(); - return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty); + return llvm::ConstantExpr::getBitCast(Fn, Int8PtrTy); } llvm::Constant * -BlockFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { +CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { ASTContext &C = getContext(); FunctionArgList args; @@ -1197,17 +1196,17 @@ BlockFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { SC_Static, SC_None, false, true); - CGF.StartFunction(FD, C.VoidTy, Fn, args, SourceLocation()); + StartFunction(FD, C.VoidTy, Fn, args, SourceLocation()); const llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); - llvm::Value *src = CGF.GetAddrOfLocalVar(srcDecl); - src = CGF.Builder.CreateLoad(src); - src = CGF.Builder.CreateBitCast(src, structPtrTy, "block"); + llvm::Value *src = GetAddrOfLocalVar(srcDecl); + src = Builder.CreateLoad(src); + src = Builder.CreateBitCast(src, structPtrTy, "block"); const BlockDecl *blockDecl = blockInfo.getBlockDecl(); - CodeGenFunction::RunCleanupsScope cleanups(CGF); + CodeGenFunction::RunCleanupsScope cleanups(*this); for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), ce = blockDecl->capture_end(); ci != ce; ++ci) { @@ -1217,7 +1216,7 @@ BlockFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); if (capture.isConstant()) continue; - unsigned flags = 0; + BlockFieldFlags flags; const CXXDestructorDecl *dtor = 0; if (ci->isByRef()) { @@ -1233,35 +1232,35 @@ BlockFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { dtor = record->getDestructor(); } - if (!dtor && !flags) continue; + if (!dtor && flags.empty()) continue; unsigned index = capture.getIndex(); - llvm::Value *srcField = CGF.Builder.CreateStructGEP(src, index); + llvm::Value *srcField = Builder.CreateStructGEP(src, index); // If there's an explicit copy expression, we do that. if (dtor) { - CGF.PushDestructorCleanup(dtor, srcField); + PushDestructorCleanup(dtor, srcField); // Otherwise we call _Block_object_dispose. It wouldn't be too // hard to just emit this as a cleanup if we wanted to make sure // that things were done in reverse. } else { llvm::Value *value = Builder.CreateLoad(srcField); - value = Builder.CreateBitCast(value, PtrToInt8Ty); + value = Builder.CreateBitCast(value, Int8PtrTy); BuildBlockRelease(value, flags); } } cleanups.ForceCleanup(); - CGF.FinishFunction(); + FinishFunction(); - return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty); + return llvm::ConstantExpr::getBitCast(Fn, Int8PtrTy); } -llvm::Constant *BlockFunction:: -GeneratebyrefCopyHelperFunction(const llvm::Type *T, int flag, - const VarDecl *BD) { +llvm::Constant *CodeGenFunction:: +GeneratebyrefCopyHelperFunction(const llvm::Type *T, BlockFieldFlags flags, + const VarDecl *variable) { QualType R = getContext().VoidTy; FunctionArgList Args; @@ -1300,46 +1299,43 @@ GeneratebyrefCopyHelperFunction(const llvm::Type *T, int flag, SC_Static, SC_None, false, true); - CGF.StartFunction(FD, R, Fn, Args, SourceLocation()); + StartFunction(FD, R, Fn, Args, SourceLocation()); // dst->x - llvm::Value *V = CGF.GetAddrOfLocalVar(Dst); + llvm::Value *V = GetAddrOfLocalVar(Dst); V = Builder.CreateBitCast(V, llvm::PointerType::get(T, 0)); V = Builder.CreateLoad(V); V = Builder.CreateStructGEP(V, 6, "x"); llvm::Value *DstObj = V; // src->x - V = CGF.GetAddrOfLocalVar(Src); + V = GetAddrOfLocalVar(Src); V = Builder.CreateLoad(V); V = Builder.CreateBitCast(V, T); V = Builder.CreateStructGEP(V, 6, "x"); - if (flag & BLOCK_HAS_CXX_OBJ) { - assert (BD && "VarDecl is null - GeneratebyrefCopyHelperFunction"); + if (Expr *copyExpr = getContext().getBlockVarCopyInits(variable)) { llvm::Value *SrcObj = V; - CGF.EmitSynthesizedCXXCopyCtor(DstObj, SrcObj, - getContext().getBlockVarCopyInits(BD)); - } - else { - DstObj = Builder.CreateBitCast(DstObj, PtrToInt8Ty); - V = Builder.CreateBitCast(V, llvm::PointerType::get(PtrToInt8Ty, 0)); + EmitSynthesizedCXXCopyCtor(DstObj, SrcObj, copyExpr); + } else { + DstObj = Builder.CreateBitCast(DstObj, Int8PtrTy); + V = Builder.CreateBitCast(V, llvm::PointerType::get(Int8PtrTy, 0)); llvm::Value *SrcObj = Builder.CreateLoad(V); - flag |= BLOCK_BYREF_CALLER; - llvm::Value *N = llvm::ConstantInt::get(CGF.Int32Ty, flag); + flags |= BLOCK_BYREF_CALLER; + llvm::Value *N = llvm::ConstantInt::get(Int32Ty, flags.getBitMask()); llvm::Value *F = CGM.getBlockObjectAssign(); Builder.CreateCall3(F, DstObj, SrcObj, N); } - CGF.FinishFunction(); + FinishFunction(); - return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty); + return llvm::ConstantExpr::getBitCast(Fn, Int8PtrTy); } llvm::Constant * -BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T, - int flag, - const VarDecl *BD) { +CodeGenFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T, + BlockFieldFlags flags, + const VarDecl *variable) { QualType R = getContext().VoidTy; FunctionArgList Args; @@ -1373,85 +1369,78 @@ BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T, SC_Static, SC_None, false, true); - CGF.StartFunction(FD, R, Fn, Args, SourceLocation()); + StartFunction(FD, R, Fn, Args, SourceLocation()); - llvm::Value *V = CGF.GetAddrOfLocalVar(Src); + llvm::Value *V = GetAddrOfLocalVar(Src); V = Builder.CreateBitCast(V, llvm::PointerType::get(T, 0)); V = Builder.CreateLoad(V); V = Builder.CreateStructGEP(V, 6, "x"); - if (flag & BLOCK_HAS_CXX_OBJ) { - EHScopeStack::stable_iterator CleanupDepth = CGF.EHStack.stable_begin(); - assert (BD && "VarDecl is null - GeneratebyrefDestroyHelperFunction"); - QualType ClassTy = BD->getType(); - CGF.PushDestructorCleanup(ClassTy, V); - CGF.PopCleanupBlocks(CleanupDepth); - } - else { - V = Builder.CreateBitCast(V, llvm::PointerType::get(PtrToInt8Ty, 0)); + + // If it's not any kind of special object, it must have a destructor + // or something. + if (!flags.isSpecialPointer()) { + EHScopeStack::stable_iterator CleanupDepth = EHStack.stable_begin(); + PushDestructorCleanup(variable->getType(), V); + PopCleanupBlocks(CleanupDepth); + + // Otherwise, call _Block_object_dispose. + } else { + V = Builder.CreateBitCast(V, llvm::PointerType::get(Int8PtrTy, 0)); V = Builder.CreateLoad(V); - flag |= BLOCK_BYREF_CALLER; - BuildBlockRelease(V, flag); + flags |= BLOCK_BYREF_CALLER; + BuildBlockRelease(V, flags); } - CGF.FinishFunction(); - return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty); + FinishFunction(); + + return llvm::ConstantExpr::getBitCast(Fn, Int8PtrTy); } -llvm::Constant *BlockFunction::BuildbyrefCopyHelper(const llvm::Type *T, - uint32_t flags, +llvm::Constant *CodeGenModule::BuildbyrefCopyHelper(const llvm::Type *T, + BlockFieldFlags flags, unsigned align, const VarDecl *var) { // All alignments below that of pointer alignment collapse down to just // pointer alignment, as we always have at least that much alignment to begin // with. - align /= unsigned(CGF.Target.getPointerAlign(0)/8); + align /= unsigned(getTarget().getPointerAlign(0) / 8); // As an optimization, we only generate a single function of each kind we // might need. We need a different one for each alignment and for each // setting of flags. We mix Align and flag to get the kind. - uint64_t Kind = (uint64_t)align*BLOCK_BYREF_CURRENT_MAX + flags; - llvm::Constant *&Entry = CGM.AssignCache[Kind]; - if (Entry) - return Entry; - return Entry = - CodeGenFunction(CGM).GeneratebyrefCopyHelperFunction(T, flags, var); + uint64_t Kind = (uint64_t)align*BLOCK_BYREF_CURRENT_MAX + flags.getBitMask(); + llvm::Constant *&Entry = AssignCache[Kind]; + if (!Entry) + Entry = CodeGenFunction(*this). + GeneratebyrefCopyHelperFunction(T, flags, var); + return Entry; } -llvm::Constant *BlockFunction::BuildbyrefDestroyHelper(const llvm::Type *T, - uint32_t flags, +llvm::Constant *CodeGenModule::BuildbyrefDestroyHelper(const llvm::Type *T, + BlockFieldFlags flags, unsigned align, const VarDecl *var) { // All alignments below that of pointer alignment collpase down to just // pointer alignment, as we always have at least that much alignment to begin // with. - align /= unsigned(CGF.Target.getPointerAlign(0)/8); + align /= unsigned(getTarget().getPointerAlign(0) / 8); // As an optimization, we only generate a single function of each kind we // might need. We need a different one for each alignment and for each // setting of flags. We mix Align and flag to get the kind. - uint64_t Kind = (uint64_t)align*BLOCK_BYREF_CURRENT_MAX + flags; - llvm::Constant *&Entry = CGM.DestroyCache[Kind]; - if (Entry) - return Entry; - return Entry = - CodeGenFunction(CGM).GeneratebyrefDestroyHelperFunction(T, flags, var); + uint64_t Kind = (uint64_t)align*BLOCK_BYREF_CURRENT_MAX + flags.getBitMask(); + llvm::Constant *&Entry = DestroyCache[Kind]; + if (!Entry) + Entry = CodeGenFunction(*this). + GeneratebyrefDestroyHelperFunction(T, flags, var); + return Entry; } -void BlockFunction::BuildBlockRelease(llvm::Value *V, uint32_t flags) { +void CodeGenFunction::BuildBlockRelease(llvm::Value *V, BlockFieldFlags flags) { llvm::Value *F = CGM.getBlockObjectDispose(); llvm::Value *N; - V = Builder.CreateBitCast(V, PtrToInt8Ty); - N = llvm::ConstantInt::get(CGF.Int32Ty, flags); + V = Builder.CreateBitCast(V, Int8PtrTy); + N = llvm::ConstantInt::get(Int32Ty, flags.getBitMask()); Builder.CreateCall2(F, V, N); } - -ASTContext &BlockFunction::getContext() const { return CGM.getContext(); } - -BlockFunction::BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf, - CGBuilderTy &B) - : CGM(cgm), VMContext(cgm.getLLVMContext()), CGF(cgf), - BlockInfo(0), BlockPointer(0), Builder(B) { - PtrToInt8Ty = llvm::PointerType::getUnqual( - llvm::Type::getInt8Ty(VMContext)); -} diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h index 888fdb6a40..a2a1cdfdf6 100644 --- a/lib/CodeGen/CGBlocks.h +++ b/lib/CodeGen/CGBlocks.h @@ -24,9 +24,6 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" -#include -#include - #include "CGBuilder.h" #include "CGCall.h" #include "CGValue.h" @@ -46,116 +43,156 @@ namespace llvm { namespace clang { namespace CodeGen { + class CodeGenModule; class CGBlockInfo; -class BlockBase { -public: - enum { - BLOCK_HAS_COPY_DISPOSE = (1 << 25), - BLOCK_HAS_CXX_OBJ = (1 << 26), - BLOCK_IS_GLOBAL = (1 << 28), - BLOCK_USE_STRET = (1 << 29), - BLOCK_HAS_SIGNATURE = (1 << 30) - }; +enum BlockFlag_t { + BLOCK_HAS_COPY_DISPOSE = (1 << 25), + BLOCK_HAS_CXX_OBJ = (1 << 26), + BLOCK_IS_GLOBAL = (1 << 28), + BLOCK_USE_STRET = (1 << 29), + BLOCK_HAS_SIGNATURE = (1 << 30) }; +class BlockFlags { + uint32_t flags; - -class BlockModule : public BlockBase { - ASTContext &Context; - llvm::Module &TheModule; - const llvm::TargetData &TheTargetData; - CodeGenTypes &Types; - CodeGenModule &CGM; - llvm::LLVMContext &VMContext; - - ASTContext &getContext() const { return Context; } - llvm::Module &getModule() const { return TheModule; } - CodeGenTypes &getTypes() { return Types; } - const llvm::TargetData &getTargetData() const { return TheTargetData; } + BlockFlags(uint32_t flags) : flags(flags) {} public: - int getGlobalUniqueCount() { return ++Block.GlobalUniqueCount; } - const llvm::Type *getBlockDescriptorType(); - - const llvm::Type *getGenericBlockLiteralType(); - - llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *); + BlockFlags() : flags(0) {} + BlockFlags(BlockFlag_t flag) : flags(flag) {} - const llvm::Type *BlockDescriptorType; - const llvm::Type *GenericBlockLiteralType; + uint32_t getBitMask() const { return flags; } + bool empty() const { return flags == 0; } - struct { - int GlobalUniqueCount; - } Block; - - const llvm::PointerType *PtrToInt8Ty; - - std::map AssignCache; - std::map DestroyCache; - - BlockModule(ASTContext &C, llvm::Module &M, const llvm::TargetData &TD, - CodeGenTypes &T, CodeGenModule &CodeGen) - : Context(C), TheModule(M), TheTargetData(TD), Types(T), - CGM(CodeGen), VMContext(M.getContext()), - BlockDescriptorType(0), GenericBlockLiteralType(0) { - Block.GlobalUniqueCount = 0; - PtrToInt8Ty = llvm::Type::getInt8PtrTy(M.getContext()); + friend BlockFlags operator|(BlockFlags l, BlockFlags r) { + return BlockFlags(l.flags | r.flags); + } + friend BlockFlags &operator|=(BlockFlags &l, BlockFlags r) { + l.flags |= r.flags; + return l; + } + friend bool operator&(BlockFlags l, BlockFlags r) { + return (l.flags & r.flags); } }; +inline BlockFlags operator|(BlockFlag_t l, BlockFlag_t r) { + return BlockFlags(l) | BlockFlags(r); +} -class BlockFunction : public BlockBase { - CodeGenModule &CGM; - ASTContext &getContext() const; +enum BlockFieldFlag_t { + BLOCK_FIELD_IS_OBJECT = 0x03, /* id, NSObject, __attribute__((NSObject)), + block, ... */ + BLOCK_FIELD_IS_BLOCK = 0x07, /* a block variable */ -protected: - llvm::LLVMContext &VMContext; + BLOCK_FIELD_IS_BYREF = 0x08, /* the on stack structure holding the __block + variable */ + BLOCK_FIELD_IS_WEAK = 0x10, /* declared __weak, only used in byref copy + helpers */ -public: - CodeGenFunction &CGF; + BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose + support routines */ + BLOCK_BYREF_CURRENT_MAX = 256 +}; - const CodeGen::CGBlockInfo *BlockInfo; - llvm::Value *BlockPointer; +class BlockFieldFlags { + uint32_t flags; - const llvm::PointerType *PtrToInt8Ty; - struct HelperInfo { - int index; - int flag; - const BlockDeclRefExpr *cxxvar_import; - bool RequiresCopying; - }; + BlockFieldFlags(uint32_t flags) : flags(flags) {} +public: + BlockFieldFlags() : flags(0) {} + BlockFieldFlags(BlockFieldFlag_t flag) : flags(flag) {} - enum { - BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), - block, ... */ - BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ - BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block - variable */ - BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy - helpers */ - BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose - support routines */ - BLOCK_BYREF_CURRENT_MAX = 256 - }; + uint32_t getBitMask() const { return flags; } + bool empty() const { return flags == 0; } - CGBuilderTy &Builder; + /// Answers whether the flags indicate that this field is an object + /// or block pointer that requires _Block_object_assign/dispose. + bool isSpecialPointer() const { return flags & BLOCK_FIELD_IS_OBJECT; } - BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf, CGBuilderTy &B); + friend BlockFieldFlags operator|(BlockFieldFlags l, BlockFieldFlags r) { + return BlockFieldFlags(l.flags | r.flags); + } + friend BlockFieldFlags &operator|=(BlockFieldFlags &l, BlockFieldFlags r) { + l.flags |= r.flags; + return l; + } + friend bool operator&(BlockFieldFlags l, BlockFieldFlags r) { + return (l.flags & r.flags); + } +}; +inline BlockFieldFlags operator|(BlockFieldFlag_t l, BlockFieldFlag_t r) { + return BlockFieldFlags(l) | BlockFieldFlags(r); +} - llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo); - llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo); +/// CGBlockInfo - Information to generate a block literal. +class CGBlockInfo { +public: + /// Name - The name of the block, kindof. + const char *Name; + + /// The field index of 'this' within the block, if there is one. + unsigned CXXThisIndex; + + class Capture { + uintptr_t Data; + + public: + bool isIndex() const { return (Data & 1) != 0; } + bool isConstant() const { return !isIndex(); } + unsigned getIndex() const { assert(isIndex()); return Data >> 1; } + llvm::Value *getConstant() const { + assert(isConstant()); + return reinterpret_cast(Data); + } + + static Capture makeIndex(unsigned index) { + Capture v; + v.Data = (index << 1) | 1; + return v; + } + + static Capture makeConstant(llvm::Value *value) { + Capture v; + v.Data = reinterpret_cast(value); + return v; + } + }; - llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag, - const VarDecl *BD); - llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, - int flag, - const VarDecl *BD); + /// The mapping of allocated indexes within the block. + llvm::DenseMap Captures; + + /// CanBeGlobal - True if the block can be global, i.e. it has + /// no non-constant captures. + bool CanBeGlobal : 1; + + /// True if the block needs a custom copy or dispose function. + bool NeedsCopyDispose : 1; + + /// HasCXXObject - True if the block's custom copy/dispose functions + /// need to be run even in GC mode. + bool HasCXXObject : 1; + + /// HasWeakBlockVariable - True if block captures a weak __block variable. + bool HasWeakBlockVariable : 1; + + const llvm::StructType *StructureType; + const BlockExpr *Block; + CharUnits BlockSize; + CharUnits BlockAlign; + llvm::SmallVector BlockLayout; + + const Capture &getCapture(const VarDecl *var) const { + llvm::DenseMap::const_iterator + it = Captures.find(var); + assert(it != Captures.end() && "no entry for variable!"); + return it->second; + } - llvm::Constant *BuildbyrefCopyHelper(const llvm::Type *T, uint32_t flags, - unsigned Align, const VarDecl *BD); - llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type *T, uint32_t flags, - unsigned Align, const VarDecl *BD); + const BlockDecl *getBlockDecl() const { return Block->getBlockDecl(); } + const BlockExpr *getBlockExpr() const { return Block; } - void BuildBlockRelease(llvm::Value *DeclPtr, uint32_t flags); + CGBlockInfo(const BlockExpr *blockExpr, const char *Name); }; } // end namespace CodeGen diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 4e59c8d517..87572d68c6 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -30,8 +30,8 @@ static void EmitMemoryBarrier(CodeGenFunction &CGF, bool LoadLoad, bool LoadStore, bool StoreLoad, bool StoreStore, bool Device) { - Value *True = llvm::ConstantInt::getTrue(CGF.getLLVMContext()); - Value *False = llvm::ConstantInt::getFalse(CGF.getLLVMContext()); + Value *True = CGF.Builder.getTrue(); + Value *False = CGF.Builder.getFalse(); Value *C[5] = { LoadLoad ? True : False, LoadStore ? True : False, StoreLoad ? True : False, @@ -178,10 +178,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, Expr::EvalResult Result; if (E->Evaluate(Result, CGM.getContext())) { if (Result.Val.isInt()) - return RValue::get(llvm::ConstantInt::get(VMContext, + return RValue::get(llvm::ConstantInt::get(getLLVMContext(), Result.Val.getInt())); if (Result.Val.isFloat()) - return RValue::get(ConstantFP::get(VMContext, Result.Val.getFloat())); + return RValue::get(llvm::ConstantFP::get(getLLVMContext(), + Result.Val.getFloat())); } switch (BuiltinID) { @@ -193,7 +194,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, case Builtin::BI__builtin_va_start: case Builtin::BI__builtin_va_end: { Value *ArgValue = EmitVAListRef(E->getArg(0)); - const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext); + const llvm::Type *DestType = Int8PtrTy; if (ArgValue->getType() != DestType) ArgValue = Builder.CreateBitCast(ArgValue, DestType, ArgValue->getName().data()); @@ -206,7 +207,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, Value *DstPtr = EmitVAListRef(E->getArg(0)); Value *SrcPtr = EmitVAListRef(E->getArg(1)); - const llvm::Type *Type = llvm::Type::getInt8PtrTy(VMContext); + const llvm::Type *Type = Int8PtrTy; DstPtr = Builder.CreateBitCast(DstPtr, Type); SrcPtr = Builder.CreateBitCast(SrcPtr, Type); @@ -335,7 +336,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, ConstantInt *CI = dyn_cast(Ty); assert(CI); uint64_t val = CI->getZExtValue(); - CI = ConstantInt::get(llvm::Type::getInt1Ty(VMContext), (val & 0x2) >> 1); + CI = ConstantInt::get(Builder.getInt1Ty(), (val & 0x2) >> 1); Value *F = CGM.getIntrinsic(Intrinsic::objectsize, ResType, 1); return RValue::get(Builder.CreateCall2(F, @@ -363,7 +364,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, Builder.CreateUnreachable(); // We do need to preserve an insertion point. - CGF.EmitBlock(createBasicBlock("unreachable.cont")); + EmitBlock(createBasicBlock("unreachable.cont")); return RValue::get(0); } @@ -524,7 +525,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, case Builtin::BIalloca: case Builtin::BI__builtin_alloca: { Value *Size = EmitScalarExpr(E->getArg(0)); - return RValue::get(Builder.CreateAlloca(llvm::Type::getInt8Ty(VMContext), Size, "tmp")); + return RValue::get(Builder.CreateAlloca(Builder.getInt8Ty(), Size, "tmp")); } case Builtin::BIbzero: case Builtin::BI__builtin_bzero: { @@ -636,7 +637,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, Builder.CreateUnreachable(); // We do need to preserve an insertion point. - CGF.EmitBlock(CGF.createBasicBlock("builtin_eh_return.cont")); + EmitBlock(createBasicBlock("builtin_eh_return.cont")); return RValue::get(0); } @@ -655,11 +656,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, // // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html - LLVMContext &C = CGM.getLLVMContext(); - // Cast the pointer to intptr_t. Value *Ptr = EmitScalarExpr(E->getArg(0)); - const llvm::IntegerType *IntPtrTy = CGM.getTargetData().getIntPtrType(C); Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast"); // If that's 64 bits, we're done. @@ -691,12 +689,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, // Call LLVM's EH setjmp, which is lightweight. Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); - Buf = Builder.CreateBitCast(Buf, llvm::Type::getInt8PtrTy(VMContext)); + Buf = Builder.CreateBitCast(Buf, Int8PtrTy); return RValue::get(Builder.CreateCall(F, Buf)); } case Builtin::BI__builtin_longjmp: { Value *Buf = EmitScalarExpr(E->getArg(0)); - Buf = Builder.CreateBitCast(Buf, llvm::Type::getInt8PtrTy(VMContext)); + Buf = Builder.CreateBitCast(Buf, Int8PtrTy); // Call LLVM's EH longjmp, which is lightweight. Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf); @@ -705,7 +703,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, Builder.CreateUnreachable(); // We do need to preserve an insertion point. - CGF.EmitBlock(CGF.createBasicBlock("longjmp.cont")); + EmitBlock(createBasicBlock("longjmp.cont")); return RValue::get(0); } @@ -807,13 +805,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, case Builtin::BI__sync_val_compare_and_swap_8: case Builtin::BI__sync_val_compare_and_swap_16: { QualType T = E->getType(); - llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); + llvm::Value *DestPtr = EmitScalarExpr(E->getArg(0)); unsigned AddrSpace = cast(DestPtr->getType())->getAddressSpace(); const llvm::IntegerType *IntType = - llvm::IntegerType::get(CGF.getLLVMContext(), - CGF.getContext().getTypeSize(T)); + llvm::IntegerType::get(getLLVMContext(), + getContext().getTypeSize(T)); const llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); const llvm::Type *IntrinsicTypes[2] = { IntType, IntPtrType }; Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, @@ -821,13 +819,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, Value *Args[3]; Args[0] = Builder.CreateBitCast(DestPtr, IntPtrType); - Args[1] = CGF.EmitScalarExpr(E->getArg(1)); + Args[1] = EmitScalarExpr(E->getArg(1)); const llvm::Type *ValueType = Args[1]->getType(); - Args[1] = EmitToInt(CGF, Args[1], T, IntType); - Args[2] = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(2)), T, IntType); + Args[1] = EmitToInt(*this, Args[1], T, IntType); + Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType); - Value *Result = EmitCallWithBarrier(CGF, AtomF, Args, Args + 3); - Result = EmitFromInt(CGF, Result, T, ValueType); + Value *Result = EmitCallWithBarrier(*this, AtomF, Args, Args + 3); + Result = EmitFromInt(*this, Result, T, ValueType); return RValue::get(Result); } @@ -837,13 +835,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, case Builtin::BI__sync_bool_compare_and_swap_8: case Builtin::BI__sync_bool_compare_and_swap_16: { QualType T = E->getArg(1)->getType(); - llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); + llvm::Value *DestPtr = EmitScalarExpr(E->getArg(0)); unsigned AddrSpace = cast(DestPtr->getType())->getAddressSpace(); const llvm::IntegerType *IntType = - llvm::IntegerType::get(CGF.getLLVMContext(), - CGF.getContext().getTypeSize(T)); + llvm::IntegerType::get(getLLVMContext(), + getContext().getTypeSize(T)); const llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); const llvm::Type *IntrinsicTypes[2] = { IntType, IntPtrType }; Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, @@ -851,8 +849,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, Value *Args[3]; Args[0] = Builder.CreateBitCast(DestPtr, IntPtrType); - Args[1] = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(1)), T, IntType); - Args[2] = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(2)), T, IntType); + Args[1] = EmitToInt(*this, EmitScalarExpr(E->getArg(1)), T, IntType); + Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType); Value *OldVal = Args[1]; Value *PrevVal = EmitCallWithBarrier(*this, AtomF, Args, Args + 3); @@ -985,7 +983,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext()); assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; - ArgValue = llvm::ConstantInt::get(VMContext, Result); + ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result); } // If the intrinsic arg type is different from the builtin arg type @@ -1003,7 +1001,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, Value *V = Builder.CreateCall(F, Args.data(), Args.data() + Args.size()); QualType BuiltinRetType = E->getType(); - const llvm::Type *RetTy = llvm::Type::getVoidTy(VMContext); + const llvm::Type *RetTy = llvm::Type::getVoidTy(getLLVMContext()); if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType); if (RetTy != V->getType()) { @@ -1141,9 +1139,9 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, // Determine the overloaded type of this builtin. const llvm::Type *Ty; if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f) - Ty = llvm::Type::getFloatTy(VMContext); + Ty = llvm::Type::getFloatTy(getLLVMContext()); else - Ty = llvm::Type::getDoubleTy(VMContext); + Ty = llvm::Type::getDoubleTy(getLLVMContext()); // Determine whether this is an unsigned conversion or not. bool usgn = Result.getZExtValue() == 1; @@ -1162,7 +1160,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, (void)poly; // Only used in assert()s. bool rightShift = false; - const llvm::VectorType *VTy = GetNeonType(VMContext, type & 0x7, quad); + const llvm::VectorType *VTy = GetNeonType(getLLVMContext(), type & 0x7, quad); const llvm::Type *Ty = VTy; if (!Ty) return 0; @@ -1233,7 +1231,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, case ARM::BI__builtin_neon_vcvt_f32_v: case ARM::BI__builtin_neon_vcvtq_f32_v: { Ops[0] = Builder.CreateBitCast(Ops[0], Ty); - Ty = GetNeonType(VMContext, 4, quad); + Ty = GetNeonType(getLLVMContext(), 4, quad); return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); } @@ -1241,13 +1239,13 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, case ARM::BI__builtin_neon_vcvt_u32_v: case ARM::BI__builtin_neon_vcvtq_s32_v: case ARM::BI__builtin_neon_vcvtq_u32_v: { - Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(VMContext, 4, quad)); + Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(getLLVMContext(), 4, quad)); return usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); } case ARM::BI__builtin_neon_vcvt_n_f32_v: case ARM::BI__builtin_neon_vcvtq_n_f32_v: { - const llvm::Type *Tys[2] = { GetNeonType(VMContext, 4, quad), Ty }; + const llvm::Type *Tys[2] = { GetNeonType(getLLVMContext(), 4, quad), Ty }; Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp : Intrinsic::arm_neon_vcvtfxs2fp; Function *F = CGM.getIntrinsic(Int, Tys, 2); return EmitNeonCall(F, Ops, "vcvt_n"); @@ -1256,7 +1254,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, case ARM::BI__builtin_neon_vcvt_n_u32_v: case ARM::BI__builtin_neon_vcvtq_n_s32_v: case ARM::BI__builtin_neon_vcvtq_n_u32_v: { - const llvm::Type *Tys[2] = { Ty, GetNeonType(VMContext, 4, quad) }; + const llvm::Type *Tys[2] = { Ty, GetNeonType(getLLVMContext(), 4, quad) }; Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu : Intrinsic::arm_neon_vcvtfp2fxs; Function *F = CGM.getIntrinsic(Int, Tys, 2); return EmitNeonCall(F, Ops, "vcvt_n"); @@ -1473,7 +1471,8 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, Int = usgn ? Intrinsic::arm_neon_vpadalu : Intrinsic::arm_neon_vpadals; // The source operand type has twice as many elements of half the size. unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); - const llvm::Type *EltTy = llvm::IntegerType::get(VMContext, EltBits / 2); + const llvm::Type *EltTy = + llvm::IntegerType::get(getLLVMContext(), EltBits / 2); const llvm::Type *NarrowTy = llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); const llvm::Type *Tys[2] = { Ty, NarrowTy }; @@ -1487,7 +1486,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, Int = usgn ? Intrinsic::arm_neon_vpaddlu : Intrinsic::arm_neon_vpaddls; // The source operand type has twice as many elements of half the size. unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); - const llvm::Type *EltTy = llvm::IntegerType::get(VMContext, EltBits / 2); + const llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2); const llvm::Type *NarrowTy = llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); const llvm::Type *Tys[2] = { Ty, NarrowTy }; @@ -1827,7 +1826,7 @@ BuildVector(const llvm::SmallVectorImpl &Ops) { for (unsigned i = 0, e = Ops.size(); i != e; ++i) Result = Builder.CreateInsertElement(Result, Ops[i], - llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), i)); + llvm::ConstantInt::get(llvm::Type::getInt32Ty(getLLVMContext()), i)); return Result; } @@ -1854,7 +1853,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, llvm::APSInt Result; bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; - Ops.push_back(llvm::ConstantInt::get(VMContext, Result)); + Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); } switch (BuiltinID) { @@ -1918,7 +1917,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, case X86::BI__builtin_ia32_vec_init_v4hi: case X86::BI__builtin_ia32_vec_init_v2si: return Builder.CreateBitCast(BuildVector(Ops), - llvm::Type::getX86_MMXTy(VMContext)); + llvm::Type::getX86_MMXTy(getLLVMContext())); case X86::BI__builtin_ia32_vec_ext_v2si: return Builder.CreateExtractElement(Ops[0], llvm::ConstantInt::get(Ops[1]->getType(), 0)); @@ -1983,7 +1982,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpss"); } case X86::BI__builtin_ia32_ldmxcsr: { - const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); + const llvm::Type *PtrTy = Int8PtrTy; Value *One = llvm::ConstantInt::get(Int32Ty, 1); Value *Tmp = Builder.CreateAlloca(Int32Ty, One, "tmp"); Builder.CreateStore(Ops[0], Tmp); @@ -1991,7 +1990,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, Builder.CreateBitCast(Tmp, PtrTy)); } case X86::BI__builtin_ia32_stmxcsr: { - const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); + const llvm::Type *PtrTy = Int8PtrTy; Value *One = llvm::ConstantInt::get(Int32Ty, 1); Value *Tmp = Builder.CreateAlloca(Int32Ty, One, "tmp"); One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), @@ -2108,7 +2107,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, case PPC::BI__builtin_altivec_lvsl: case PPC::BI__builtin_altivec_lvsr: { - Ops[1] = Builder.CreateBitCast(Ops[1], llvm::Type::getInt8PtrTy(VMContext)); + Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); Ops[0] = Builder.CreateGEP(Ops[1], Ops[0], "tmp"); Ops.pop_back(); @@ -2148,7 +2147,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, case PPC::BI__builtin_altivec_stvehx: case PPC::BI__builtin_altivec_stvewx: { - Ops[2] = Builder.CreateBitCast(Ops[2], llvm::Type::getInt8PtrTy(VMContext)); + Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); Ops[1] = Builder.CreateGEP(Ops[2], Ops[1], "tmp"); Ops.pop_back(); diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index b217729e6e..d4bd9cbc9a 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -338,8 +338,8 @@ CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD, CGM.getVTables().getAddressPoint(BaseSubobject(RD, 0), RD); VTableIndex += AddressPoint; llvm::Value *VFuncPtr = - CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt"); - return CGF.Builder.CreateLoad(VFuncPtr); + Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt"); + return Builder.CreateLoad(VFuncPtr); } /// BuildVirtualCall - This routine makes indirect vtable call for @@ -373,8 +373,8 @@ CodeGenFunction::BuildAppleKextVirtualDestructorCall( CGM.getVTables().getAddressPoint(BaseSubobject(RD, 0), RD); VTableIndex += AddressPoint; llvm::Value *VFuncPtr = - CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt"); - Callee = CGF.Builder.CreateLoad(VFuncPtr); + Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt"); + Callee = Builder.CreateLoad(VFuncPtr); } return Callee; } diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index e6e5ea1970..c517cf3d09 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -928,7 +928,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, // The alignment we need to use is the max of the requested alignment for // the argument plus the alignment required by our access code below. unsigned AlignmentToUse = - CGF.CGM.getTargetData().getABITypeAlignment(ArgI.getCoerceToType()); + CGM.getTargetData().getABITypeAlignment(ArgI.getCoerceToType()); AlignmentToUse = std::max(AlignmentToUse, (unsigned)getContext().getDeclAlign(Arg).getQuantity()); diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index ac2a5445a4..fc239a536f 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -1312,9 +1312,6 @@ llvm::Value * CodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl) { - const llvm::Type *Int8PtrTy = - llvm::Type::getInt8Ty(VMContext)->getPointerTo(); - llvm::Value *VTablePtr = GetVTablePtr(This, Int8PtrTy); int64_t VBaseOffsetOffset = CGM.getVTables().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl); diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp index 3c4d80f236..374ede880d 100644 --- a/lib/CodeGen/CGCleanup.cpp +++ b/lib/CodeGen/CGCleanup.cpp @@ -784,7 +784,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { // Optimistically hope that any fixups will continue falling through. for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups(); I < E; ++I) { - BranchFixup &Fixup = CGF.EHStack.getBranchFixup(I); + BranchFixup &Fixup = EHStack.getBranchFixup(I); if (!Fixup.Destination) continue; if (!Fixup.OptimisticBranchBlock) { new llvm::StoreInst(Builder.getInt32(Fixup.DestinationIndex), @@ -846,7 +846,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { if (NewNormalEntry != NormalEntry && NormalEntry == NormalExit) for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups(); I < E; ++I) - CGF.EHStack.getBranchFixup(I).OptimisticBranchBlock = NewNormalEntry; + EHStack.getBranchFixup(I).OptimisticBranchBlock = NewNormalEntry; } } diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 6526ee0f63..ccf9c50125 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -14,6 +14,7 @@ #include "CGDebugInfo.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" +#include "CGBlocks.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclObjC.h" diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 0f74a3f530..c3708d1efd 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -14,6 +14,7 @@ #include "CGDebugInfo.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" +#include "CGBlocks.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CharUnits.h" #include "clang/AST/Decl.h" @@ -337,9 +338,7 @@ const llvm::Type *CodeGenFunction::BuildByRefType(const VarDecl *D) { std::vector Types; - const llvm::PointerType *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); - - llvm::PATypeHolder ByRefTypeHolder = llvm::OpaqueType::get(VMContext); + llvm::PATypeHolder ByRefTypeHolder = llvm::OpaqueType::get(getLLVMContext()); // void *__isa; Types.push_back(Int8PtrTy); @@ -380,7 +379,7 @@ const llvm::Type *CodeGenFunction::BuildByRefType(const VarDecl *D) { unsigned NumPaddingBytes = AlignedOffsetInBytes - CurrentOffsetInBytes; if (NumPaddingBytes > 0) { - const llvm::Type *Ty = llvm::Type::getInt8Ty(VMContext); + const llvm::Type *Ty = llvm::Type::getInt8Ty(getLLVMContext()); // FIXME: We need a sema error for alignment larger than the minimum of // the maximal stack alignmint and the alignment of malloc on the system. if (NumPaddingBytes > 1) @@ -396,7 +395,7 @@ const llvm::Type *CodeGenFunction::BuildByRefType(const VarDecl *D) { // T x; Types.push_back(ConvertTypeForMem(Ty)); - const llvm::Type *T = llvm::StructType::get(VMContext, Types, Packed); + const llvm::Type *T = llvm::StructType::get(getLLVMContext(), Types, Packed); cast(ByRefTypeHolder.get())->refineAbstractTypeTo(T); CGM.getModule().addTypeName("struct.__block_byref_" + D->getNameAsString(), @@ -507,7 +506,7 @@ namespace { void Emit(CodeGenFunction &CGF, bool IsForEH) { llvm::Value *V = CGF.Builder.CreateStructGEP(Addr, 1, "forwarding"); V = CGF.Builder.CreateLoad(V); - CGF.BuildBlockRelease(V, BlockFunction::BLOCK_FIELD_IS_BYREF); + CGF.BuildBlockRelease(V, BLOCK_FIELD_IS_BYREF); } }; } @@ -686,8 +685,7 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D, if (!DidCallStackSave) { // Save the stack. - const llvm::Type *LTy = llvm::Type::getInt8PtrTy(VMContext); - llvm::Value *Stack = CreateTempAlloca(LTy, "saved_stack"); + llvm::Value *Stack = CreateTempAlloca(Int8PtrTy, "saved_stack"); llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stacksave); llvm::Value *V = Builder.CreateCall(F); @@ -709,7 +707,7 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D, // Allocate memory for the array. llvm::AllocaInst *VLA = - Builder.CreateAlloca(llvm::Type::getInt8Ty(VMContext), VLASize, "vla"); + Builder.CreateAlloca(llvm::Type::getInt8Ty(getLLVMContext()), VLASize, "vla"); VLA->setAlignment(getContext().getDeclAlign(&D).getQuantity()); DeclPtr = Builder.CreateBitCast(VLA, LElemPtrTy, "tmp"); @@ -743,59 +741,62 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D, } if (isByRef) { - const llvm::PointerType *PtrToInt8Ty = llvm::Type::getInt8PtrTy(VMContext); - EnsureInsertPoint(); llvm::Value *isa_field = Builder.CreateStructGEP(DeclPtr, 0); llvm::Value *forwarding_field = Builder.CreateStructGEP(DeclPtr, 1); llvm::Value *flags_field = Builder.CreateStructGEP(DeclPtr, 2); llvm::Value *size_field = Builder.CreateStructGEP(DeclPtr, 3); llvm::Value *V; - int flag = 0; - int flags = 0; + + BlockFieldFlags fieldFlags; + bool fieldNeedsCopyDispose = false; needsDispose = true; if (Ty->isBlockPointerType()) { - flag |= BLOCK_FIELD_IS_BLOCK; - flags |= BLOCK_HAS_COPY_DISPOSE; + fieldFlags |= BLOCK_FIELD_IS_BLOCK; + fieldNeedsCopyDispose = true; } else if (getContext().isObjCNSObjectType(Ty) || Ty->isObjCObjectPointerType()) { - flag |= BLOCK_FIELD_IS_OBJECT; - flags |= BLOCK_HAS_COPY_DISPOSE; - } else if (getContext().getBlockVarCopyInits(&D)) { - flag |= BLOCK_HAS_CXX_OBJ; - flags |= BLOCK_HAS_COPY_DISPOSE; + fieldFlags |= BLOCK_FIELD_IS_OBJECT; + fieldNeedsCopyDispose = true; + } else if (getLangOptions().CPlusPlus) { + if (getContext().getBlockVarCopyInits(&D)) + fieldNeedsCopyDispose = true; + else if (const CXXRecordDecl *record = D.getType()->getAsCXXRecordDecl()) + fieldNeedsCopyDispose = !record->hasTrivialDestructor(); } // FIXME: Someone double check this. if (Ty.isObjCGCWeak()) - flag |= BLOCK_FIELD_IS_WEAK; + fieldFlags |= BLOCK_FIELD_IS_WEAK; int isa = 0; - if (flag & BLOCK_FIELD_IS_WEAK) + if (fieldFlags & BLOCK_FIELD_IS_WEAK) isa = 1; - V = Builder.CreateIntToPtr(Builder.getInt32(isa), PtrToInt8Ty, "isa"); + V = Builder.CreateIntToPtr(Builder.getInt32(isa), Int8PtrTy, "isa"); Builder.CreateStore(V, isa_field); Builder.CreateStore(DeclPtr, forwarding_field); - Builder.CreateStore(Builder.getInt32(flags), flags_field); + Builder.CreateStore(Builder.getInt32(fieldFlags.getBitMask()), flags_field); const llvm::Type *V1; V1 = cast(DeclPtr->getType())->getElementType(); V = Builder.getInt32(CGM.GetTargetTypeStoreSize(V1).getQuantity()); Builder.CreateStore(V, size_field); - if (flags & BLOCK_HAS_COPY_DISPOSE) { + if (fieldNeedsCopyDispose) { llvm::Value *copy_helper = Builder.CreateStructGEP(DeclPtr, 4); - Builder.CreateStore(BuildbyrefCopyHelper(DeclPtr->getType(), flag, - Align.getQuantity(), &D), + Builder.CreateStore(CGM.BuildbyrefCopyHelper(DeclPtr->getType(), + fieldFlags, + Align.getQuantity(), &D), copy_helper); llvm::Value *destroy_helper = Builder.CreateStructGEP(DeclPtr, 5); - Builder.CreateStore(BuildbyrefDestroyHelper(DeclPtr->getType(), flag, - Align.getQuantity(), &D), + Builder.CreateStore(CGM.BuildbyrefDestroyHelper(DeclPtr->getType(), + fieldFlags, + Align.getQuantity(), &D), destroy_helper); } } @@ -814,10 +815,10 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D, assert(Init != 0 && "Wasn't a simple constant init?"); llvm::Value *SizeVal = - llvm::ConstantInt::get(CGF.IntPtrTy, + llvm::ConstantInt::get(IntPtrTy, getContext().getTypeSizeInChars(Ty).getQuantity()); - const llvm::Type *BP = Builder.getInt8PtrTy(); + const llvm::Type *BP = Int8PtrTy; if (Loc->getType() != BP) Loc = Builder.CreateBitCast(Loc, BP, "tmp"); diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index 8b2d6f5e66..db72080372 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -117,15 +117,13 @@ CodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn, return; } - const llvm::Type *Int8PtrTy = - llvm::Type::getInt8Ty(VMContext)->getPointerTo(); - std::vector Params; Params.push_back(Int8PtrTy); // Get the destructor function type const llvm::Type *DtorFnTy = - llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false); + llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), + Params, false); DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy); Params.clear(); diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index fe51ce67e4..f110f797b0 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -228,7 +228,7 @@ static llvm::Constant *getPersonalityFn(CodeGenModule &CGM, static llvm::Constant *getOpaquePersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality) { llvm::Constant *Fn = getPersonalityFn(CGM, Personality); - return llvm::ConstantExpr::getBitCast(Fn, CGM.PtrToInt8Ty); + return llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy); } /// Check whether a personality function could reasonably be swapped @@ -310,7 +310,7 @@ void CodeGenModule::SimplifyPersonality() { /// presence of a catch-all. static llvm::Constant *getCatchAllValue(CodeGenFunction &CGF) { // Possibly we should use @llvm.eh.catch.all.value here. - return llvm::ConstantPointerNull::get(CGF.CGM.PtrToInt8Ty); + return llvm::ConstantPointerNull::get(CGF.Int8PtrTy); } /// Returns the value to inject into a selector to indicate the @@ -625,8 +625,7 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() { // Save the current IR generation state. CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); - const EHPersonality &Personality = - EHPersonality::get(CGF.CGM.getLangOptions()); + const EHPersonality &Personality = EHPersonality::get(getLangOptions()); // Create and configure the landing pad. llvm::BasicBlock *LP = createBasicBlock("lpad"); @@ -723,7 +722,7 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() { // If we have a catch-all, add null to the selector. if (CatchAll.isValid()) { - EHSelector.push_back(getCatchAllValue(CGF)); + EHSelector.push_back(getCatchAllValue(*this)); // If we have an EH filter, we need to add those handlers in the // right place in the selector, which is to say, at the end. @@ -739,14 +738,14 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() { // Also check whether we need a cleanup. if (UseInvokeInlineHack || HasEHCleanup) EHSelector.push_back(UseInvokeInlineHack - ? getCatchAllValue(CGF) - : getCleanupValue(CGF)); + ? getCatchAllValue(*this) + : getCleanupValue(*this)); // Otherwise, signal that we at least have cleanups. } else if (UseInvokeInlineHack || HasEHCleanup) { EHSelector.push_back(UseInvokeInlineHack - ? getCatchAllValue(CGF) - : getCleanupValue(CGF)); + ? getCatchAllValue(*this) + : getCleanupValue(*this)); } else { assert(LastToEmitInLoop > 2); LastToEmitInLoop--; @@ -788,7 +787,7 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() { // Check whether the exception matches. llvm::CallInst *Id = Builder.CreateCall(llvm_eh_typeid_for, - Builder.CreateBitCast(Type, CGM.PtrToInt8Ty)); + Builder.CreateBitCast(Type, Int8PtrTy)); Id->setDoesNotThrow(); Builder.CreateCondBr(Builder.CreateICmpEQ(Selection, Id), Match, Next); @@ -1314,7 +1313,7 @@ CodeGenFunction::EnterFinallyBlock(const Stmt *Body, JumpDest RethrowDest = getJumpDestInCurrentScope(getUnreachableBlock()); // Whether the finally block is being executed for EH purposes. - llvm::AllocaInst *ForEHVar = CreateTempAlloca(CGF.Builder.getInt1Ty(), + llvm::AllocaInst *ForEHVar = CreateTempAlloca(Builder.getInt1Ty(), "finally.for-eh"); InitTempAlloca(ForEHVar, llvm::ConstantInt::getFalse(getLLVMContext())); @@ -1397,7 +1396,7 @@ llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() { llvm::CallInst *TerminateCall = Builder.CreateCall(getTerminateFn(*this)); TerminateCall->setDoesNotReturn(); TerminateCall->setDoesNotThrow(); - CGF.Builder.CreateUnreachable(); + Builder.CreateUnreachable(); // Restore the saved insertion state. Builder.restoreIP(SavedIP); diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 4dd187f538..019a6c524d 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -29,6 +29,18 @@ using namespace CodeGen; // Miscellaneous Helper Methods //===--------------------------------------------------------------------===// +llvm::Value *CodeGenFunction::EmitCastToVoidPtr(llvm::Value *value) { + unsigned addressSpace = + cast(value->getType())->getAddressSpace(); + + const llvm::PointerType *destType = Int8PtrTy; + if (addressSpace) + destType = llvm::Type::getInt8PtrTy(getLLVMContext(), addressSpace); + + if (value->getType() == destType) return value; + return Builder.CreateBitCast(value, destType); +} + /// CreateTempAlloca - This creates a alloca and inserts it into the entry /// block. llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(const llvm::Type *Ty, @@ -68,7 +80,7 @@ llvm::AllocaInst *CodeGenFunction::CreateMemTemp(QualType Ty, llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) { if (const MemberPointerType *MPT = E->getType()->getAs()) { llvm::Value *MemPtr = EmitScalarExpr(E); - return CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, MemPtr, MPT); + return CGM.getCXXABI().EmitMemberPointerIsNotNull(*this, MemPtr, MPT); } QualType BoolTy = getContext().BoolTy; @@ -350,8 +362,8 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E, if (VD->hasGlobalStorage()) { llvm::Constant *DtorFn = CGM.GetAddrOfCXXDestructor(ReferenceTemporaryDtor, Dtor_Complete); - CGF.EmitCXXGlobalDtorRegistration(DtorFn, - cast(ReferenceTemporary)); + EmitCXXGlobalDtorRegistration(DtorFn, + cast(ReferenceTemporary)); return RValue::get(Value); } @@ -377,14 +389,14 @@ void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) { if (!CatchUndefined) return; - Address = Builder.CreateBitCast(Address, PtrToInt8Ty); + // This needs to be to the standard address space. + Address = Builder.CreateBitCast(Address, Int8PtrTy); const llvm::Type *IntPtrT = IntPtrTy; llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, &IntPtrT, 1); - const llvm::IntegerType *Int1Ty = llvm::Type::getInt1Ty(VMContext); // In time, people may want to control this and use a 1 here. - llvm::Value *Arg = llvm::ConstantInt::get(Int1Ty, 0); + llvm::Value *Arg = Builder.getFalse(); llvm::Value *C = Builder.CreateCall2(F, Address, Arg); llvm::BasicBlock *Cont = createBasicBlock(); llvm::BasicBlock *Check = createBasicBlock(); @@ -497,8 +509,8 @@ LValue CodeGenFunction::EmitCheckedLValue(const Expr *E) { /// LValue CodeGenFunction::EmitLValue(const Expr *E) { llvm::DenseMap::iterator I = - CGF.ConditionalSaveLValueExprs.find(E); - if (I != CGF.ConditionalSaveLValueExprs.end()) + ConditionalSaveLValueExprs.find(E); + if (I != ConditionalSaveLValueExprs.end()) return I->second; switch (E->getStmtClass()) { @@ -702,13 +714,13 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV, // Offset by the byte offset, if used. if (AI.FieldByteOffset) { - const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext); - Ptr = Builder.CreateBitCast(Ptr, i8PTy); + Ptr = EmitCastToVoidPtr(Ptr); Ptr = Builder.CreateConstGEP1_32(Ptr, AI.FieldByteOffset,"bf.field.offs"); } // Cast to the access type. - const llvm::Type *PTy = llvm::Type::getIntNPtrTy(VMContext, AI.AccessWidth, + const llvm::Type *PTy = llvm::Type::getIntNPtrTy(getLLVMContext(), + AI.AccessWidth, ExprType.getAddressSpace()); Ptr = Builder.CreateBitCast(Ptr, PTy); @@ -896,6 +908,8 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, // Get the field pointer. llvm::Value *Ptr = Dst.getBitFieldBaseAddr(); + unsigned addressSpace = + cast(Ptr->getType())->getAddressSpace(); // Only offset by the field index if used, so that incoming values are not // required to be structures. @@ -904,14 +918,15 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, // Offset by the byte offset, if used. if (AI.FieldByteOffset) { - const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext); - Ptr = Builder.CreateBitCast(Ptr, i8PTy); + Ptr = EmitCastToVoidPtr(Ptr); Ptr = Builder.CreateConstGEP1_32(Ptr, AI.FieldByteOffset,"bf.field.offs"); } // Cast to the access type. - const llvm::Type *PTy = llvm::Type::getIntNPtrTy(VMContext, AI.AccessWidth, - Ty.getAddressSpace()); + const llvm::Type *AccessLTy = + llvm::Type::getIntNTy(getLLVMContext(), AI.AccessWidth); + + const llvm::Type *PTy = AccessLTy->getPointerTo(addressSpace); Ptr = Builder.CreateBitCast(Ptr, PTy); // Extract the piece of the bit-field value to write in this access, limited @@ -923,8 +938,6 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, AI.TargetBitWidth)); // Extend or truncate to the access size. - const llvm::Type *AccessLTy = - llvm::Type::getIntNTy(VMContext, AI.AccessWidth); if (ResSizeInBits < AI.AccessWidth) Val = Builder.CreateZExt(Val, AccessLTy); else if (ResSizeInBits > AI.AccessWidth) @@ -1141,7 +1154,7 @@ static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF, LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { const NamedDecl *ND = E->getDecl(); - unsigned Alignment = CGF.getContext().getDeclAlign(ND).getQuantity(); + unsigned Alignment = getContext().getDeclAlign(ND).getQuantity(); if (ND->hasAttr()) { const ValueDecl *VD = cast(ND); @@ -1191,7 +1204,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { LValue CodeGenFunction::EmitBlockDeclRefLValue(const BlockDeclRefExpr *E) { unsigned Alignment = - CGF.getContext().getDeclAlign(E->getDecl()).getQuantity(); + getContext().getDeclAlign(E->getDecl()).getQuantity(); return MakeAddrLValue(GetAddrOfBlockDecl(E), E->getType(), Alignment); } @@ -1368,7 +1381,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) { // Emit the vector as an lvalue to get its address. LValue LHS = EmitLValue(E->getBase()); assert(LHS.isSimple() && "Can only subscript lvalue vectors here!"); - Idx = Builder.CreateIntCast(Idx, CGF.Int32Ty, IdxSigned, "vidx"); + Idx = Builder.CreateIntCast(Idx, Int32Ty, IdxSigned, "vidx"); return LValue::MakeVectorElt(LHS.getAddress(), Idx, E->getBase()->getType().getCVRQualifiers()); } @@ -1406,13 +1419,11 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) { Idx = Builder.CreateMul(Idx, VLASize); - const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext); - // The base must be a pointer, which is not an aggregate. Emit it. llvm::Value *Base = EmitScalarExpr(E->getBase()); - - Address = Builder.CreateInBoundsGEP(Builder.CreateBitCast(Base, i8PTy), - Idx, "arrayidx"); + + Address = EmitCastToVoidPtr(Base); + Address = Builder.CreateInBoundsGEP(Address, Idx, "arrayidx"); Address = Builder.CreateBitCast(Address, Base->getType()); } else if (const ObjCObjectType *OIT = E->getType()->getAs()){ // Indexing over an interface, as in "NSString *P; P[4];" @@ -1422,12 +1433,10 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) { Idx = Builder.CreateMul(Idx, InterfaceSize); - const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext); - // The base must be a pointer, which is not an aggregate. Emit it. llvm::Value *Base = EmitScalarExpr(E->getBase()); - Address = Builder.CreateGEP(Builder.CreateBitCast(Base, i8PTy), - Idx, "arrayidx"); + Address = EmitCastToVoidPtr(Base); + Address = Builder.CreateGEP(Address, Idx, "arrayidx"); Address = Builder.CreateBitCast(Address, Base->getType()); } else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) { // If this is A[i] where A is an array, the frontend will have decayed the @@ -1509,7 +1518,7 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) { E->getEncodedElementAccess(Indices); if (Base.isSimple()) { - llvm::Constant *CV = GenerateConstantVector(VMContext, Indices); + llvm::Constant *CV = GenerateConstantVector(getLLVMContext(), Indices); return LValue::MakeExtVectorElt(Base.getAddress(), CV, Base.getVRQualifiers()); } diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 3a758a8102..ad62a3ba53 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -901,12 +901,12 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr, const llvm::PointerType *DPT = cast(DestPtr->getType()); const llvm::Type *DBP = - llvm::Type::getInt8PtrTy(VMContext, DPT->getAddressSpace()); + llvm::Type::getInt8PtrTy(getLLVMContext(), DPT->getAddressSpace()); DestPtr = Builder.CreateBitCast(DestPtr, DBP, "tmp"); const llvm::PointerType *SPT = cast(SrcPtr->getType()); const llvm::Type *SBP = - llvm::Type::getInt8PtrTy(VMContext, SPT->getAddressSpace()); + llvm::Type::getInt8PtrTy(getLLVMContext(), SPT->getAddressSpace()); SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp"); if (const RecordType *RecordTy = Ty->getAs()) { diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index bd971af96d..bba7864bff 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -279,7 +279,7 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, // Ask the ABI to load the callee. Note that This is modified. llvm::Value *Callee = - CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(CGF, This, MemFnPtr, MPT); + CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(*this, This, MemFnPtr, MPT); CallArgList Args; @@ -692,11 +692,7 @@ CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E, static void EmitZeroMemSet(CodeGenFunction &CGF, QualType T, llvm::Value *NewPtr, llvm::Value *Size) { - llvm::LLVMContext &VMContext = CGF.CGM.getLLVMContext(); - const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext); - if (NewPtr->getType() != BP) - NewPtr = CGF.Builder.CreateBitCast(NewPtr, BP, "tmp"); - + CGF.EmitCastToVoidPtr(NewPtr); CharUnits Alignment = CGF.getContext().getTypeAlignInChars(T); CGF.Builder.CreateMemSet(NewPtr, CGF.Builder.getInt8(0), Size, Alignment.getQuantity(), false); @@ -1011,7 +1007,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { CalculateCookiePadding(*this, E).isZero()); if (AllocSize != AllocSizeWithoutCookie) { assert(E->isArray()); - NewPtr = CGM.getCXXABI().InitializeArrayCookie(CGF, NewPtr, NumElements, + NewPtr = CGM.getCXXABI().InitializeArrayCookie(*this, NewPtr, NumElements, E, AllocType); } @@ -1345,7 +1341,7 @@ llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { NonZeroBlock, ZeroBlock); EmitBlock(ZeroBlock); /// Call __cxa_bad_typeid - const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext); + const llvm::Type *ResultType = llvm::Type::getVoidTy(getLLVMContext()); const llvm::FunctionType *FTy; FTy = llvm::FunctionType::get(ResultType, false); llvm::Value *F = CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid"); @@ -1413,19 +1409,17 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(llvm::Value *V, V = GetVTablePtr(This, PtrDiffTy->getPointerTo()); V = Builder.CreateConstInBoundsGEP1_64(V, -2ULL); V = Builder.CreateLoad(V, "offset to top"); - This = Builder.CreateBitCast(This, llvm::Type::getInt8PtrTy(VMContext)); + This = EmitCastToVoidPtr(This); V = Builder.CreateInBoundsGEP(This, V); V = Builder.CreateBitCast(V, LTy); } else { /// Call __dynamic_cast - const llvm::Type *ResultType = llvm::Type::getInt8PtrTy(VMContext); + const llvm::Type *ResultType = Int8PtrTy; const llvm::FunctionType *FTy; std::vector ArgTys; - const llvm::Type *PtrToInt8Ty - = llvm::Type::getInt8Ty(VMContext)->getPointerTo(); - ArgTys.push_back(PtrToInt8Ty); - ArgTys.push_back(PtrToInt8Ty); - ArgTys.push_back(PtrToInt8Ty); + ArgTys.push_back(Int8PtrTy); + ArgTys.push_back(Int8PtrTy); + ArgTys.push_back(Int8PtrTy); ArgTys.push_back(PtrDiffTy); FTy = llvm::FunctionType::get(ResultType, ArgTys, false); @@ -1440,7 +1434,7 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(llvm::Value *V, llvm::Value *DestArg = CGM.GetAddrOfRTTIDescriptor(DestTy.getUnqualifiedType()); - V = Builder.CreateBitCast(V, PtrToInt8Ty); + V = Builder.CreateBitCast(V, Int8PtrTy); V = Builder.CreateCall4(CGM.CreateRuntimeFunction(FTy, "__dynamic_cast"), V, SrcArg, DestArg, hint); V = Builder.CreateBitCast(V, LTy); @@ -1450,7 +1444,7 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(llvm::Value *V, Builder.CreateCondBr(Builder.CreateIsNotNull(V), ContBlock, BadCastBlock); EmitBlock(BadCastBlock); /// Invoke __cxa_bad_cast - ResultType = llvm::Type::getVoidTy(VMContext); + ResultType = llvm::Type::getVoidTy(getLLVMContext()); const llvm::FunctionType *FBadTy; FBadTy = llvm::FunctionType::get(ResultType, false); llvm::Value *F = CGM.CreateRuntimeFunction(FBadTy, "__cxa_bad_cast"); diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 9627125491..be7c79cbb5 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -16,6 +16,7 @@ #include "CGRecordLayout.h" #include "CodeGenModule.h" #include "CodeGenFunction.h" +#include "CGBlocks.h" #include "CGCleanup.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index b0278c7d02..60aa7541cf 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -335,8 +335,7 @@ void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) { // Ensure that we have an i8* for our PHI node. llvm::Value *V = Builder.CreateBitCast(EmitScalarExpr(S.getTarget()), - llvm::Type::getInt8PtrTy(VMContext), - "addr"); + Int8PtrTy, "addr"); llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); @@ -657,11 +656,8 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { // If there is an NRVO flag for this variable, set it to 1 into indicate // that the cleanup code should not destroy the variable. - if (llvm::Value *NRVOFlag = NRVOFlags[S.getNRVOCandidate()]) { - const llvm::Type *BoolTy = llvm::Type::getInt1Ty(VMContext); - llvm::Value *One = llvm::ConstantInt::get(BoolTy, 1); - Builder.CreateStore(One, NRVOFlag); - } + if (llvm::Value *NRVOFlag = NRVOFlags[S.getNRVOCandidate()]) + Builder.CreateStore(Builder.getTrue(), NRVOFlag); } else if (!ReturnValue) { // Make sure not to return anything, but evaluate the expression // for side effects. @@ -749,7 +745,8 @@ void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) { if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) { // Range is small enough to add multiple switch instruction cases. for (unsigned i = 0, e = Range.getZExtValue() + 1; i != e; ++i) { - SwitchInsn->addCase(llvm::ConstantInt::get(VMContext, LHS), CaseDest); + SwitchInsn->addCase(llvm::ConstantInt::get(getLLVMContext(), LHS), + CaseDest); LHS++; } return; @@ -771,10 +768,10 @@ void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) { // Emit range check. llvm::Value *Diff = Builder.CreateSub(SwitchInsn->getCondition(), - llvm::ConstantInt::get(VMContext, LHS), "tmp"); + llvm::ConstantInt::get(getLLVMContext(), LHS), "tmp"); llvm::Value *Cond = - Builder.CreateICmpULE(Diff, - llvm::ConstantInt::get(VMContext, Range), "tmp"); + Builder.CreateICmpULE(Diff, llvm::ConstantInt::get(getLLVMContext(), Range), + "inbounds"); Builder.CreateCondBr(Cond, CaseDest, FalseDest); // Restore the appropriate insertion point. @@ -793,7 +790,8 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { EmitBlock(createBasicBlock("sw.bb")); llvm::BasicBlock *CaseDest = Builder.GetInsertBlock(); llvm::APSInt CaseVal = S.getLHS()->EvaluateAsInt(getContext()); - SwitchInsn->addCase(llvm::ConstantInt::get(VMContext, CaseVal), CaseDest); + SwitchInsn->addCase(llvm::ConstantInt::get(getLLVMContext(), CaseVal), + CaseDest); // Recursively emitting the statement is acceptable, but is not wonderful for // code where we have many case statements nested together, i.e.: @@ -811,7 +809,8 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { while (NextCase && NextCase->getRHS() == 0) { CurCase = NextCase; CaseVal = CurCase->getLHS()->EvaluateAsInt(getContext()); - SwitchInsn->addCase(llvm::ConstantInt::get(VMContext, CaseVal), CaseDest); + SwitchInsn->addCase(llvm::ConstantInt::get(getLLVMContext(), CaseVal), + CaseDest); NextCase = dyn_cast(CurCase->getSubStmt()); } @@ -975,7 +974,7 @@ CodeGenFunction::EmitAsmInputLValue(const AsmStmt &S, const llvm::Type *Ty = ConvertType(InputType); uint64_t Size = CGM.getTargetData().getTypeSizeInBits(Ty); if (Size <= 64 && llvm::isPowerOf2_64(Size)) { - Ty = llvm::IntegerType::get(VMContext, Size); + Ty = llvm::IntegerType::get(getLLVMContext(), Size); Ty = llvm::PointerType::getUnqual(Ty); Arg = Builder.CreateLoad(Builder.CreateBitCast(InputValue.getAddress(), @@ -1138,7 +1137,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { } if (const llvm::Type* AdjTy = Target.adjustInlineAsmType(OutputConstraint, ResultRegTypes.back(), - VMContext)) + getLLVMContext())) ResultRegTypes.back() = AdjTy; } else { ArgTypes.push_back(Dest.getAddress()->getType()); @@ -1210,7 +1209,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { } if (const llvm::Type* AdjTy = Target.adjustInlineAsmType(InputConstraint, Arg->getType(), - VMContext)) + getLLVMContext())) Arg = Builder.CreateBitCast(Arg, AdjTy); ArgTypes.push_back(Arg->getType()); @@ -1249,11 +1248,11 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { const llvm::Type *ResultType; if (ResultRegTypes.empty()) - ResultType = llvm::Type::getVoidTy(VMContext); + ResultType = llvm::Type::getVoidTy(getLLVMContext()); else if (ResultRegTypes.size() == 1) ResultType = ResultRegTypes[0]; else - ResultType = llvm::StructType::get(VMContext, ResultRegTypes); + ResultType = llvm::StructType::get(getLLVMContext(), ResultRegTypes); const llvm::FunctionType *FTy = llvm::FunctionType::get(ResultType, ArgTypes, false); @@ -1293,13 +1292,13 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { Tmp = Builder.CreateFPTrunc(Tmp, TruncTy); else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) { uint64_t ResSize = CGM.getTargetData().getTypeSizeInBits(TruncTy); - Tmp = Builder.CreateTrunc(Tmp, llvm::IntegerType::get(VMContext, - (unsigned)ResSize)); + Tmp = Builder.CreateTrunc(Tmp, + llvm::IntegerType::get(getLLVMContext(), (unsigned)ResSize)); Tmp = Builder.CreateIntToPtr(Tmp, TruncTy); } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) { uint64_t TmpSize =CGM.getTargetData().getTypeSizeInBits(Tmp->getType()); - Tmp = Builder.CreatePtrToInt(Tmp, llvm::IntegerType::get(VMContext, - (unsigned)TmpSize)); + Tmp = Builder.CreatePtrToInt(Tmp, + llvm::IntegerType::get(getLLVMContext(), (unsigned)TmpSize)); Tmp = Builder.CreateTrunc(Tmp, TruncTy); } else if (TruncTy->isIntegerTy()) { Tmp = Builder.CreateTrunc(Tmp, TruncTy); diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index d74226ec89..4bf67b53a3 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -2668,7 +2668,7 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD, } if (!ResultType->isVoidType() && Slot.isNull()) - CGM.getCXXABI().EmitReturnFromThunk(CGF, RV, ResultType); + CGM.getCXXABI().EmitReturnFromThunk(*this, RV, ResultType); FinishFunction(); diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index d887943871..66114c87a4 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -29,9 +29,9 @@ using namespace clang; using namespace CodeGen; CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) - : BlockFunction(cgm, *this, Builder), CGM(cgm), - Target(CGM.getContext().Target), + : CGM(cgm), Target(CGM.getContext().Target), Builder(cgm.getModule().getContext()), + BlockInfo(0), BlockPointer(0), NormalCleanupDest(0), EHCleanupDest(0), NextCleanupDestIndex(1), ExceptionSlot(0), DebugInfo(0), IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), @@ -46,6 +46,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) IntPtrTy = llvm::IntegerType::get(LLVMContext, LLVMPointerWidth); Int32Ty = llvm::Type::getInt32Ty(LLVMContext); Int64Ty = llvm::Type::getInt64Ty(LLVMContext); + Int8PtrTy = cgm.Int8PtrTy; Exceptions = getContext().getLangOptions().Exceptions; CatchUndefined = getContext().getLangOptions().CatchUndefined; @@ -192,12 +193,11 @@ void CodeGenFunction::EmitFunctionInstrumentation(const char *Fn) { std::vector ProfileFuncArgs; // void __cyg_profile_func_{enter,exit} (void *this_fn, void *call_site); - PointerTy = llvm::Type::getInt8PtrTy(VMContext); + PointerTy = Int8PtrTy; ProfileFuncArgs.push_back(PointerTy); ProfileFuncArgs.push_back(PointerTy); - FunctionTy = llvm::FunctionType::get( - llvm::Type::getVoidTy(VMContext), - ProfileFuncArgs, false); + FunctionTy = llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), + ProfileFuncArgs, false); llvm::Constant *F = CGM.CreateRuntimeFunction(FunctionTy, Fn); llvm::CallInst *CallSite = Builder.CreateCall( @@ -671,8 +671,6 @@ llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() { CGBuilderTy TmpBuilder(createBasicBlock("indirectgoto")); - const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); - // Create the PHI node that indirect gotos will add entries to. llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, "indirect.goto.dest"); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index d7ea784ee5..f591840d92 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -24,7 +24,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ValueHandle.h" #include "CodeGenModule.h" -#include "CGBlocks.h" #include "CGBuilder.h" #include "CGCall.h" #include "CGValue.h" @@ -71,6 +70,8 @@ namespace CodeGen { class CGRecordLayout; class CGBlockInfo; class CGCXXABI; + class BlockFlags; + class BlockFieldFlags; /// A branch fixup. These are required when emitting a goto to a /// label which hasn't been emitted yet. The goto is optimistically @@ -502,7 +503,7 @@ public: /// CodeGenFunction - This class organizes the per-function state that is used /// while generating LLVM code. -class CodeGenFunction : public BlockFunction { +class CodeGenFunction { CodeGenFunction(const CodeGenFunction&); // DO NOT IMPLEMENT void operator=(const CodeGenFunction&); // DO NOT IMPLEMENT @@ -584,9 +585,14 @@ public: const llvm::IntegerType *IntPtrTy, *Int32Ty, *Int64Ty; uint32_t LLVMPointerWidth; + const llvm::PointerType *Int8PtrTy; + bool Exceptions; bool CatchUndefined; + const CodeGen::CGBlockInfo *BlockInfo; + llvm::Value *BlockPointer; + /// \brief A mapping from NRVO variables to the flags used to indicate /// when the NRVO has been applied to this variable. llvm::DenseMap NRVOFlags; @@ -932,6 +938,8 @@ public: ASTContext &getContext() const; CGDebugInfo *getDebugInfo() { return DebugInfo; } + const LangOptions &getLangOptions() const { return CGM.getLangOptions(); } + /// Returns a pointer to the function's exception object slot, which /// is assigned in every landing pad. llvm::Value *getExceptionSlot(); @@ -952,7 +960,7 @@ public: return getInvokeDestImpl(); } - llvm::LLVMContext &getLLVMContext() { return VMContext; } + llvm::LLVMContext &getLLVMContext() { return CGM.getLLVMContext(); } //===--------------------------------------------------------------------===// // Objective-C @@ -984,14 +992,25 @@ public: llvm::Constant *BuildDescriptorBlockDecl(const BlockExpr *, const CGBlockInfo &Info, const llvm::StructType *, - llvm::Constant *BlockVarLayout, - std::vector *); + llvm::Constant *BlockVarLayout); llvm::Function *GenerateBlockFunction(GlobalDecl GD, const CGBlockInfo &Info, const Decl *OuterFuncDecl, const DeclMapTy &ldm); + llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo); + llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo); + + llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, + BlockFieldFlags flags, + const VarDecl *BD); + llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, + BlockFieldFlags flags, + const VarDecl *BD); + + void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags); + llvm::Value *LoadBlockStruct() { assert(BlockPointer && "no block pointer set!"); return BlockPointer; @@ -1111,13 +1130,13 @@ public: static bool hasAggregateLLVMType(QualType T); /// createBasicBlock - Create an LLVM basic block. - llvm::BasicBlock *createBasicBlock(const char *Name="", - llvm::Function *Parent=0, - llvm::BasicBlock *InsertBefore=0) { + llvm::BasicBlock *createBasicBlock(llvm::StringRef name = "", + llvm::Function *parent = 0, + llvm::BasicBlock *before = 0) { #ifdef NDEBUG - return llvm::BasicBlock::Create(VMContext, "", Parent, InsertBefore); + return llvm::BasicBlock::Create(getLLVMContext(), "", parent, before); #else - return llvm::BasicBlock::Create(VMContext, Name, Parent, InsertBefore); + return llvm::BasicBlock::Create(getLLVMContext(), name, parent, before); #endif } @@ -1205,6 +1224,9 @@ public: return AggValueSlot::forAddr(CreateMemTemp(T, Name), false, false); } + /// Emit a cast to void* in the appropriate address space. + llvm::Value *EmitCastToVoidPtr(llvm::Value *value); + /// EvaluateExprAsBool - Perform the usual unary conversions on the specified /// expression and compare the result against zero, returning an Int1Ty value. llvm::Value *EvaluateExprAsBool(const Expr *E); @@ -2022,76 +2044,6 @@ template <> struct DominatingValue { } }; -/// CGBlockInfo - Information to generate a block literal. -class CGBlockInfo { -public: - /// Name - The name of the block, kindof. - const char *Name; - - /// The field index of 'this' within the block, if there is one. - unsigned CXXThisIndex; - - class Capture { - uintptr_t Data; - - public: - bool isIndex() const { return (Data & 1) != 0; } - bool isConstant() const { return !isIndex(); } - unsigned getIndex() const { assert(isIndex()); return Data >> 1; } - llvm::Value *getConstant() const { - assert(isConstant()); - return reinterpret_cast(Data); - } - - static Capture makeIndex(unsigned index) { - Capture v; - v.Data = (index << 1) | 1; - return v; - } - - static Capture makeConstant(llvm::Value *value) { - Capture v; - v.Data = reinterpret_cast(value); - return v; - } - }; - - /// The mapping of allocated indexes within the block. - llvm::DenseMap Captures; - - /// CanBeGlobal - True if the block can be global, i.e. it has - /// no non-constant captures. - bool CanBeGlobal : 1; - - /// True if the block needs a custom copy or dispose function. - bool NeedsCopyDispose : 1; - - /// HasCXXObject - True if the block's custom copy/dispose functions - /// need to be run even in GC mode. - bool HasCXXObject : 1; - - /// HasWeakBlockVariable - True if block captures a weak __block variable. - bool HasWeakBlockVariable : 1; - - const llvm::StructType *StructureType; - const BlockExpr *Block; - CharUnits BlockSize; - CharUnits BlockAlign; - llvm::SmallVector BlockLayout; - - const Capture &getCapture(const VarDecl *var) const { - llvm::DenseMap::const_iterator - it = Captures.find(var); - assert(it != Captures.end() && "no entry for variable!"); - return it->second; - } - - const BlockDecl *getBlockDecl() const { return Block->getBlockDecl(); } - const BlockExpr *getBlockExpr() const { return Block; } - - CGBlockInfo(const BlockExpr *blockExpr, const char *Name); -}; - } // end namespace CodeGen } // end namespace clang diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 82365aab42..89aeeb6fc7 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -58,8 +58,7 @@ static CGCXXABI &createCXXABI(CodeGenModule &CGM) { CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, llvm::Module &M, const llvm::TargetData &TD, Diagnostic &diags) - : BlockModule(C, M, TD, Types, *this), Context(C), - Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M), + : Context(C), Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M), TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags), ABI(createCXXABI(*this)), Types(C, M, TD, getTargetCodeGenInfo().getABIInfo(), ABI), @@ -70,8 +69,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, NSConcreteGlobalBlockDecl(0), NSConcreteStackBlockDecl(0), NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockObjectAssignDecl(0), BlockObjectDisposeDecl(0), - BlockObjectAssign(0), BlockObjectDispose(0){ - + BlockObjectAssign(0), BlockObjectDispose(0), + BlockDescriptorType(0), GenericBlockLiteralType(0) { if (!Features.ObjC1) Runtime = 0; else if (!Features.NeXTRuntime) @@ -88,6 +87,9 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, // If debug info generation is enabled, create the CGDebugInfo object. DebugInfo = CodeGenOpts.DebugInfo ? new CGDebugInfo(*this) : 0; + + Block.GlobalUniqueCount = 0; + Int8PtrTy = llvm::Type::getInt8PtrTy(M.getContext()); } CodeGenModule::~CodeGenModule() { @@ -2170,7 +2172,7 @@ llvm::Constant *CodeGenModule::getBlockObjectDispose() { const llvm::FunctionType *FTy; std::vector ArgTys; const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext); - ArgTys.push_back(PtrToInt8Ty); + ArgTys.push_back(Int8PtrTy); ArgTys.push_back(llvm::Type::getInt32Ty(VMContext)); FTy = llvm::FunctionType::get(ResultType, ArgTys, false); return BlockObjectDispose = @@ -2192,8 +2194,8 @@ llvm::Constant *CodeGenModule::getBlockObjectAssign() { const llvm::FunctionType *FTy; std::vector ArgTys; const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext); - ArgTys.push_back(PtrToInt8Ty); - ArgTys.push_back(PtrToInt8Ty); + ArgTys.push_back(Int8PtrTy); + ArgTys.push_back(Int8PtrTy); ArgTys.push_back(llvm::Type::getInt32Ty(VMContext)); FTy = llvm::FunctionType::get(ResultType, ArgTys, false); return BlockObjectAssign = @@ -2212,8 +2214,8 @@ llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() { } // Otherwise construct the variable by hand. - return NSConcreteGlobalBlock = CreateRuntimeVariable( - PtrToInt8Ty, "_NSConcreteGlobalBlock"); + return NSConcreteGlobalBlock = + CreateRuntimeVariable(Int8PtrTy, "_NSConcreteGlobalBlock"); } llvm::Constant *CodeGenModule::getNSConcreteStackBlock() { @@ -2228,8 +2230,8 @@ llvm::Constant *CodeGenModule::getNSConcreteStackBlock() { } // Otherwise construct the variable by hand. - return NSConcreteStackBlock = CreateRuntimeVariable( - PtrToInt8Ty, "_NSConcreteStackBlock"); + return NSConcreteStackBlock = + CreateRuntimeVariable(Int8PtrTy, "_NSConcreteStackBlock"); } ///@} diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 1ed56d5b92..5d2e581ec3 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -20,7 +20,6 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Mangle.h" -#include "CGBlocks.h" #include "CGCall.h" #include "CGVTables.h" #include "CodeGenTypes.h" @@ -75,6 +74,7 @@ namespace CodeGen { class CGCXXABI; class CGDebugInfo; class CGObjCRuntime; + class BlockFieldFlags; struct OrderGlobalInits { unsigned int priority; @@ -97,7 +97,7 @@ namespace CodeGen { /// CodeGenModule - This class organizes the cross-function state that is used /// while generating LLVM code. -class CodeGenModule : public BlockModule { +class CodeGenModule { CodeGenModule(const CodeGenModule&); // DO NOT IMPLEMENT void operator=(const CodeGenModule&); // DO NOT IMPLEMENT @@ -207,6 +207,16 @@ class CodeGenModule : public BlockModule { llvm::Constant *BlockObjectAssign; llvm::Constant *BlockObjectDispose; + const llvm::Type *BlockDescriptorType; + const llvm::Type *GenericBlockLiteralType; + + struct { + int GlobalUniqueCount; + } Block; + + llvm::DenseMap AssignCache; + llvm::DenseMap DestroyCache; + /// @} public: CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts, @@ -217,6 +227,8 @@ public: /// Release - Finalize LLVM code generation. void Release(); + const llvm::PointerType *Int8PtrTy; + /// getObjCRuntime() - Return a reference to the configured /// Objective-C runtime. CGObjCRuntime &getObjCRuntime() { @@ -248,6 +260,7 @@ public: CodeGenVTables &getVTables() { return VTables; } Diagnostic &getDiags() const { return Diags; } const llvm::TargetData &getTargetData() const { return TheTargetData; } + const TargetInfo &getTarget() const { return Context.Target; } llvm::LLVMContext &getLLVMContext() { return VMContext; } const TargetCodeGenInfo &getTargetCodeGenInfo(); bool isTargetDarwin() const; @@ -336,6 +349,29 @@ public: GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd); + + llvm::Constant *BuildbyrefCopyHelper(const llvm::Type *T, + BlockFieldFlags flags, + unsigned Align, + const VarDecl *variable); + llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type *T, + BlockFieldFlags flags, + unsigned Align, + const VarDecl *variable); + + /// getGlobalUniqueCount - Fetches the global unique block count. + int getGlobalUniqueCount() { return ++Block.GlobalUniqueCount; } + + /// getBlockDescriptorType - Fetches the type of a generic block + /// descriptor. + const llvm::Type *getBlockDescriptorType(); + + /// getGenericBlockLiteralType - The type of a generic block literal. + const llvm::Type *getGenericBlockLiteralType(); + + /// GetAddrOfGlobalBlock - Gets the address of a block which + /// requires no captures. + llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *); /// GetStringForStringLiteral - Return the appropriate bytes for a string /// literal, properly padded to match the literal type. If only the address of