[cfe-commits] r153660 - in /cfe/trunk: lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGClass.cpp lib/CodeGen/CGDecl.cpp lib/CodeGen/CGDeclCXX.cpp lib/CodeGen/CGException.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CGObjC.cpp lib/CodeGen/CGStmt.cpp lib/CodeGen/CGValue.h lib/CodeGen/CodeGenFunction.h test/CodeGenCXX/assign-operator.cpp
Chad Rosier
mcrosier at apple.com
Thu Mar 29 10:39:55 PDT 2012
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
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list