CGExprAgg.cpp revision 218893
1193326Sed//===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This contains code to emit Aggregate Expr nodes as LLVM code. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#include "CodeGenFunction.h" 15193326Sed#include "CodeGenModule.h" 16198092Srdivacky#include "CGObjCRuntime.h" 17193326Sed#include "clang/AST/ASTContext.h" 18193326Sed#include "clang/AST/DeclCXX.h" 19193326Sed#include "clang/AST/StmtVisitor.h" 20193326Sed#include "llvm/Constants.h" 21193326Sed#include "llvm/Function.h" 22193326Sed#include "llvm/GlobalVariable.h" 23193326Sed#include "llvm/Intrinsics.h" 24193326Sedusing namespace clang; 25193326Sedusing namespace CodeGen; 26193326Sed 27193326Sed//===----------------------------------------------------------------------===// 28193326Sed// Aggregate Expression Emitter 29193326Sed//===----------------------------------------------------------------------===// 30193326Sed 31193326Sednamespace { 32199990Srdivackyclass AggExprEmitter : public StmtVisitor<AggExprEmitter> { 33193326Sed CodeGenFunction &CGF; 34193326Sed CGBuilderTy &Builder; 35218893Sdim AggValueSlot Dest; 36193326Sed bool IgnoreResult; 37208600Srdivacky 38208600Srdivacky ReturnValueSlot getReturnValueSlot() const { 39208600Srdivacky // If the destination slot requires garbage collection, we can't 40208600Srdivacky // use the real return value slot, because we have to use the GC 41208600Srdivacky // API. 42218893Sdim if (Dest.requiresGCollection()) return ReturnValueSlot(); 43208600Srdivacky 44218893Sdim return ReturnValueSlot(Dest.getAddr(), Dest.isVolatile()); 45208600Srdivacky } 46208600Srdivacky 47218893Sdim AggValueSlot EnsureSlot(QualType T) { 48218893Sdim if (!Dest.isIgnored()) return Dest; 49218893Sdim return CGF.CreateAggTemp(T, "agg.tmp.ensured"); 50218893Sdim } 51218893Sdim 52193326Sedpublic: 53218893Sdim AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest, 54218893Sdim bool ignore) 55218893Sdim : CGF(cgf), Builder(CGF.Builder), Dest(Dest), 56218893Sdim IgnoreResult(ignore) { 57193326Sed } 58193326Sed 59193326Sed //===--------------------------------------------------------------------===// 60193326Sed // Utilities 61193326Sed //===--------------------------------------------------------------------===// 62193326Sed 63193326Sed /// EmitAggLoadOfLValue - Given an expression with aggregate type that 64193326Sed /// represents a value lvalue, this method emits the address of the lvalue, 65193326Sed /// then loads the result into DestPtr. 66193326Sed void EmitAggLoadOfLValue(const Expr *E); 67193326Sed 68193326Sed /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired. 69193326Sed void EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore = false); 70193326Sed void EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore = false); 71193326Sed 72208600Srdivacky void EmitGCMove(const Expr *E, RValue Src); 73208600Srdivacky 74208600Srdivacky bool TypeRequiresGCollection(QualType T); 75208600Srdivacky 76193326Sed //===--------------------------------------------------------------------===// 77193326Sed // Visitor Methods 78193326Sed //===--------------------------------------------------------------------===// 79198092Srdivacky 80193326Sed void VisitStmt(Stmt *S) { 81193326Sed CGF.ErrorUnsupported(S, "aggregate expression"); 82193326Sed } 83193326Sed void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); } 84193326Sed void VisitUnaryExtension(UnaryOperator *E) { Visit(E->getSubExpr()); } 85193326Sed 86193326Sed // l-values. 87193326Sed void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); } 88193326Sed void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); } 89193326Sed void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); } 90193326Sed void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); } 91193326Sed void VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { 92198092Srdivacky EmitAggLoadOfLValue(E); 93193326Sed } 94193326Sed void VisitArraySubscriptExpr(ArraySubscriptExpr *E) { 95193326Sed EmitAggLoadOfLValue(E); 96193326Sed } 97193326Sed void VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) { 98198092Srdivacky EmitAggLoadOfLValue(E); 99193326Sed } 100193326Sed void VisitPredefinedExpr(const PredefinedExpr *E) { 101198092Srdivacky EmitAggLoadOfLValue(E); 102193326Sed } 103198092Srdivacky 104193326Sed // Operators. 105198092Srdivacky void VisitCastExpr(CastExpr *E); 106193326Sed void VisitCallExpr(const CallExpr *E); 107193326Sed void VisitStmtExpr(const StmtExpr *E); 108193326Sed void VisitBinaryOperator(const BinaryOperator *BO); 109198398Srdivacky void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO); 110193326Sed void VisitBinAssign(const BinaryOperator *E); 111193326Sed void VisitBinComma(const BinaryOperator *E); 112193326Sed 113193326Sed void VisitObjCMessageExpr(ObjCMessageExpr *E); 114193326Sed void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 115193326Sed EmitAggLoadOfLValue(E); 116193326Sed } 117193326Sed void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E); 118198092Srdivacky 119218893Sdim void VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO); 120198092Srdivacky void VisitChooseExpr(const ChooseExpr *CE); 121193326Sed void VisitInitListExpr(InitListExpr *E); 122201361Srdivacky void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E); 123193326Sed void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { 124193326Sed Visit(DAE->getExpr()); 125193326Sed } 126193326Sed void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E); 127193326Sed void VisitCXXConstructExpr(const CXXConstructExpr *E); 128218893Sdim void VisitExprWithCleanups(ExprWithCleanups *E); 129210299Sed void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); 130199482Srdivacky void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); } 131193326Sed 132218893Sdim void VisitOpaqueValueExpr(OpaqueValueExpr *E); 133218893Sdim 134193326Sed void VisitVAArgExpr(VAArgExpr *E); 135193326Sed 136203955Srdivacky void EmitInitializationToLValue(Expr *E, LValue Address, QualType T); 137193326Sed void EmitNullInitializationToLValue(LValue Address, QualType T); 138193326Sed // case Expr::ChooseExprClass: 139200583Srdivacky void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); } 140193326Sed}; 141193326Sed} // end anonymous namespace. 142193326Sed 143193326Sed//===----------------------------------------------------------------------===// 144193326Sed// Utilities 145193326Sed//===----------------------------------------------------------------------===// 146193326Sed 147193326Sed/// EmitAggLoadOfLValue - Given an expression with aggregate type that 148193326Sed/// represents a value lvalue, this method emits the address of the lvalue, 149193326Sed/// then loads the result into DestPtr. 150193326Sedvoid AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) { 151193326Sed LValue LV = CGF.EmitLValue(E); 152193326Sed EmitFinalDestCopy(E, LV); 153193326Sed} 154193326Sed 155208600Srdivacky/// \brief True if the given aggregate type requires special GC API calls. 156208600Srdivackybool AggExprEmitter::TypeRequiresGCollection(QualType T) { 157208600Srdivacky // Only record types have members that might require garbage collection. 158208600Srdivacky const RecordType *RecordTy = T->getAs<RecordType>(); 159208600Srdivacky if (!RecordTy) return false; 160208600Srdivacky 161208600Srdivacky // Don't mess with non-trivial C++ types. 162208600Srdivacky RecordDecl *Record = RecordTy->getDecl(); 163208600Srdivacky if (isa<CXXRecordDecl>(Record) && 164208600Srdivacky (!cast<CXXRecordDecl>(Record)->hasTrivialCopyConstructor() || 165208600Srdivacky !cast<CXXRecordDecl>(Record)->hasTrivialDestructor())) 166208600Srdivacky return false; 167208600Srdivacky 168208600Srdivacky // Check whether the type has an object member. 169208600Srdivacky return Record->hasObjectMember(); 170208600Srdivacky} 171208600Srdivacky 172208600Srdivacky/// \brief Perform the final move to DestPtr if RequiresGCollection is set. 173208600Srdivacky/// 174208600Srdivacky/// The idea is that you do something like this: 175208600Srdivacky/// RValue Result = EmitSomething(..., getReturnValueSlot()); 176208600Srdivacky/// EmitGCMove(E, Result); 177208600Srdivacky/// If GC doesn't interfere, this will cause the result to be emitted 178208600Srdivacky/// directly into the return value slot. If GC does interfere, a final 179208600Srdivacky/// move will be performed. 180208600Srdivackyvoid AggExprEmitter::EmitGCMove(const Expr *E, RValue Src) { 181218893Sdim if (Dest.requiresGCollection()) { 182210299Sed std::pair<uint64_t, unsigned> TypeInfo = 183210299Sed CGF.getContext().getTypeInfo(E->getType()); 184210299Sed unsigned long size = TypeInfo.first/8; 185210299Sed const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType()); 186210299Sed llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size); 187218893Sdim CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, Dest.getAddr(), 188208600Srdivacky Src.getAggregateAddr(), 189210299Sed SizeVal); 190210299Sed } 191208600Srdivacky} 192208600Srdivacky 193193326Sed/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired. 194193326Sedvoid AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) { 195193326Sed assert(Src.isAggregate() && "value must be aggregate value!"); 196193326Sed 197218893Sdim // If Dest is ignored, then we're evaluating an aggregate expression 198212904Sdim // in a context (like an expression statement) that doesn't care 199212904Sdim // about the result. C says that an lvalue-to-rvalue conversion is 200212904Sdim // performed in these cases; C++ says that it is not. In either 201212904Sdim // case, we don't actually need to do anything unless the value is 202212904Sdim // volatile. 203218893Sdim if (Dest.isIgnored()) { 204212904Sdim if (!Src.isVolatileQualified() || 205212904Sdim CGF.CGM.getLangOptions().CPlusPlus || 206212904Sdim (IgnoreResult && Ignore)) 207193326Sed return; 208212904Sdim 209193326Sed // If the source is volatile, we must read from it; to do that, we need 210193326Sed // some place to put it. 211218893Sdim Dest = CGF.CreateAggTemp(E->getType(), "agg.tmp"); 212193326Sed } 213193326Sed 214218893Sdim if (Dest.requiresGCollection()) { 215210299Sed std::pair<uint64_t, unsigned> TypeInfo = 216210299Sed CGF.getContext().getTypeInfo(E->getType()); 217210299Sed unsigned long size = TypeInfo.first/8; 218210299Sed const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType()); 219210299Sed llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size); 220198092Srdivacky CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, 221218893Sdim Dest.getAddr(), 222218893Sdim Src.getAggregateAddr(), 223218893Sdim SizeVal); 224198092Srdivacky return; 225198092Srdivacky } 226193326Sed // If the result of the assignment is used, copy the LHS there also. 227193326Sed // FIXME: Pass VolatileDest as well. I think we also need to merge volatile 228193326Sed // from the source as well, as we can't eliminate it if either operand 229193326Sed // is volatile, unless copy has volatile for both source and destination.. 230218893Sdim CGF.EmitAggregateCopy(Dest.getAddr(), Src.getAggregateAddr(), E->getType(), 231218893Sdim Dest.isVolatile()|Src.isVolatileQualified()); 232193326Sed} 233193326Sed 234193326Sed/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired. 235193326Sedvoid AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) { 236193326Sed assert(Src.isSimple() && "Can't have aggregate bitfield, vector, etc"); 237193326Sed 238193326Sed EmitFinalDestCopy(E, RValue::getAggregate(Src.getAddress(), 239193326Sed Src.isVolatileQualified()), 240193326Sed Ignore); 241193326Sed} 242193326Sed 243193326Sed//===----------------------------------------------------------------------===// 244193326Sed// Visitor Methods 245193326Sed//===----------------------------------------------------------------------===// 246193326Sed 247218893Sdimvoid AggExprEmitter::VisitOpaqueValueExpr(OpaqueValueExpr *e) { 248218893Sdim EmitFinalDestCopy(e, CGF.getOpaqueLValueMapping(e)); 249218893Sdim} 250218893Sdim 251198092Srdivackyvoid AggExprEmitter::VisitCastExpr(CastExpr *E) { 252218893Sdim if (Dest.isIgnored() && E->getCastKind() != CK_Dynamic) { 253204962Srdivacky Visit(E->getSubExpr()); 254204962Srdivacky return; 255204962Srdivacky } 256204962Srdivacky 257198092Srdivacky switch (E->getCastKind()) { 258212904Sdim case CK_Dynamic: { 259208600Srdivacky assert(isa<CXXDynamicCastExpr>(E) && "CK_Dynamic without a dynamic_cast?"); 260208600Srdivacky LValue LV = CGF.EmitCheckedLValue(E->getSubExpr()); 261208600Srdivacky // FIXME: Do we also need to handle property references here? 262208600Srdivacky if (LV.isSimple()) 263208600Srdivacky CGF.EmitDynamicCast(LV.getAddress(), cast<CXXDynamicCastExpr>(E)); 264208600Srdivacky else 265208600Srdivacky CGF.CGM.ErrorUnsupported(E, "non-simple lvalue dynamic_cast"); 266208600Srdivacky 267218893Sdim if (!Dest.isIgnored()) 268218893Sdim CGF.CGM.ErrorUnsupported(E, "lvalue dynamic_cast with a destination"); 269208600Srdivacky break; 270208600Srdivacky } 271208600Srdivacky 272212904Sdim case CK_ToUnion: { 273198092Srdivacky // GCC union extension 274212904Sdim QualType Ty = E->getSubExpr()->getType(); 275212904Sdim QualType PtrTy = CGF.getContext().getPointerType(Ty); 276218893Sdim llvm::Value *CastPtr = Builder.CreateBitCast(Dest.getAddr(), 277193401Sed CGF.ConvertType(PtrTy)); 278212904Sdim EmitInitializationToLValue(E->getSubExpr(), CGF.MakeAddrLValue(CastPtr, Ty), 279212904Sdim Ty); 280198092Srdivacky break; 281193326Sed } 282193326Sed 283212904Sdim case CK_DerivedToBase: 284212904Sdim case CK_BaseToDerived: 285212904Sdim case CK_UncheckedDerivedToBase: { 286208600Srdivacky assert(0 && "cannot perform hierarchy conversion in EmitAggExpr: " 287208600Srdivacky "should have been unpacked before we got here"); 288208600Srdivacky break; 289208600Srdivacky } 290208600Srdivacky 291218893Sdim case CK_GetObjCProperty: { 292218893Sdim LValue LV = CGF.EmitLValue(E->getSubExpr()); 293218893Sdim assert(LV.isPropertyRef()); 294218893Sdim RValue RV = CGF.EmitLoadOfPropertyRefLValue(LV, getReturnValueSlot()); 295218893Sdim EmitGCMove(E, RV); 296218893Sdim break; 297218893Sdim } 298218893Sdim 299218893Sdim case CK_LValueToRValue: // hope for downstream optimization 300212904Sdim case CK_NoOp: 301212904Sdim case CK_UserDefinedConversion: 302212904Sdim case CK_ConstructorConversion: 303198092Srdivacky assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(), 304198092Srdivacky E->getType()) && 305198092Srdivacky "Implicit cast types must be compatible"); 306198092Srdivacky Visit(E->getSubExpr()); 307198092Srdivacky break; 308218893Sdim 309212904Sdim case CK_LValueBitCast: 310218893Sdim llvm_unreachable("should not be emitting lvalue bitcast as rvalue"); 311210299Sed break; 312218893Sdim 313218893Sdim case CK_Dependent: 314218893Sdim case CK_BitCast: 315218893Sdim case CK_ArrayToPointerDecay: 316218893Sdim case CK_FunctionToPointerDecay: 317218893Sdim case CK_NullToPointer: 318218893Sdim case CK_NullToMemberPointer: 319218893Sdim case CK_BaseToDerivedMemberPointer: 320218893Sdim case CK_DerivedToBaseMemberPointer: 321218893Sdim case CK_MemberPointerToBoolean: 322218893Sdim case CK_IntegralToPointer: 323218893Sdim case CK_PointerToIntegral: 324218893Sdim case CK_PointerToBoolean: 325218893Sdim case CK_ToVoid: 326218893Sdim case CK_VectorSplat: 327218893Sdim case CK_IntegralCast: 328218893Sdim case CK_IntegralToBoolean: 329218893Sdim case CK_IntegralToFloating: 330218893Sdim case CK_FloatingToIntegral: 331218893Sdim case CK_FloatingToBoolean: 332218893Sdim case CK_FloatingCast: 333218893Sdim case CK_AnyPointerToObjCPointerCast: 334218893Sdim case CK_AnyPointerToBlockPointerCast: 335218893Sdim case CK_ObjCObjectLValueCast: 336218893Sdim case CK_FloatingRealToComplex: 337218893Sdim case CK_FloatingComplexToReal: 338218893Sdim case CK_FloatingComplexToBoolean: 339218893Sdim case CK_FloatingComplexCast: 340218893Sdim case CK_FloatingComplexToIntegralComplex: 341218893Sdim case CK_IntegralRealToComplex: 342218893Sdim case CK_IntegralComplexToReal: 343218893Sdim case CK_IntegralComplexToBoolean: 344218893Sdim case CK_IntegralComplexCast: 345218893Sdim case CK_IntegralComplexToFloatingComplex: 346218893Sdim llvm_unreachable("cast kind invalid for aggregate types"); 347198398Srdivacky } 348193326Sed} 349193326Sed 350193326Sedvoid AggExprEmitter::VisitCallExpr(const CallExpr *E) { 351193326Sed if (E->getCallReturnType()->isReferenceType()) { 352193326Sed EmitAggLoadOfLValue(E); 353193326Sed return; 354193326Sed } 355198092Srdivacky 356208600Srdivacky RValue RV = CGF.EmitCallExpr(E, getReturnValueSlot()); 357208600Srdivacky EmitGCMove(E, RV); 358193326Sed} 359193326Sed 360193326Sedvoid AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) { 361208600Srdivacky RValue RV = CGF.EmitObjCMessageExpr(E, getReturnValueSlot()); 362208600Srdivacky EmitGCMove(E, RV); 363193326Sed} 364193326Sed 365193326Sedvoid AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { 366218893Sdim llvm_unreachable("direct property access not surrounded by " 367218893Sdim "lvalue-to-rvalue cast"); 368193326Sed} 369193326Sed 370193326Sedvoid AggExprEmitter::VisitBinComma(const BinaryOperator *E) { 371218893Sdim CGF.EmitIgnoredExpr(E->getLHS()); 372218893Sdim Visit(E->getRHS()); 373193326Sed} 374193326Sed 375193326Sedvoid AggExprEmitter::VisitStmtExpr(const StmtExpr *E) { 376218893Sdim CodeGenFunction::StmtExprEvaluation eval(CGF); 377218893Sdim CGF.EmitCompoundStmt(*E->getSubStmt(), true, Dest); 378193326Sed} 379193326Sed 380193326Sedvoid AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) { 381212904Sdim if (E->getOpcode() == BO_PtrMemD || E->getOpcode() == BO_PtrMemI) 382198398Srdivacky VisitPointerToDataMemberBinaryOperator(E); 383198398Srdivacky else 384198398Srdivacky CGF.ErrorUnsupported(E, "aggregate binary expression"); 385193326Sed} 386193326Sed 387198398Srdivackyvoid AggExprEmitter::VisitPointerToDataMemberBinaryOperator( 388198398Srdivacky const BinaryOperator *E) { 389198398Srdivacky LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E); 390198398Srdivacky EmitFinalDestCopy(E, LV); 391198398Srdivacky} 392198398Srdivacky 393193326Sedvoid AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { 394193326Sed // For an assignment to work, the value on the right has 395193326Sed // to be compatible with the value on the left. 396193326Sed assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), 397193326Sed E->getRHS()->getType()) 398193326Sed && "Invalid assignment"); 399218893Sdim 400218893Sdim // FIXME: __block variables need the RHS evaluated first! 401193326Sed LValue LHS = CGF.EmitLValue(E->getLHS()); 402193326Sed 403193326Sed // We have to special case property setters, otherwise we must have 404193326Sed // a simple lvalue (no aggregates inside vectors, bitfields). 405193326Sed if (LHS.isPropertyRef()) { 406218893Sdim AggValueSlot Slot = EnsureSlot(E->getRHS()->getType()); 407218893Sdim CGF.EmitAggExpr(E->getRHS(), Slot); 408218893Sdim CGF.EmitStoreThroughPropertyRefLValue(Slot.asRValue(), LHS); 409193326Sed } else { 410218893Sdim bool GCollection = false; 411208600Srdivacky if (CGF.getContext().getLangOptions().getGCMode()) 412218893Sdim GCollection = TypeRequiresGCollection(E->getLHS()->getType()); 413208600Srdivacky 414193326Sed // Codegen the RHS so that it stores directly into the LHS. 415218893Sdim AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true, 416218893Sdim GCollection); 417218893Sdim CGF.EmitAggExpr(E->getRHS(), LHSSlot, false); 418193326Sed EmitFinalDestCopy(E, LHS, true); 419193326Sed } 420193326Sed} 421193326Sed 422218893Sdimvoid AggExprEmitter:: 423218893SdimVisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { 424193326Sed llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); 425193326Sed llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); 426193326Sed llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); 427198092Srdivacky 428218893Sdim // Bind the common expression if necessary. 429218893Sdim CodeGenFunction::OpaqueValueMapping binding(CGF, E); 430218893Sdim 431218893Sdim CodeGenFunction::ConditionalEvaluation eval(CGF); 432201361Srdivacky CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock); 433198092Srdivacky 434218893Sdim // Save whether the destination's lifetime is externally managed. 435218893Sdim bool DestLifetimeManaged = Dest.isLifetimeExternallyManaged(); 436218893Sdim 437218893Sdim eval.begin(CGF); 438193326Sed CGF.EmitBlock(LHSBlock); 439218893Sdim Visit(E->getTrueExpr()); 440218893Sdim eval.end(CGF); 441198092Srdivacky 442218893Sdim assert(CGF.HaveInsertPoint() && "expression evaluation ended with no IP!"); 443218893Sdim CGF.Builder.CreateBr(ContBlock); 444193326Sed 445218893Sdim // If the result of an agg expression is unused, then the emission 446218893Sdim // of the LHS might need to create a destination slot. That's fine 447218893Sdim // with us, and we can safely emit the RHS into the same slot, but 448218893Sdim // we shouldn't claim that its lifetime is externally managed. 449218893Sdim Dest.setLifetimeExternallyManaged(DestLifetimeManaged); 450198092Srdivacky 451218893Sdim eval.begin(CGF); 452193326Sed CGF.EmitBlock(RHSBlock); 453218893Sdim Visit(E->getFalseExpr()); 454218893Sdim eval.end(CGF); 455198092Srdivacky 456193326Sed CGF.EmitBlock(ContBlock); 457193326Sed} 458193326Sed 459198092Srdivackyvoid AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) { 460198092Srdivacky Visit(CE->getChosenSubExpr(CGF.getContext())); 461198092Srdivacky} 462198092Srdivacky 463193326Sedvoid AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) { 464193326Sed llvm::Value *ArgValue = CGF.EmitVAListRef(VE->getSubExpr()); 465193326Sed llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType()); 466193326Sed 467193326Sed if (!ArgPtr) { 468193326Sed CGF.ErrorUnsupported(VE, "aggregate va_arg expression"); 469193326Sed return; 470193326Sed } 471193326Sed 472212904Sdim EmitFinalDestCopy(VE, CGF.MakeAddrLValue(ArgPtr, VE->getType())); 473193326Sed} 474193326Sed 475193326Sedvoid AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { 476218893Sdim // Ensure that we have a slot, but if we already do, remember 477218893Sdim // whether its lifetime was externally managed. 478218893Sdim bool WasManaged = Dest.isLifetimeExternallyManaged(); 479218893Sdim Dest = EnsureSlot(E->getType()); 480218893Sdim Dest.setLifetimeExternallyManaged(); 481198092Srdivacky 482218893Sdim Visit(E->getSubExpr()); 483193326Sed 484218893Sdim // Set up the temporary's destructor if its lifetime wasn't already 485218893Sdim // being managed. 486218893Sdim if (!WasManaged) 487218893Sdim CGF.EmitCXXTemporary(E->getTemporary(), Dest.getAddr()); 488193326Sed} 489193326Sed 490193326Sedvoid 491193326SedAggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) { 492218893Sdim AggValueSlot Slot = EnsureSlot(E->getType()); 493218893Sdim CGF.EmitCXXConstructExpr(E, Slot); 494193326Sed} 495193326Sed 496218893Sdimvoid AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) { 497218893Sdim CGF.EmitExprWithCleanups(E, Dest); 498193326Sed} 499193326Sed 500210299Sedvoid AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { 501218893Sdim QualType T = E->getType(); 502218893Sdim AggValueSlot Slot = EnsureSlot(T); 503218893Sdim EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T), T); 504198398Srdivacky} 505198398Srdivacky 506201361Srdivackyvoid AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { 507218893Sdim QualType T = E->getType(); 508218893Sdim AggValueSlot Slot = EnsureSlot(T); 509218893Sdim EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T), T); 510218893Sdim} 511201361Srdivacky 512218893Sdim/// isSimpleZero - If emitting this value will obviously just cause a store of 513218893Sdim/// zero to memory, return true. This can return false if uncertain, so it just 514218893Sdim/// handles simple cases. 515218893Sdimstatic bool isSimpleZero(const Expr *E, CodeGenFunction &CGF) { 516218893Sdim // (0) 517218893Sdim if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) 518218893Sdim return isSimpleZero(PE->getSubExpr(), CGF); 519218893Sdim // 0 520218893Sdim if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E)) 521218893Sdim return IL->getValue() == 0; 522218893Sdim // +0.0 523218893Sdim if (const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(E)) 524218893Sdim return FL->getValue().isPosZero(); 525218893Sdim // int() 526218893Sdim if ((isa<ImplicitValueInitExpr>(E) || isa<CXXScalarValueInitExpr>(E)) && 527218893Sdim CGF.getTypes().isZeroInitializable(E->getType())) 528218893Sdim return true; 529218893Sdim // (int*)0 - Null pointer expressions. 530218893Sdim if (const CastExpr *ICE = dyn_cast<CastExpr>(E)) 531218893Sdim return ICE->getCastKind() == CK_NullToPointer; 532218893Sdim // '\0' 533218893Sdim if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E)) 534218893Sdim return CL->getValue() == 0; 535218893Sdim 536218893Sdim // Otherwise, hard case: conservatively return false. 537218893Sdim return false; 538201361Srdivacky} 539201361Srdivacky 540218893Sdim 541203955Srdivackyvoid 542203955SrdivackyAggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV, QualType T) { 543193326Sed // FIXME: Ignore result? 544193326Sed // FIXME: Are initializers affected by volatile? 545218893Sdim if (Dest.isZeroed() && isSimpleZero(E, CGF)) { 546218893Sdim // Storing "i32 0" to a zero'd memory location is a noop. 547218893Sdim } else if (isa<ImplicitValueInitExpr>(E)) { 548203955Srdivacky EmitNullInitializationToLValue(LV, T); 549203955Srdivacky } else if (T->isReferenceType()) { 550210299Sed RValue RV = CGF.EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0); 551203955Srdivacky CGF.EmitStoreThroughLValue(RV, LV, T); 552203955Srdivacky } else if (T->isAnyComplexType()) { 553193326Sed CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false); 554203955Srdivacky } else if (CGF.hasAggregateLLVMType(T)) { 555218893Sdim CGF.EmitAggExpr(E, AggValueSlot::forAddr(LV.getAddress(), false, true, 556218893Sdim false, Dest.isZeroed())); 557193326Sed } else { 558218893Sdim CGF.EmitStoreThroughLValue(RValue::get(CGF.EmitScalarExpr(E)), LV, T); 559193326Sed } 560193326Sed} 561193326Sed 562193326Sedvoid AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) { 563218893Sdim // If the destination slot is already zeroed out before the aggregate is 564218893Sdim // copied into it, we don't have to emit any zeros here. 565218893Sdim if (Dest.isZeroed() && CGF.getTypes().isZeroInitializable(T)) 566218893Sdim return; 567218893Sdim 568193326Sed if (!CGF.hasAggregateLLVMType(T)) { 569193326Sed // For non-aggregates, we can store zero 570193326Sed llvm::Value *Null = llvm::Constant::getNullValue(CGF.ConvertType(T)); 571193326Sed CGF.EmitStoreThroughLValue(RValue::get(Null), LV, T); 572193326Sed } else { 573193326Sed // There's a potential optimization opportunity in combining 574193326Sed // memsets; that would be easy for arrays, but relatively 575193326Sed // difficult for structures with the current code. 576208600Srdivacky CGF.EmitNullInitialization(LV.getAddress(), T); 577193326Sed } 578193326Sed} 579193326Sed 580193326Sedvoid AggExprEmitter::VisitInitListExpr(InitListExpr *E) { 581193326Sed#if 0 582200583Srdivacky // FIXME: Assess perf here? Figure out what cases are worth optimizing here 583200583Srdivacky // (Length of globals? Chunks of zeroed-out space?). 584193326Sed // 585193326Sed // If we can, prefer a copy from a global; this is a lot less code for long 586193326Sed // globals, and it's easier for the current optimizers to analyze. 587200583Srdivacky if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) { 588193326Sed llvm::GlobalVariable* GV = 589200583Srdivacky new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true, 590200583Srdivacky llvm::GlobalValue::InternalLinkage, C, ""); 591212904Sdim EmitFinalDestCopy(E, CGF.MakeAddrLValue(GV, E->getType())); 592193326Sed return; 593193326Sed } 594193326Sed#endif 595218893Sdim if (E->hadArrayRangeDesignator()) 596193326Sed CGF.ErrorUnsupported(E, "GNU array range designator extension"); 597193326Sed 598218893Sdim llvm::Value *DestPtr = Dest.getAddr(); 599218893Sdim 600193326Sed // Handle initialization of an array. 601193326Sed if (E->getType()->isArrayType()) { 602193326Sed const llvm::PointerType *APType = 603193326Sed cast<llvm::PointerType>(DestPtr->getType()); 604193326Sed const llvm::ArrayType *AType = 605193326Sed cast<llvm::ArrayType>(APType->getElementType()); 606198092Srdivacky 607193326Sed uint64_t NumInitElements = E->getNumInits(); 608193326Sed 609193326Sed if (E->getNumInits() > 0) { 610193326Sed QualType T1 = E->getType(); 611193326Sed QualType T2 = E->getInit(0)->getType(); 612193326Sed if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) { 613193326Sed EmitAggLoadOfLValue(E->getInit(0)); 614193326Sed return; 615193326Sed } 616193326Sed } 617193326Sed 618193326Sed uint64_t NumArrayElements = AType->getNumElements(); 619193326Sed QualType ElementType = CGF.getContext().getCanonicalType(E->getType()); 620193326Sed ElementType = CGF.getContext().getAsArrayType(ElementType)->getElementType(); 621193326Sed 622198092Srdivacky // FIXME: were we intentionally ignoring address spaces and GC attributes? 623198092Srdivacky 624193326Sed for (uint64_t i = 0; i != NumArrayElements; ++i) { 625218893Sdim // If we're done emitting initializers and the destination is known-zeroed 626218893Sdim // then we're done. 627218893Sdim if (i == NumInitElements && 628218893Sdim Dest.isZeroed() && 629218893Sdim CGF.getTypes().isZeroInitializable(ElementType)) 630218893Sdim break; 631218893Sdim 632193326Sed llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array"); 633212904Sdim LValue LV = CGF.MakeAddrLValue(NextVal, ElementType); 634218893Sdim 635193326Sed if (i < NumInitElements) 636212904Sdim EmitInitializationToLValue(E->getInit(i), LV, ElementType); 637193326Sed else 638212904Sdim EmitNullInitializationToLValue(LV, ElementType); 639218893Sdim 640218893Sdim // If the GEP didn't get used because of a dead zero init or something 641218893Sdim // else, clean it up for -O0 builds and general tidiness. 642218893Sdim if (llvm::GetElementPtrInst *GEP = 643218893Sdim dyn_cast<llvm::GetElementPtrInst>(NextVal)) 644218893Sdim if (GEP->use_empty()) 645218893Sdim GEP->eraseFromParent(); 646193326Sed } 647193326Sed return; 648193326Sed } 649198092Srdivacky 650193326Sed assert(E->getType()->isRecordType() && "Only support structs/unions here!"); 651198092Srdivacky 652193326Sed // Do struct initialization; this code just sets each individual member 653193326Sed // to the approprate value. This makes bitfield support automatic; 654193326Sed // the disadvantage is that the generated code is more difficult for 655193326Sed // the optimizer, especially with bitfields. 656193326Sed unsigned NumInitElements = E->getNumInits(); 657198092Srdivacky RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl(); 658212904Sdim 659193326Sed if (E->getType()->isUnionType()) { 660193326Sed // Only initialize one field of a union. The field itself is 661193326Sed // specified by the initializer list. 662193326Sed if (!E->getInitializedFieldInUnion()) { 663193326Sed // Empty union; we have nothing to do. 664198092Srdivacky 665193326Sed#ifndef NDEBUG 666193326Sed // Make sure that it's really an empty and not a failure of 667193326Sed // semantic analysis. 668195341Sed for (RecordDecl::field_iterator Field = SD->field_begin(), 669195341Sed FieldEnd = SD->field_end(); 670193326Sed Field != FieldEnd; ++Field) 671193326Sed assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed"); 672193326Sed#endif 673193326Sed return; 674193326Sed } 675193326Sed 676193326Sed // FIXME: volatility 677193326Sed FieldDecl *Field = E->getInitializedFieldInUnion(); 678218893Sdim 679203955Srdivacky LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0); 680193326Sed if (NumInitElements) { 681193326Sed // Store the initializer into the field 682203955Srdivacky EmitInitializationToLValue(E->getInit(0), FieldLoc, Field->getType()); 683193326Sed } else { 684218893Sdim // Default-initialize to null. 685193326Sed EmitNullInitializationToLValue(FieldLoc, Field->getType()); 686193326Sed } 687193326Sed 688193326Sed return; 689193326Sed } 690198092Srdivacky 691193326Sed // Here we iterate over the fields; this makes it simpler to both 692193326Sed // default-initialize fields and skip over unnamed fields. 693212904Sdim unsigned CurInitVal = 0; 694195341Sed for (RecordDecl::field_iterator Field = SD->field_begin(), 695195341Sed FieldEnd = SD->field_end(); 696193326Sed Field != FieldEnd; ++Field) { 697193326Sed // We're done once we hit the flexible array member 698193326Sed if (Field->getType()->isIncompleteArrayType()) 699193326Sed break; 700193326Sed 701193326Sed if (Field->isUnnamedBitfield()) 702193326Sed continue; 703193326Sed 704218893Sdim // Don't emit GEP before a noop store of zero. 705218893Sdim if (CurInitVal == NumInitElements && Dest.isZeroed() && 706218893Sdim CGF.getTypes().isZeroInitializable(E->getType())) 707218893Sdim break; 708218893Sdim 709193326Sed // FIXME: volatility 710203955Srdivacky LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, *Field, 0); 711193326Sed // We never generate write-barries for initialized fields. 712212904Sdim FieldLoc.setNonGC(true); 713218893Sdim 714193326Sed if (CurInitVal < NumInitElements) { 715204962Srdivacky // Store the initializer into the field. 716204962Srdivacky EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc, 717203955Srdivacky Field->getType()); 718193326Sed } else { 719193326Sed // We're out of initalizers; default-initialize to null 720193326Sed EmitNullInitializationToLValue(FieldLoc, Field->getType()); 721193326Sed } 722218893Sdim 723218893Sdim // If the GEP didn't get used because of a dead zero init or something 724218893Sdim // else, clean it up for -O0 builds and general tidiness. 725218893Sdim if (FieldLoc.isSimple()) 726218893Sdim if (llvm::GetElementPtrInst *GEP = 727218893Sdim dyn_cast<llvm::GetElementPtrInst>(FieldLoc.getAddress())) 728218893Sdim if (GEP->use_empty()) 729218893Sdim GEP->eraseFromParent(); 730193326Sed } 731193326Sed} 732193326Sed 733193326Sed//===----------------------------------------------------------------------===// 734193326Sed// Entry Points into this File 735193326Sed//===----------------------------------------------------------------------===// 736193326Sed 737218893Sdim/// GetNumNonZeroBytesInInit - Get an approximate count of the number of 738218893Sdim/// non-zero bytes that will be stored when outputting the initializer for the 739218893Sdim/// specified initializer expression. 740218893Sdimstatic uint64_t GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) { 741218893Sdim if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) 742218893Sdim return GetNumNonZeroBytesInInit(PE->getSubExpr(), CGF); 743218893Sdim 744218893Sdim // 0 and 0.0 won't require any non-zero stores! 745218893Sdim if (isSimpleZero(E, CGF)) return 0; 746218893Sdim 747218893Sdim // If this is an initlist expr, sum up the size of sizes of the (present) 748218893Sdim // elements. If this is something weird, assume the whole thing is non-zero. 749218893Sdim const InitListExpr *ILE = dyn_cast<InitListExpr>(E); 750218893Sdim if (ILE == 0 || !CGF.getTypes().isZeroInitializable(ILE->getType())) 751218893Sdim return CGF.getContext().getTypeSize(E->getType())/8; 752218893Sdim 753218893Sdim // InitListExprs for structs have to be handled carefully. If there are 754218893Sdim // reference members, we need to consider the size of the reference, not the 755218893Sdim // referencee. InitListExprs for unions and arrays can't have references. 756218893Sdim if (const RecordType *RT = E->getType()->getAs<RecordType>()) { 757218893Sdim if (!RT->isUnionType()) { 758218893Sdim RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl(); 759218893Sdim uint64_t NumNonZeroBytes = 0; 760218893Sdim 761218893Sdim unsigned ILEElement = 0; 762218893Sdim for (RecordDecl::field_iterator Field = SD->field_begin(), 763218893Sdim FieldEnd = SD->field_end(); Field != FieldEnd; ++Field) { 764218893Sdim // We're done once we hit the flexible array member or run out of 765218893Sdim // InitListExpr elements. 766218893Sdim if (Field->getType()->isIncompleteArrayType() || 767218893Sdim ILEElement == ILE->getNumInits()) 768218893Sdim break; 769218893Sdim if (Field->isUnnamedBitfield()) 770218893Sdim continue; 771218893Sdim 772218893Sdim const Expr *E = ILE->getInit(ILEElement++); 773218893Sdim 774218893Sdim // Reference values are always non-null and have the width of a pointer. 775218893Sdim if (Field->getType()->isReferenceType()) 776218893Sdim NumNonZeroBytes += CGF.getContext().Target.getPointerWidth(0); 777218893Sdim else 778218893Sdim NumNonZeroBytes += GetNumNonZeroBytesInInit(E, CGF); 779218893Sdim } 780218893Sdim 781218893Sdim return NumNonZeroBytes; 782218893Sdim } 783218893Sdim } 784218893Sdim 785218893Sdim 786218893Sdim uint64_t NumNonZeroBytes = 0; 787218893Sdim for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i) 788218893Sdim NumNonZeroBytes += GetNumNonZeroBytesInInit(ILE->getInit(i), CGF); 789218893Sdim return NumNonZeroBytes; 790218893Sdim} 791218893Sdim 792218893Sdim/// CheckAggExprForMemSetUse - If the initializer is large and has a lot of 793218893Sdim/// zeros in it, emit a memset and avoid storing the individual zeros. 794218893Sdim/// 795218893Sdimstatic void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E, 796218893Sdim CodeGenFunction &CGF) { 797218893Sdim // If the slot is already known to be zeroed, nothing to do. Don't mess with 798218893Sdim // volatile stores. 799218893Sdim if (Slot.isZeroed() || Slot.isVolatile() || Slot.getAddr() == 0) return; 800218893Sdim 801218893Sdim // If the type is 16-bytes or smaller, prefer individual stores over memset. 802218893Sdim std::pair<uint64_t, unsigned> TypeInfo = 803218893Sdim CGF.getContext().getTypeInfo(E->getType()); 804218893Sdim if (TypeInfo.first/8 <= 16) 805218893Sdim return; 806218893Sdim 807218893Sdim // Check to see if over 3/4 of the initializer are known to be zero. If so, 808218893Sdim // we prefer to emit memset + individual stores for the rest. 809218893Sdim uint64_t NumNonZeroBytes = GetNumNonZeroBytesInInit(E, CGF); 810218893Sdim if (NumNonZeroBytes*4 > TypeInfo.first/8) 811218893Sdim return; 812218893Sdim 813218893Sdim // Okay, it seems like a good idea to use an initial memset, emit the call. 814218893Sdim llvm::Constant *SizeVal = CGF.Builder.getInt64(TypeInfo.first/8); 815218893Sdim unsigned Align = TypeInfo.second/8; 816218893Sdim 817218893Sdim llvm::Value *Loc = Slot.getAddr(); 818218893Sdim const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); 819218893Sdim 820218893Sdim Loc = CGF.Builder.CreateBitCast(Loc, BP); 821218893Sdim CGF.Builder.CreateMemSet(Loc, CGF.Builder.getInt8(0), SizeVal, Align, false); 822218893Sdim 823218893Sdim // Tell the AggExprEmitter that the slot is known zero. 824218893Sdim Slot.setZeroed(); 825218893Sdim} 826218893Sdim 827218893Sdim 828218893Sdim 829218893Sdim 830193326Sed/// EmitAggExpr - Emit the computation of the specified expression of aggregate 831193326Sed/// type. The result is computed into DestPtr. Note that if DestPtr is null, 832193326Sed/// the value of the aggregate expression is not needed. If VolatileDest is 833193326Sed/// true, DestPtr cannot be 0. 834218893Sdim/// 835218893Sdim/// \param IsInitializer - true if this evaluation is initializing an 836218893Sdim/// object whose lifetime is already being managed. 837203955Srdivacky// 838203955Srdivacky// FIXME: Take Qualifiers object. 839218893Sdimvoid CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot, 840218893Sdim bool IgnoreResult) { 841193326Sed assert(E && hasAggregateLLVMType(E->getType()) && 842193326Sed "Invalid aggregate expression to emit"); 843218893Sdim assert((Slot.getAddr() != 0 || Slot.isIgnored()) && 844218893Sdim "slot has bits but no address"); 845198092Srdivacky 846218893Sdim // Optimize the slot if possible. 847218893Sdim CheckAggExprForMemSetUse(Slot, E, *this); 848218893Sdim 849218893Sdim AggExprEmitter(*this, Slot, IgnoreResult).Visit(const_cast<Expr*>(E)); 850193326Sed} 851193326Sed 852203955SrdivackyLValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) { 853203955Srdivacky assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!"); 854203955Srdivacky llvm::Value *Temp = CreateMemTemp(E->getType()); 855212904Sdim LValue LV = MakeAddrLValue(Temp, E->getType()); 856218893Sdim EmitAggExpr(E, AggValueSlot::forAddr(Temp, LV.isVolatileQualified(), false)); 857212904Sdim return LV; 858203955Srdivacky} 859203955Srdivacky 860193326Sedvoid CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr, 861193326Sed llvm::Value *SrcPtr, QualType Ty, 862193326Sed bool isVolatile) { 863193326Sed assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex"); 864198092Srdivacky 865207619Srdivacky if (getContext().getLangOptions().CPlusPlus) { 866207619Srdivacky if (const RecordType *RT = Ty->getAs<RecordType>()) { 867208600Srdivacky CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl()); 868208600Srdivacky assert((Record->hasTrivialCopyConstructor() || 869208600Srdivacky Record->hasTrivialCopyAssignment()) && 870208600Srdivacky "Trying to aggregate-copy a type without a trivial copy " 871208600Srdivacky "constructor or assignment operator"); 872208600Srdivacky // Ignore empty classes in C++. 873208600Srdivacky if (Record->isEmpty()) 874207619Srdivacky return; 875207619Srdivacky } 876207619Srdivacky } 877207619Srdivacky 878193326Sed // Aggregate assignment turns into llvm.memcpy. This is almost valid per 879193326Sed // C99 6.5.16.1p3, which states "If the value being stored in an object is 880193326Sed // read from another object that overlaps in anyway the storage of the first 881193326Sed // object, then the overlap shall be exact and the two objects shall have 882193326Sed // qualified or unqualified versions of a compatible type." 883193326Sed // 884193326Sed // memcpy is not defined if the source and destination pointers are exactly 885193326Sed // equal, but other compilers do this optimization, and almost every memcpy 886193326Sed // implementation handles this case safely. If there is a libc that does not 887193326Sed // safely handle this, we can add a target hook. 888198092Srdivacky 889193326Sed // Get size and alignment info for this aggregate. 890193326Sed std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty); 891198092Srdivacky 892193326Sed // FIXME: Handle variable sized types. 893198092Srdivacky 894193326Sed // FIXME: If we have a volatile struct, the optimizer can remove what might 895193326Sed // appear to be `extra' memory ops: 896193326Sed // 897193326Sed // volatile struct { int i; } a, b; 898193326Sed // 899193326Sed // int main() { 900193326Sed // a = b; 901193326Sed // a = b; 902193326Sed // } 903193326Sed // 904206275Srdivacky // we need to use a different call here. We use isVolatile to indicate when 905193326Sed // either the source or the destination is volatile. 906206275Srdivacky 907206275Srdivacky const llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType()); 908210299Sed const llvm::Type *DBP = 909218893Sdim llvm::Type::getInt8PtrTy(getLLVMContext(), DPT->getAddressSpace()); 910210299Sed DestPtr = Builder.CreateBitCast(DestPtr, DBP, "tmp"); 911206275Srdivacky 912206275Srdivacky const llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType()); 913210299Sed const llvm::Type *SBP = 914218893Sdim llvm::Type::getInt8PtrTy(getLLVMContext(), SPT->getAddressSpace()); 915210299Sed SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp"); 916206275Srdivacky 917210299Sed if (const RecordType *RecordTy = Ty->getAs<RecordType>()) { 918210299Sed RecordDecl *Record = RecordTy->getDecl(); 919210299Sed if (Record->hasObjectMember()) { 920210299Sed unsigned long size = TypeInfo.first/8; 921210299Sed const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 922210299Sed llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size); 923210299Sed CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, 924210299Sed SizeVal); 925210299Sed return; 926210299Sed } 927210299Sed } else if (getContext().getAsArrayType(Ty)) { 928210299Sed QualType BaseType = getContext().getBaseElementType(Ty); 929210299Sed if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) { 930210299Sed if (RecordTy->getDecl()->hasObjectMember()) { 931210299Sed unsigned long size = TypeInfo.first/8; 932210299Sed const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 933210299Sed llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size); 934210299Sed CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, 935210299Sed SizeVal); 936210299Sed return; 937210299Sed } 938210299Sed } 939210299Sed } 940210299Sed 941218893Sdim Builder.CreateMemCpy(DestPtr, SrcPtr, 942218893Sdim llvm::ConstantInt::get(IntPtrTy, TypeInfo.first/8), 943218893Sdim TypeInfo.second/8, isVolatile); 944193326Sed} 945