diff options
author | John McCall <rjmccall@apple.com> | 2010-08-07 08:21:30 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-08-07 08:21:30 +0000 |
commit | 9021718882441dd391a1960084580d3cd19c423a (patch) | |
tree | da6d1dd06ee722faa32105c1c54859db107bef0f /lib/CodeGen/CodeGenFunction.cpp | |
parent | f8cf0b028c7a5b632c3a711813cd44a9d9642537 (diff) |
Inline a special case of EmitAggregateCopy into EmitNullInitialization
to avoid the awesome-but-wrong-in-this-case assertion in the canon EAC.
Fixes PR7834.
Also fix a subtle address-space bug in the memset path.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110511 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 68 |
1 files changed, 41 insertions, 27 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 35664af219..a3cd4f4c29 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -545,21 +545,6 @@ void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type, void CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) { - // If the type contains a pointer to data member we can't memset it to zero. - // Instead, create a null constant and copy it to the destination. - if (CGM.getTypes().ContainsPointerToDataMember(Ty)) { - llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty); - - llvm::GlobalVariable *NullVariable = - new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(), - /*isConstant=*/true, - llvm::GlobalVariable::PrivateLinkage, - NullConstant, llvm::Twine()); - EmitAggregateCopy(DestPtr, NullVariable, Ty, /*isVolatile=*/false); - return; - } - - // Ignore empty classes in C++. if (getContext().getLangOptions().CPlusPlus) { if (const RecordType *RT = Ty->getAs<RecordType>()) { @@ -567,29 +552,58 @@ CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) { return; } } - - // Otherwise, just memset the whole thing to zero. This is legal - // because in LLVM, all default initializers (other than the ones we just - // handled above) are guaranteed to have a bit pattern of all zeros. - const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext); + + // Cast the dest ptr to the appropriate i8 pointer type. + unsigned DestAS = + cast<llvm::PointerType>(DestPtr->getType())->getAddressSpace(); + const llvm::Type *BP = + llvm::Type::getInt8PtrTy(VMContext, DestAS); if (DestPtr->getType() != BP) DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp"); // Get size and alignment info for this aggregate. std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty); + uint64_t Size = TypeInfo.first; + unsigned Align = TypeInfo.second; // Don't bother emitting a zero-byte memset. - if (TypeInfo.first == 0) + if (Size == 0) return; + llvm::ConstantInt *SizeVal = llvm::ConstantInt::get(IntPtrTy, Size / 8); + llvm::ConstantInt *AlignVal = Builder.getInt32(Align / 8); + + // If the type contains a pointer to data member we can't memset it to zero. + // Instead, create a null constant and copy it to the destination. + if (CGM.getTypes().ContainsPointerToDataMember(Ty)) { + llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty); + + llvm::GlobalVariable *NullVariable = + new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(), + /*isConstant=*/true, + llvm::GlobalVariable::PrivateLinkage, + NullConstant, llvm::Twine()); + llvm::Value *SrcPtr = + Builder.CreateBitCast(NullVariable, Builder.getInt8PtrTy()); + + // FIXME: variable-size types? + + // Get and call the appropriate llvm.memcpy overload. + llvm::Constant *Memcpy = + CGM.getMemCpyFn(DestPtr->getType(), SrcPtr->getType(), IntPtrTy); + Builder.CreateCall5(Memcpy, DestPtr, SrcPtr, SizeVal, AlignVal, + /*volatile*/ Builder.getFalse()); + return; + } + + // Otherwise, just memset the whole thing to zero. This is legal + // because in LLVM, all default initializers (other than the ones we just + // handled above) are guaranteed to have a bit pattern of all zeros. + // FIXME: Handle variable sized types. Builder.CreateCall5(CGM.getMemSetFn(BP, IntPtrTy), DestPtr, - llvm::Constant::getNullValue(llvm::Type::getInt8Ty(VMContext)), - // TypeInfo.first describes size in bits. - llvm::ConstantInt::get(IntPtrTy, TypeInfo.first/8), - llvm::ConstantInt::get(Int32Ty, TypeInfo.second/8), - llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), - 0)); + Builder.getInt8(0), + SizeVal, AlignVal, /*volatile*/ Builder.getFalse()); } llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) { |