[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