For the record, I've contacted John about the regression. Chad
On Mar 29, 2012, at 10:37 AM, Chad Rosier wrote: > Author: mcrosier > Date: Thu Mar 29 12:37:10 2012 > New Revision: 153660 > > URL: http://llvm.org/viewvc/llvm-project?rev=153660&view=rev > Log: > Revert r153613 as it's causing large compile-time regressions on the nightly > testers. > > Modified: > cfe/trunk/lib/CodeGen/CGBlocks.cpp > cfe/trunk/lib/CodeGen/CGCall.cpp > cfe/trunk/lib/CodeGen/CGClass.cpp > cfe/trunk/lib/CodeGen/CGDecl.cpp > cfe/trunk/lib/CodeGen/CGDeclCXX.cpp > cfe/trunk/lib/CodeGen/CGException.cpp > cfe/trunk/lib/CodeGen/CGExpr.cpp > cfe/trunk/lib/CodeGen/CGExprAgg.cpp > cfe/trunk/lib/CodeGen/CGExprCXX.cpp > cfe/trunk/lib/CodeGen/CGObjC.cpp > cfe/trunk/lib/CodeGen/CGStmt.cpp > cfe/trunk/lib/CodeGen/CGValue.h > cfe/trunk/lib/CodeGen/CodeGenFunction.h > cfe/trunk/test/CodeGenCXX/assign-operator.cpp > > Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Thu Mar 29 12:37:10 2012 > @@ -734,8 +734,7 @@ > AggValueSlot::forAddr(blockField, Align, Qualifiers(), > AggValueSlot::IsDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsCompleteObject); > + AggValueSlot::IsNotAliased); > EmitAggExpr(copyExpr, Slot); > } else { > EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr); > > Modified: cfe/trunk/lib/CodeGen/CGCall.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGCall.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGCall.cpp Thu Mar 29 12:37:10 2012 > @@ -1875,8 +1875,7 @@ > if (Align > AI->getAlignment()) > AI->setAlignment(Align); > Args.push_back(AI); > - EmitAggregateCopy(AI, Addr, I->Ty, RV.isVolatileQualified(), > - /*destIsCompleteObject*/ true); > + EmitAggregateCopy(AI, Addr, I->Ty, RV.isVolatileQualified()); > > // Validate argument match. > checkArgMatches(AI, IRArgNo, IRFuncTy); > > Modified: cfe/trunk/lib/CodeGen/CGClass.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGClass.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGClass.cpp Thu Mar 29 12:37:10 2012 > @@ -401,8 +401,7 @@ > AggValueSlot::forAddr(V, Alignment, Qualifiers(), > AggValueSlot::IsDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsNotCompleteObject); > + AggValueSlot::IsNotAliased); > > CGF.EmitAggExpr(BaseInit->getInit(), AggSlot); > > @@ -450,8 +449,7 @@ > AggValueSlot::forLValue(LV, > AggValueSlot::IsDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsCompleteObject); > + AggValueSlot::IsNotAliased); > > CGF.EmitAggExpr(Init, Slot); > } > @@ -591,8 +589,7 @@ > > // Copy the aggregate. > CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType, > - LHS.isVolatileQualified(), > - /*destIsCompleteObject*/ true); > + LHS.isVolatileQualified()); > return; > } > } > @@ -1374,10 +1371,7 @@ > AggValueSlot::forAddr(ThisPtr, Alignment, Qualifiers(), > AggValueSlot::IsDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - CurGD.getCtorType() == Ctor_Complete > - ? AggValueSlot::IsCompleteObject > - : AggValueSlot::IsNotCompleteObject); > + AggValueSlot::IsNotAliased); > > EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); > > > Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Thu Mar 29 12:37:10 2012 > @@ -1092,10 +1092,9 @@ > } else { > // TODO: how can we delay here if D is captured by its initializer? > EmitAggExpr(init, AggValueSlot::forLValue(lvalue, > - AggValueSlot::IsDestructed, > + AggValueSlot::IsDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsCompleteObject)); > + AggValueSlot::IsNotAliased)); > MaybeEmitStdInitializerListCleanup(lvalue.getAddress(), init); > } > } > > Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Thu Mar 29 12:37:10 2012 > @@ -46,11 +46,9 @@ > } else if (type->isAnyComplexType()) { > CGF.EmitComplexExprIntoAddr(Init, DeclPtr, lv.isVolatile()); > } else { > - CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv, > - AggValueSlot::IsDestructed, > - > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsCompleteObject)); > + CGF.EmitAggExpr(Init, > AggValueSlot::forLValue(lv,AggValueSlot::IsDestructed, > + > AggValueSlot::DoesNotNeedGCBarriers, > + > AggValueSlot::IsNotAliased)); > } > } > > > Modified: cfe/trunk/lib/CodeGen/CGException.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGException.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGException.cpp Thu Mar 29 12:37:10 2012 > @@ -373,7 +373,8 @@ > // evaluated but before the exception is caught. But the best way > // to handle that is to teach EmitAggExpr to do the final copy > // differently if it can't be elided. > - CGF.EmitAnyExprToMem(e, typedAddr, e->getType().getQualifiers()); > + CGF.EmitAnyExprToMem(e, typedAddr, e->getType().getQualifiers(), > + /*IsInit*/ true); > > // Deactivate the cleanup block. > CGF.DeactivateCleanupBlock(cleanup, cast<llvm::Instruction>(typedAddr)); > @@ -1047,8 +1048,7 @@ > if (!copyExpr) { > llvm::Value *rawAdjustedExn = CallBeginCatch(CGF, Exn, true); > llvm::Value *adjustedExn = CGF.Builder.CreateBitCast(rawAdjustedExn, > PtrTy); > - CGF.EmitAggregateCopy(ParamAddr, adjustedExn, CatchType, > - /*volatile*/ false, 0, /*destIsCompleteObject*/ > true); > + CGF.EmitAggregateCopy(ParamAddr, adjustedExn, CatchType); > return; > } > > @@ -1076,8 +1076,7 @@ > AggValueSlot::forAddr(ParamAddr, Alignment, Qualifiers(), > AggValueSlot::IsNotDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsCompleteObject)); > + AggValueSlot::IsNotAliased)); > > // Leave the terminate scope. > CGF.EHStack.popTerminate(); > > Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Mar 29 12:37:10 2012 > @@ -133,17 +133,17 @@ > /// location. > void CodeGenFunction::EmitAnyExprToMem(const Expr *E, > llvm::Value *Location, > - Qualifiers Quals) { > + Qualifiers Quals, > + bool IsInit) { > // FIXME: This function should take an LValue as an argument. > if (E->getType()->isAnyComplexType()) { > EmitComplexExprIntoAddr(E, Location, Quals.hasVolatile()); > } else if (hasAggregateLLVMType(E->getType())) { > CharUnits Alignment = getContext().getTypeAlignInChars(E->getType()); > EmitAggExpr(E, AggValueSlot::forAddr(Location, Alignment, Quals, > - AggValueSlot::IsDestructed, > + > AggValueSlot::IsDestructed_t(IsInit), > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsCompleteObject)); > + > AggValueSlot::IsAliased_t(!IsInit))); > } else { > RValue RV = RValue::get(EmitScalarExpr(E, /*Ignore*/ false)); > LValue LV = MakeAddrLValue(Location, E->getType()); > @@ -366,8 +366,7 @@ > AggSlot = AggValueSlot::forAddr(ReferenceTemporary, Alignment, > Qualifiers(), isDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsCompleteObject); > + AggValueSlot::IsNotAliased); > } > > if (InitializedDecl) { > @@ -2152,7 +2151,8 @@ > const Expr *InitExpr = E->getInitializer(); > LValue Result = MakeAddrLValue(DeclPtr, E->getType()); > > - EmitAnyExprToMem(InitExpr, DeclPtr, E->getType().getQualifiers()); > + EmitAnyExprToMem(InitExpr, DeclPtr, E->getType().getQualifiers(), > + /*Init*/ true); > > return Result; > } > @@ -2283,7 +2283,7 @@ > // as a value, copy it into a temporary, and return an lvalue referring to > // that temporary. > llvm::Value *V = CreateMemTemp(E->getType(), "ref.temp"); > - EmitAnyExprToMem(E, V, E->getType().getQualifiers()); > + EmitAnyExprToMem(E, V, E->getType().getQualifiers(), false); > return MakeAddrLValue(V, E->getType()); > } > > @@ -2754,7 +2754,8 @@ > static llvm::Value * > EmitValToTemp(CodeGenFunction &CGF, Expr *E) { > llvm::Value *DeclPtr = CGF.CreateMemTemp(E->getType(), ".atomictmp"); > - CGF.EmitAnyExprToMem(E, DeclPtr, E->getType().getQualifiers()); > + CGF.EmitAnyExprToMem(E, DeclPtr, E->getType().getQualifiers(), > + /*Init*/ true); > return DeclPtr; > } > > > Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Thu Mar 29 12:37:10 2012 > @@ -179,8 +179,7 @@ > > void VisitVAArgExpr(VAArgExpr *E); > > - void EmitInitializationToLValue(Expr *E, LValue Address, > - AggValueSlot::IsCompleteObject_t isCompleteObject); > + void EmitInitializationToLValue(Expr *E, LValue Address); > void EmitNullInitializationToLValue(LValue Address); > // case Expr::ChooseExprClass: > void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); } > @@ -280,7 +279,7 @@ > // is volatile, unless copy has volatile for both source and destination.. > CGF.EmitAggregateCopy(Dest.getAddr(), Src.getAggregateAddr(), E->getType(), > Dest.isVolatile()|Src.isVolatileQualified(), > - Alignment, Dest.isCompleteObject()); > + Alignment); > } > > /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired. > @@ -442,8 +441,7 @@ > EmitStdInitializerList(element, initList); > } else { > LValue elementLV = CGF.MakeAddrLValue(element, elementType); > - EmitInitializationToLValue(E->getInit(i), elementLV, > - AggValueSlot::IsCompleteObject); > + EmitInitializationToLValue(E->getInit(i), elementLV); > } > } > > @@ -490,8 +488,7 @@ > // Emit the actual filler expression. > LValue elementLV = CGF.MakeAddrLValue(currentElement, elementType); > if (filler) > - EmitInitializationToLValue(filler, elementLV, > - AggValueSlot::IsCompleteObject); > + EmitInitializationToLValue(filler, elementLV); > else > EmitNullInitializationToLValue(elementLV); > > @@ -570,8 +567,7 @@ > llvm::Value *CastPtr = Builder.CreateBitCast(Dest.getAddr(), > CGF.ConvertType(PtrTy)); > EmitInitializationToLValue(E->getSubExpr(), > - CGF.MakeAddrLValue(CastPtr, Ty), > - Dest.isCompleteObject()); > + CGF.MakeAddrLValue(CastPtr, Ty)); > break; > } > > @@ -679,29 +675,6 @@ > EmitFinalDestCopy(E, LV); > } > > -/// Quickly check whether the object looks like it might be a complete > -/// object. > -static AggValueSlot::IsCompleteObject_t isCompleteObject(const Expr *E) { > - E = E->IgnoreParens(); > - > - QualType objectType; > - if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { > - objectType = DRE->getDecl()->getType(); > - } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) { > - objectType = ME->getMemberDecl()->getType(); > - } else { > - // Be conservative. > - return AggValueSlot::MayNotBeCompleteObject; > - } > - > - // The expression refers directly to some sort of object. > - // If that object has reference type, be conservative. > - if (objectType->isReferenceType()) > - return AggValueSlot::MayNotBeCompleteObject; > - > - return AggValueSlot::IsCompleteObject; > -} > - > void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { > // For an assignment to work, the value on the right has > // to be compatible with the value on the left. > @@ -709,8 +682,7 @@ > E->getRHS()->getType()) > && "Invalid assignment"); > > - if (const DeclRefExpr *DRE > - = dyn_cast<DeclRefExpr>(E->getLHS()->IgnoreParens())) > + if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getLHS())) > if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) > if (VD->hasAttr<BlocksAttr>() && > E->getRHS()->HasSideEffects(CGF.getContext())) { > @@ -720,20 +692,18 @@ > LValue LHS = CGF.EmitLValue(E->getLHS()); > Dest = AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed, > needsGC(E->getLHS()->getType()), > - AggValueSlot::IsAliased, > - AggValueSlot::IsCompleteObject); > + AggValueSlot::IsAliased); > EmitFinalDestCopy(E, RHS, true); > return; > } > - > + > LValue LHS = CGF.EmitLValue(E->getLHS()); > > // Codegen the RHS so that it stores directly into the LHS. > AggValueSlot LHSSlot = > AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed, > needsGC(E->getLHS()->getType()), > - AggValueSlot::IsAliased, > - isCompleteObject(E->getLHS())); > + AggValueSlot::IsAliased); > CGF.EmitAggExpr(E->getRHS(), LHSSlot, false); > EmitFinalDestCopy(E, LHS, true); > } > @@ -866,8 +836,7 @@ > > > void > -AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV, > - AggValueSlot::IsCompleteObject_t > isCompleteObject) { > +AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) { > QualType type = LV.getType(); > // FIXME: Ignore result? > // FIXME: Are initializers affected by volatile? > @@ -885,7 +854,6 @@ > AggValueSlot::IsDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > AggValueSlot::IsNotAliased, > - isCompleteObject, > Dest.isZeroed())); > } else if (LV.isSimple()) { > CGF.EmitScalarInit(E, /*D=*/0, LV, /*Captured=*/false); > @@ -1001,8 +969,7 @@ > LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0); > if (NumInitElements) { > // Store the initializer into the field > - EmitInitializationToLValue(E->getInit(0), FieldLoc, > - AggValueSlot::IsCompleteObject); > + EmitInitializationToLValue(E->getInit(0), FieldLoc); > } else { > // Default-initialize to null. > EmitNullInitializationToLValue(FieldLoc); > @@ -1044,8 +1011,7 @@ > > if (curInitIndex < NumInitElements) { > // Store the initializer into the field. > - EmitInitializationToLValue(E->getInit(curInitIndex++), LV, > - AggValueSlot::IsCompleteObject); > + EmitInitializationToLValue(E->getInit(curInitIndex++), LV); > } else { > // We're out of initalizers; default-initialize to null > EmitNullInitializationToLValue(LV); > @@ -1220,106 +1186,105 @@ > LValue LV = MakeAddrLValue(Temp, E->getType()); > EmitAggExpr(E, AggValueSlot::forLValue(LV, AggValueSlot::IsNotDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsCompleteObject)); > + AggValueSlot::IsNotAliased)); > return LV; > } > > -void CodeGenFunction::EmitAggregateCopy(llvm::Value *dest, llvm::Value *src, > - QualType type, > - bool isVolatile, unsigned alignment, > - bool destIsCompleteObject) { > - assert(!type->isAnyComplexType() && "Shouldn't happen for complex"); > - > - // Get size and alignment info for this type. Note that the type > - // might include an alignment attribute, so we can't just rely on > - // the layout. > - // FIXME: Do we need to handle VLAs here? > - std::pair<CharUnits, CharUnits> typeInfo = > - getContext().getTypeInfoInChars(type); > - > - // If we weren't given an alignment, use the natural alignment. > - if (!alignment) alignment = typeInfo.second.getQuantity(); > - > - CharUnits sizeToCopy = typeInfo.first; > +void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr, > + llvm::Value *SrcPtr, QualType Ty, > + bool isVolatile, unsigned Alignment) > { > + assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex"); > > - // There's some special logic that applies to C++ classes: > if (getContext().getLangOpts().CPlusPlus) { > - if (const RecordType *RT = type->getAs<RecordType>()) { > - // First, we want to assert that we're not doing this to > - // something with a non-trivial operator/constructor. > - CXXRecordDecl *record = cast<CXXRecordDecl>(RT->getDecl()); > - assert((record->hasTrivialCopyConstructor() || > - record->hasTrivialCopyAssignment() || > - record->hasTrivialMoveConstructor() || > - record->hasTrivialMoveAssignment()) && > + if (const RecordType *RT = Ty->getAs<RecordType>()) { > + CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl()); > + assert((Record->hasTrivialCopyConstructor() || > + Record->hasTrivialCopyAssignment() || > + Record->hasTrivialMoveConstructor() || > + Record->hasTrivialMoveAssignment()) && > "Trying to aggregate-copy a type without a trivial copy " > "constructor or assignment operator"); > - > - // Second, we want to ignore empty classes. > - if (record->isEmpty()) > + // Ignore empty classes in C++. > + if (Record->isEmpty()) > return; > - > - // Third, if it's possible that the destination might not be a > - // complete object, then we need to make sure we only copy the > - // data size, not the full sizeof, so that we don't overwrite > - // subclass fields in the tailing padding. It's generally going > - // to be more efficient to copy the sizeof, since we can use > - // larger stores. > - // > - // Unions and final classes can never be base classes. > - if (!destIsCompleteObject && !record->isUnion() && > - !record->hasAttr<FinalAttr>()) { > - const ASTRecordLayout &layout > - = getContext().getASTRecordLayout(record); > - sizeToCopy = layout.getDataSize(); > - } > } > } > > - llvm::PointerType *DPT = cast<llvm::PointerType>(dest->getType()); > + // Aggregate assignment turns into llvm.memcpy. This is almost valid per > + // C99 6.5.16.1p3, which states "If the value being stored in an object is > + // read from another object that overlaps in anyway the storage of the > first > + // object, then the overlap shall be exact and the two objects shall have > + // qualified or unqualified versions of a compatible type." > + // > + // memcpy is not defined if the source and destination pointers are exactly > + // equal, but other compilers do this optimization, and almost every memcpy > + // implementation handles this case safely. If there is a libc that does > not > + // safely handle this, we can add a target hook. > + > + // Get size and alignment info for this aggregate. > + std::pair<CharUnits, CharUnits> TypeInfo = > + getContext().getTypeInfoInChars(Ty); > + > + if (!Alignment) > + Alignment = TypeInfo.second.getQuantity(); > + > + // FIXME: Handle variable sized types. > + > + // FIXME: If we have a volatile struct, the optimizer can remove what might > + // appear to be `extra' memory ops: > + // > + // volatile struct { int i; } a, b; > + // > + // int main() { > + // a = b; > + // a = b; > + // } > + // > + // we need to use a different call here. We use isVolatile to indicate > when > + // either the source or the destination is volatile. > + > + llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType()); > llvm::Type *DBP = > llvm::Type::getInt8PtrTy(getLLVMContext(), DPT->getAddressSpace()); > - dest = Builder.CreateBitCast(dest, DBP); > + DestPtr = Builder.CreateBitCast(DestPtr, DBP); > > - llvm::PointerType *SPT = cast<llvm::PointerType>(src->getType()); > + llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType()); > llvm::Type *SBP = > llvm::Type::getInt8PtrTy(getLLVMContext(), SPT->getAddressSpace()); > - src = Builder.CreateBitCast(src, SBP); > - > - llvm::Value *sizeVal = > - llvm::ConstantInt::get(CGM.SizeTy, sizeToCopy.getQuantity()); > + SrcPtr = Builder.CreateBitCast(SrcPtr, SBP); > > // Don't do any of the memmove_collectable tests if GC isn't set. > if (CGM.getLangOpts().getGC() == LangOptions::NonGC) { > // fall through > - } else if (const RecordType *RT = type->getAs<RecordType>()) { > - if (RT->getDecl()->hasObjectMember()) { > - CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, dest, src, > sizeVal); > + } else if (const RecordType *RecordTy = Ty->getAs<RecordType>()) { > + RecordDecl *Record = RecordTy->getDecl(); > + if (Record->hasObjectMember()) { > + CharUnits size = TypeInfo.first; > + llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); > + llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, > size.getQuantity()); > + CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, > + SizeVal); > return; > } > - } else if (type->isArrayType()) { > - QualType baseType = getContext().getBaseElementType(type); > - if (const RecordType *RT = baseType->getAs<RecordType>()) { > - if (RT->getDecl()->hasObjectMember()) { > - CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, dest, > src,sizeVal); > + } else if (Ty->isArrayType()) { > + QualType BaseType = getContext().getBaseElementType(Ty); > + if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) { > + if (RecordTy->getDecl()->hasObjectMember()) { > + CharUnits size = TypeInfo.first; > + llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); > + llvm::Value *SizeVal = > + llvm::ConstantInt::get(SizeTy, size.getQuantity()); > + CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, > SrcPtr, > + SizeVal); > return; > } > } > } > - > - // Aggregate assignment turns into llvm.memcpy. This is almost valid per > - // C99 6.5.16.1p3, which states "If the value being stored in an object is > - // read from another object that overlaps in anyway the storage of the > first > - // object, then the overlap shall be exact and the two objects shall have > - // qualified or unqualified versions of a compatible type." > - // > - // memcpy is not defined if the source and destination pointers are exactly > - // equal, but other compilers do this optimization, and almost every memcpy > - // implementation handles this case safely. If there is a libc that does > not > - // safely handle this, we can add a target hook. > > - Builder.CreateMemCpy(dest, src, sizeVal, alignment, isVolatile); > + Builder.CreateMemCpy(DestPtr, SrcPtr, > + llvm::ConstantInt::get(IntPtrTy, > + TypeInfo.first.getQuantity()), > + Alignment, isVolatile); > } > > void CodeGenFunction::MaybeEmitStdInitializerListCleanup(llvm::Value *loc, > > Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Thu Mar 29 12:37:10 2012 > @@ -781,8 +781,7 @@ > = AggValueSlot::forAddr(NewPtr, Alignment, AllocType.getQualifiers(), > AggValueSlot::IsDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsCompleteObject); > + AggValueSlot::IsNotAliased); > CGF.EmitAggExpr(Init, Slot); > > CGF.MaybeEmitStdInitializerListCleanup(NewPtr, Init); > > Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGObjC.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGObjC.cpp Thu Mar 29 12:37:10 2012 > @@ -887,8 +887,7 @@ > // The return value slot is guaranteed to not be aliased, but > // that's not necessarily the same as "on the stack", so > // we still potentially need objc_memmove_collectable. > - EmitAggregateCopy(ReturnValue, LV.getAddress(), ivarType, > - /*volatile*/ false, 0, /*destIsCompleteObject*/ > true); > + EmitAggregateCopy(ReturnValue, LV.getAddress(), ivarType); > } else { > llvm::Value *value; > if (propType->isReferenceType()) { > @@ -1313,8 +1312,7 @@ > EmitAggExpr(IvarInit->getInit(), > AggValueSlot::forLValue(LV, AggValueSlot::IsDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsCompleteObject)); > + AggValueSlot::IsNotAliased)); > } > // constructor returns 'self'. > CodeGenTypes &Types = CGM.getTypes(); > @@ -2939,8 +2937,7 @@ > AggValueSlot::forAddr(DV.getScalarVal(), Alignment, > Qualifiers(), > AggValueSlot::IsDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsCompleteObject)); > + AggValueSlot::IsNotAliased)); > > FinishFunction(); > HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy); > > Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGStmt.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGStmt.cpp Thu Mar 29 12:37:10 2012 > @@ -722,8 +722,7 @@ > if (RV.isScalar()) { > Builder.CreateStore(RV.getScalarVal(), ReturnValue); > } else if (RV.isAggregate()) { > - EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty, > - /*volatile*/ false, 0, /*destIsCompleteObject*/ true); > + EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty); > } else { > StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false); > } > @@ -770,8 +769,7 @@ > EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, Alignment, > Qualifiers(), > AggValueSlot::IsDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsCompleteObject)); > + AggValueSlot::IsNotAliased)); > } > > EmitBranchThroughCleanup(ReturnBlock); > > Modified: cfe/trunk/lib/CodeGen/CGValue.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGValue.h?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGValue.h (original) > +++ cfe/trunk/lib/CodeGen/CGValue.h Thu Mar 29 12:37:10 2012 > @@ -318,22 +318,22 @@ > // Qualifiers > Qualifiers Quals; > > - unsigned Alignment : 16; > + unsigned short Alignment; > > /// DestructedFlag - This is set to true if some external code is > /// responsible for setting up a destructor for the slot. Otherwise > /// the code which constructs it should push the appropriate cleanup. > - unsigned DestructedFlag : 1; > + bool DestructedFlag : 1; > > /// ObjCGCFlag - This is set to true if writing to the memory in the > /// slot might require calling an appropriate Objective-C GC > /// barrier. The exact interaction here is unnecessarily mysterious. > - unsigned ObjCGCFlag : 1; > + bool ObjCGCFlag : 1; > > /// ZeroedFlag - This is set to true if the memory in the slot is > /// known to be zero before the assignment into it. This means that > /// zero fields don't need to be set. > - unsigned ZeroedFlag : 1; > + bool ZeroedFlag : 1; > > /// AliasedFlag - This is set to true if the slot might be aliased > /// and it's not undefined behavior to access it through such an > @@ -347,32 +347,19 @@ > /// over. Since it's invalid in general to memcpy a non-POD C++ > /// object, it's important that this flag never be set when > /// evaluating an expression which constructs such an object. > - unsigned AliasedFlag : 1; > - > - /// CompleteObjectFlag - This is set to true if the slot is known to > - /// be a complete object. When emitting an aggregate copy of a > - /// non-POD C++ struct to a location which may not be a complete > - /// object, only the data size of the type can be copied in order to > - /// prevent unrelated fields from being overwritten. > - unsigned CompleteObjectFlag : 1; > + bool AliasedFlag : 1; > > public: > enum IsAliased_t { IsNotAliased, IsAliased }; > enum IsDestructed_t { IsNotDestructed, IsDestructed }; > enum IsZeroed_t { IsNotZeroed, IsZeroed }; > - enum IsCompleteObject_t { > - IsNotCompleteObject, > - MayNotBeCompleteObject = IsNotCompleteObject, > - IsCompleteObject > - }; > enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers }; > > /// ignored - Returns an aggregate value slot indicating that the > /// aggregate value is being ignored. > static AggValueSlot ignored() { > return forAddr(0, CharUnits(), Qualifiers(), IsNotDestructed, > - DoesNotNeedGCBarriers, IsNotAliased, > - IsCompleteObject); > + DoesNotNeedGCBarriers, IsNotAliased); > } > > /// forAddr - Make a slot for an aggregate value. > @@ -390,7 +377,6 @@ > IsDestructed_t isDestructed, > NeedsGCBarriers_t needsGC, > IsAliased_t isAliased, > - IsCompleteObject_t isCompleteObject, > IsZeroed_t isZeroed = IsNotZeroed) { > AggValueSlot AV; > AV.Addr = addr; > @@ -400,18 +386,15 @@ > AV.ObjCGCFlag = needsGC; > AV.ZeroedFlag = isZeroed; > AV.AliasedFlag = isAliased; > - AV.CompleteObjectFlag = isCompleteObject; > return AV; > } > > static AggValueSlot forLValue(LValue LV, IsDestructed_t isDestructed, > NeedsGCBarriers_t needsGC, > IsAliased_t isAliased, > - IsCompleteObject_t isCompleteObject, > IsZeroed_t isZeroed = IsNotZeroed) { > return forAddr(LV.getAddress(), LV.getAlignment(), > - LV.getQuals(), isDestructed, needsGC, isAliased, > - isCompleteObject, isZeroed); > + LV.getQuals(), isDestructed, needsGC, isAliased, > isZeroed); > } > > IsDestructed_t isExternallyDestructed() const { > @@ -451,10 +434,6 @@ > return IsAliased_t(AliasedFlag); > } > > - IsCompleteObject_t isCompleteObject() const { > - return IsCompleteObject_t(CompleteObjectFlag); > - } > - > // FIXME: Alignment? > RValue asRValue() const { > return RValue::getAggregate(getAddr(), isVolatile()); > > Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) > +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Mar 29 12:37:10 2012 > @@ -1596,9 +1596,7 @@ > T.getQualifiers(), > AggValueSlot::IsNotDestructed, > AggValueSlot::DoesNotNeedGCBarriers, > - AggValueSlot::IsNotAliased, > - AggValueSlot::IsCompleteObject, > - AggValueSlot::IsNotZeroed); > + AggValueSlot::IsNotAliased); > } > > /// Emit a cast to void* in the appropriate address space. > @@ -1630,10 +1628,9 @@ > RValue EmitAnyExprToTemp(const Expr *E); > > /// EmitAnyExprToMem - Emits the code necessary to evaluate an > - /// arbitrary expression as an initialization of the given memory > - /// location. > + /// arbitrary expression into the given memory location. > void EmitAnyExprToMem(const Expr *E, llvm::Value *Location, > - Qualifiers Quals); > + Qualifiers Quals, bool IsInitializer); > > /// EmitExprAsInit - Emits the code necessary to initialize a > /// location in memory with the given initializer. > @@ -1644,12 +1641,9 @@ > /// > /// \param isVolatile - True iff either the source or the destination is > /// volatile. > - /// \param destIsCompleteObject - True if the destination is known to be > - /// a complete object. > void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr, > QualType EltTy, bool isVolatile=false, > - unsigned alignment = 0, > - bool destIsCompleteObject = false); > + unsigned Alignment = 0); > > /// StartBlock - Start new block named N. If insert block is a dummy block > /// then reuse it. > > Modified: cfe/trunk/test/CodeGenCXX/assign-operator.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/assign-operator.cpp?rev=153660&r1=153659&r2=153660&view=diff > ============================================================================== > --- cfe/trunk/test/CodeGenCXX/assign-operator.cpp (original) > +++ cfe/trunk/test/CodeGenCXX/assign-operator.cpp Thu Mar 29 12:37:10 2012 > @@ -28,24 +28,3 @@ > > A<int> a; > } > - > -// PR12204 > -namespace test2 { > - struct A { > - A() {} // make this non-POD to enable tail layout > - void *ptr; > - char c; > - }; > - > - void test(A &out) { > - out = A(); > - } > -} > -// CHECK: define void @_ZN5test24testERNS_1AE( > -// CHECK: [[OUT:%.*]] = alloca [[A:%.*]]*, align 8 > -// CHECK-NEXT: [[TMP:%.*]] = alloca [[A]], align 8 > -// CHECK: [[REF:%.*]] = load [[A]]** [[OUT]], align 8 > -// CHECK-NEXT: call void @_ZN5test21AC1Ev([[A]]* [[TMP]]) > -// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[REF]] to i8* > -// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[TMP]] to i8* > -// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T0]], i8* [[T1]], > i64 9, i32 8, i1 false) > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
