diff options
Diffstat (limited to 'lib/CodeGen')
| -rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 46 | ||||
| -rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 4 | ||||
| -rw-r--r-- | lib/CodeGen/CGDecl.cpp | 14 | ||||
| -rw-r--r-- | lib/CodeGen/CGExpr.cpp | 41 | ||||
| -rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 23 | ||||
| -rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 4 | ||||
| -rw-r--r-- | lib/CodeGen/CGObjC.cpp | 7 | ||||
| -rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 45 | ||||
| -rw-r--r-- | lib/CodeGen/CGObjCRuntime.h | 3 | ||||
| -rw-r--r-- | lib/CodeGen/CGRecordLayout.h | 30 | ||||
| -rw-r--r-- | lib/CodeGen/CGRecordLayoutBuilder.cpp | 42 | ||||
| -rw-r--r-- | lib/CodeGen/CGValue.h | 38 | ||||
| -rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 6 | ||||
| -rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 30 | ||||
| -rw-r--r-- | lib/CodeGen/CodeGenModule.h | 18 | 
15 files changed, 189 insertions, 162 deletions
| diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index a9b0b645a4a6..38c40ed489d2 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -338,38 +338,50 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,    case Builtin::BIbzero:    case Builtin::BI__builtin_bzero: {      Value *Address = EmitScalarExpr(E->getArg(0)); -    Builder.CreateCall4(CGM.getMemSetFn(), Address, -                        llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0), -                        EmitScalarExpr(E->getArg(1)), -                        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1)); +    Value *SizeVal = EmitScalarExpr(E->getArg(1)); +    Builder.CreateCall5(CGM.getMemSetFn(Address->getType(), SizeVal->getType()), +                   Address, +                   llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0), +                   SizeVal, +                   llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1), +                   llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));      return RValue::get(Address);    }    case Builtin::BImemcpy:    case Builtin::BI__builtin_memcpy: {      Value *Address = EmitScalarExpr(E->getArg(0)); -    Builder.CreateCall4(CGM.getMemCpyFn(), Address, -                        EmitScalarExpr(E->getArg(1)), -                        EmitScalarExpr(E->getArg(2)), -                        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1)); +    Value *SrcAddr = EmitScalarExpr(E->getArg(1)); +    Value *SizeVal = EmitScalarExpr(E->getArg(2)); +    Builder.CreateCall5(CGM.getMemCpyFn(Address->getType(), SrcAddr->getType(), +                                        SizeVal->getType()), +                  Address, SrcAddr, SizeVal,  +                  llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1), +                  llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));      return RValue::get(Address);    }    case Builtin::BImemmove:    case Builtin::BI__builtin_memmove: {      Value *Address = EmitScalarExpr(E->getArg(0)); -    Builder.CreateCall4(CGM.getMemMoveFn(), Address, -                        EmitScalarExpr(E->getArg(1)), -                        EmitScalarExpr(E->getArg(2)), -                        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1)); +    Value *SrcAddr = EmitScalarExpr(E->getArg(1)); +    Value *SizeVal = EmitScalarExpr(E->getArg(2)); +    Builder.CreateCall5(CGM.getMemMoveFn(Address->getType(), SrcAddr->getType(), +                                         SizeVal->getType()), +                  Address, SrcAddr, SizeVal,  +                  llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1), +                  llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));      return RValue::get(Address);    }    case Builtin::BImemset:    case Builtin::BI__builtin_memset: {      Value *Address = EmitScalarExpr(E->getArg(0)); -    Builder.CreateCall4(CGM.getMemSetFn(), Address, -                        Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), -                                            llvm::Type::getInt8Ty(VMContext)), -                        EmitScalarExpr(E->getArg(2)), -                        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1)); +    Value *SizeVal = EmitScalarExpr(E->getArg(2)); +    Builder.CreateCall5(CGM.getMemSetFn(Address->getType(), SizeVal->getType()), +                  Address, +                  Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), +                                      llvm::Type::getInt8Ty(VMContext)), +                  SizeVal, +                  llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1), +                  llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));      return RValue::get(Address);    }    case Builtin::BI__builtin_dwarf_cfa: { diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 4f14f94388fc..bcbda8a0a747 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -1380,7 +1380,9 @@ void CGDebugInfo::EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder) {         || (SM.getInstantiationLineNumber(CurLoc) ==             SM.getInstantiationLineNumber(PrevLoc)             && SM.isFromSameFile(CurLoc, PrevLoc))) -    return; +    // New Builder may not be in sync with CGDebugInfo. +    if (!Builder.getCurrentDebugLocation().isUnknown()) +      return;    // Update last state.    PrevLoc = CurLoc; diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 4eb95af8ff61..07d219f1fbfc 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -564,11 +564,15 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {        if (Loc->getType() != BP)          Loc = Builder.CreateBitCast(Loc, BP, "tmp"); +      llvm::Value *NotVolatile = +        llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0); +        // If the initializer is all zeros, codegen with memset.        if (isa<llvm::ConstantAggregateZero>(Init)) {          llvm::Value *Zero = -        llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0); -        Builder.CreateCall4(CGM.getMemSetFn(), Loc, Zero, SizeVal, AlignVal); +          llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0); +        Builder.CreateCall5(CGM.getMemSetFn(Loc->getType(), SizeVal->getType()), +                            Loc, Zero, SizeVal, AlignVal, NotVolatile);        } else {          // Otherwise, create a temporary global with the initializer then           // memcpy from the global to the alloca. @@ -582,8 +586,10 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {          llvm::Value *SrcPtr = GV;          if (SrcPtr->getType() != BP)            SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp"); -         -        Builder.CreateCall4(CGM.getMemCpyFn(), Loc, SrcPtr, SizeVal, AlignVal); + +        Builder.CreateCall5(CGM.getMemCpyFn(Loc->getType(), SrcPtr->getType(), +                                            SizeVal->getType()), +                            Loc, SrcPtr, SizeVal, AlignVal, NotVolatile);        }      } else if (Ty->isReferenceType()) {        RValue RV = EmitReferenceBindingToExpr(Init, /*IsInitializer=*/true); diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 87ec159a6010..0aa4438f4f47 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -345,7 +345,7 @@ EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,    }    // Store the updated result through the lvalue. -  if (LV.isBitfield()) +  if (LV.isBitField())      EmitStoreThroughBitfieldLValue(RValue::get(NextVal), LV, ValTy, &NextVal);    else      EmitStoreThroughLValue(RValue::get(NextVal), LV, ValTy); @@ -429,7 +429,7 @@ LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,  LValue CodeGenFunction::EmitCheckedLValue(const Expr *E) {    LValue LV = EmitLValue(E); -  if (!isa<DeclRefExpr>(E) && !LV.isBitfield() && LV.isSimple()) +  if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple())      EmitCheck(LV.getAddress(), getContext().getTypeSize(E->getType()) / 8);    return LV;  } @@ -593,7 +593,7 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {    if (LV.isExtVectorElt())      return EmitLoadOfExtVectorElementLValue(LV, ExprType); -  if (LV.isBitfield()) +  if (LV.isBitField())      return EmitLoadOfBitfieldLValue(LV, ExprType);    if (LV.isPropertyRef()) @@ -605,9 +605,10 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {  RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,                                                   QualType ExprType) { -  unsigned StartBit = LV.getBitfieldStartBit(); -  unsigned BitfieldSize = LV.getBitfieldSize(); -  llvm::Value *Ptr = LV.getBitfieldAddr(); +  const CGBitFieldInfo &Info = LV.getBitFieldInfo(); +  unsigned StartBit = Info.Start; +  unsigned BitfieldSize = Info.Size; +  llvm::Value *Ptr = LV.getBitFieldAddr();    const llvm::Type *EltTy =      cast<llvm::PointerType>(Ptr->getType())->getElementType(); @@ -650,7 +651,7 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,    }    // Sign extend if necessary. -  if (LV.isBitfieldSigned()) { +  if (Info.IsSigned) {      llvm::Value *ExtraBits = llvm::ConstantInt::get(EltTy,                                                      EltTySize - BitfieldSize);      Val = Builder.CreateAShr(Builder.CreateShl(Val, ExtraBits), @@ -733,7 +734,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,      if (Dst.isExtVectorElt())        return EmitStoreThroughExtVectorComponentLValue(Src, Dst, Ty); -    if (Dst.isBitfield()) +    if (Dst.isBitField())        return EmitStoreThroughBitfieldLValue(Src, Dst, Ty);      if (Dst.isPropertyRef()) @@ -781,9 +782,10 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,  void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,                                                       QualType Ty,                                                       llvm::Value **Result) { -  unsigned StartBit = Dst.getBitfieldStartBit(); -  unsigned BitfieldSize = Dst.getBitfieldSize(); -  llvm::Value *Ptr = Dst.getBitfieldAddr(); +  const CGBitFieldInfo &Info = Dst.getBitFieldInfo(); +  unsigned StartBit = Info.Start; +  unsigned BitfieldSize = Info.Size; +  llvm::Value *Ptr = Dst.getBitFieldAddr();    const llvm::Type *EltTy =      cast<llvm::PointerType>(Ptr->getType())->getElementType(); @@ -805,7 +807,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,                                                    "bf.reload.val");      // Sign extend if necessary. -    if (Dst.isBitfieldSigned()) { +    if (Info.IsSigned) {        unsigned SrcTySize = CGM.getTargetData().getTypeSizeInBits(SrcTy);        llvm::Value *ExtraBits = llvm::ConstantInt::get(SrcTy,                                                        SrcTySize - BitfieldSize); @@ -1471,7 +1473,7 @@ LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,                                                unsigned CVRQualifiers) {    const CGRecordLayout &RL =      CGM.getTypes().getCGRecordLayout(Field->getParent()); -  const CGRecordLayout::BitFieldInfo &Info = RL.getBitFieldInfo(Field); +  const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field);    // FIXME: CodeGenTypes should expose a method to get the appropriate type for    // FieldTy (the appropriate type is ABI-dependent). @@ -1481,16 +1483,11 @@ LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,    cast<llvm::PointerType>(BaseValue->getType());    unsigned AS = BaseTy->getAddressSpace();    BaseValue = Builder.CreateBitCast(BaseValue, -                                    llvm::PointerType::get(FieldTy, AS), -                                    "tmp"); +                                    llvm::PointerType::get(FieldTy, AS)); +  llvm::Value *V = Builder.CreateConstGEP1_32(BaseValue, Info.FieldNo); -  llvm::Value *Idx = -    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Info.FieldNo); -  llvm::Value *V = Builder.CreateGEP(BaseValue, Idx, "tmp"); - -  return LValue::MakeBitfield(V, Info.Start, Info.Size, -                              Field->getType()->isSignedIntegerType(), -                            Field->getType().getCVRQualifiers()|CVRQualifiers); +  return LValue::MakeBitfield(V, Info, +                             Field->getType().getCVRQualifiers()|CVRQualifiers);  }  LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue, diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index e2e2cd050419..4d5160f39b0b 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -771,12 +771,27 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,    //   a = b;    // }    // -  // we need to use a differnt call here.  We use isVolatile to indicate when +  // we need to use a different call here.  We use isVolatile to indicate when    // either the source or the destination is volatile. -  Builder.CreateCall4(CGM.getMemCpyFn(), +  const llvm::Type *I1Ty = llvm::Type::getInt1Ty(VMContext); +  const llvm::Type *I8Ty = llvm::Type::getInt8Ty(VMContext); +  const llvm::Type *I32Ty = llvm::Type::getInt32Ty(VMContext); + +  const llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType()); +  const llvm::Type *DBP = llvm::PointerType::get(I8Ty, DPT->getAddressSpace()); +  if (DestPtr->getType() != DBP) +    DestPtr = Builder.CreateBitCast(DestPtr, DBP, "tmp"); + +  const llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType()); +  const llvm::Type *SBP = llvm::PointerType::get(I8Ty, SPT->getAddressSpace()); +  if (SrcPtr->getType() != SBP) +    SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp"); + +  Builder.CreateCall5(CGM.getMemCpyFn(DestPtr->getType(), SrcPtr->getType(), +                                      IntPtr),                        DestPtr, SrcPtr,                        // TypeInfo.first describes size in bits.                        llvm::ConstantInt::get(IntPtr, TypeInfo.first/8), -                      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), -                                             TypeInfo.second/8)); +                      llvm::ConstantInt::get(I32Ty,  TypeInfo.second/8), +                      llvm::ConstantInt::get(I1Ty,  isVolatile));  } diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 42bf68ed52ce..d1c0f8dc3d73 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1140,7 +1140,7 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,    // specially because the result is altered by the store, i.e., [C99 6.5.16p1]    // 'An assignment expression has the value of the left operand after the    // assignment...'. -  if (LHSLV.isBitfield()) { +  if (LHSLV.isBitField()) {      if (!LHSLV.isVolatileQualified()) {        CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, LHSTy,                                           &Result); @@ -1575,7 +1575,7 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {    // because the result is altered by the store, i.e., [C99 6.5.16p1]    // 'An assignment expression has the value of the left operand after    // the assignment...'. -  if (LHS.isBitfield()) { +  if (LHS.isBitField()) {      if (!LHS.isVolatileQualified()) {        CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, E->getType(),                                           &RHS); diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 9eaf57c445ed..206d438ced67 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -108,6 +108,10 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {  void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,                                        const ObjCContainerDecl *CD) {    FunctionArgList Args; +  // Check if we should generate debug info for this method. +  if (CGM.getDebugInfo() && !OMD->hasAttr<NoDebugAttr>()) +    DebugInfo = CGM.getDebugInfo(); +    llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);    const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(OMD); @@ -128,9 +132,6 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,  /// Generate an Objective-C method.  An Objective-C method is a C function with  /// its pointer, name, and types registered in the class struture.  void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) { -  // Check if we should generate debug info for this method. -  if (CGM.getDebugInfo() && !OMD->hasAttr<NoDebugAttr>()) -    DebugInfo = CGM.getDebugInfo();    StartObjCMethod(OMD, OMD->getClassInterface());    EmitStmt(OMD->getBody());    FinishFunction(OMD->getBodyRBrace()); diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 5373390ef7e8..ac8fa057a0e7 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -107,24 +107,31 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,    Qualifiers Quals = CGF.MakeQualifiers(IvarTy);    Quals.addCVRQualifiers(CVRQualifiers); -  if (Ivar->isBitField()) { -    // We need to compute the bit offset for the bit-field, the offset -    // is to the byte. Note, there is a subtle invariant here: we can -    // only call this routine on non-sythesized ivars but we may be -    // called for synthesized ivars. However, a synthesized ivar can -    // never be a bit-field so this is safe. -    uint64_t BitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar) % 8; - -    uint64_t BitFieldSize = -      Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue(); -    return LValue::MakeBitfield(V, BitOffset, BitFieldSize, -                                IvarTy->isSignedIntegerType(), -                                Quals.getCVRQualifiers()); -  } - -   -  LValue LV = LValue::MakeAddr(V, Quals); -  return LV; +  if (!Ivar->isBitField()) +    return LValue::MakeAddr(V, Quals); + +  // We need to compute the bit offset for the bit-field, the offset is to the +  // byte. Note, there is a subtle invariant here: we can only call this routine +  // on non-synthesized ivars but we may be called for synthesized ivars. +  // However, a synthesized ivar can never be a bit-field, so this is safe. +  uint64_t BitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar) % 8; +  uint64_t BitFieldSize = +    Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue(); + +  // Allocate a new CGBitFieldInfo object to describe this access. +  // +  // FIXME: This is incredibly wasteful, these should be uniqued or part of some +  // layout object. However, this is blocked on other cleanups to the +  // Objective-C code, so for now we just live with allocating a bunch of these +  // objects. +  unsigned FieldNo = 0; // This value is unused. +  CGBitFieldInfo *Info = +    new (CGF.CGM.getContext()) CGBitFieldInfo(FieldNo, BitOffset, BitFieldSize, +                                              IvarTy->isSignedIntegerType()); + +  // FIXME: We need to set a very conservative alignment on this, or make sure +  // that the runtime is doing the right thing. +  return LValue::MakeBitfield(V, *Info, Quals.getCVRQualifiers());  }  /// @@ -3128,7 +3135,7 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,        const CGRecordLayout &RL =          CGM.getTypes().getCGRecordLayout(Field->getParent());        if (Field->isBitField()) { -        const CGRecordLayout::BitFieldInfo &Info = RL.getBitFieldInfo(Field); +        const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field);          const llvm::Type *Ty =            CGM.getTypes().ConvertTypeForMemRecursive(Field->getType()); diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index b781940ffad5..e478394fb1aa 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -61,12 +61,11 @@ namespace CodeGen {  /// Implements runtime-specific code generation functions.  class CGObjCRuntime { -public: +protected:    // Utility functions for unified ivar access. These need to    // eventually be folded into other places (the structure layout    // code). -protected:    /// Compute an offset to the given ivar, suitable for passing to    /// EmitValueForIvarAtOffset.  Note that the correct handling of    /// bit-fields is carefully coordinated by these two, use caution! diff --git a/lib/CodeGen/CGRecordLayout.h b/lib/CodeGen/CGRecordLayout.h index d0d8f984a9ef..fd1775ea5e6c 100644 --- a/lib/CodeGen/CGRecordLayout.h +++ b/lib/CodeGen/CGRecordLayout.h @@ -19,6 +19,18 @@ namespace llvm {  namespace clang {  namespace CodeGen { +class CGBitFieldInfo { +public: +  CGBitFieldInfo(unsigned FieldNo, unsigned Start, unsigned Size, +                 bool IsSigned) +    : FieldNo(FieldNo), Start(Start), Size(Size), IsSigned(IsSigned) {} + +  unsigned FieldNo; +  unsigned Start; +  unsigned Size; +  bool IsSigned : 1; +}; +  /// CGRecordLayout - This class handles struct and union layout info while  /// lowering AST types to LLVM types.  /// @@ -29,18 +41,6 @@ class CGRecordLayout {    CGRecordLayout(const CGRecordLayout&); // DO NOT IMPLEMENT    void operator=(const CGRecordLayout&); // DO NOT IMPLEMENT -public: -  struct BitFieldInfo { -    BitFieldInfo(unsigned FieldNo, -                 unsigned Start, -                 unsigned Size) -      : FieldNo(FieldNo), Start(Start), Size(Size) {} - -    unsigned FieldNo; -    unsigned Start; -    unsigned Size; -  }; -  private:    /// The LLVMType corresponding to this record layout.    const llvm::Type *LLVMType; @@ -51,7 +51,7 @@ private:    /// Map from (bit-field) struct field to the corresponding llvm struct type    /// field no. This info is populated by record builder. -  llvm::DenseMap<const FieldDecl *, BitFieldInfo> BitFields; +  llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;    /// Whether one of the fields in this record layout is a pointer to data    /// member, or a struct that contains pointer to data member. @@ -80,9 +80,9 @@ public:    /// \brief Return llvm::StructType element number that corresponds to the    /// field FD. -  const BitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const { +  const CGBitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {      assert(FD->isBitField() && "Invalid call for non bit-field decl!"); -    llvm::DenseMap<const FieldDecl *, BitFieldInfo>::const_iterator +    llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator        it = BitFields.find(FD);      assert(it != BitFields.end()  && "Unable to find bitfield info");      return it->second; diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index daebabddc61f..4b9ec66e178c 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -37,17 +37,7 @@ public:    llvm::SmallVector<LLVMFieldInfo, 16> LLVMFields;    /// LLVMBitFieldInfo - Holds location and size information about a bit field. -  struct LLVMBitFieldInfo { -    LLVMBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, unsigned Start, -                     unsigned Size) -      : FD(FD), FieldNo(FieldNo), Start(Start), Size(Size) { } - -    const FieldDecl *FD; - -    unsigned FieldNo; -    unsigned Start; -    unsigned Size; -  }; +  typedef std::pair<const FieldDecl *, CGBitFieldInfo> LLVMBitFieldInfo;    llvm::SmallVector<LLVMBitFieldInfo, 16> LLVMBitFields;    /// ContainsPointerToDataMember - Whether one of the fields in this record @@ -188,9 +178,11 @@ void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,    const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(D->getType());    uint64_t TypeSizeInBits = getTypeSizeInBytes(Ty) * 8; -  LLVMBitFields.push_back(LLVMBitFieldInfo(D, FieldOffset / TypeSizeInBits, -                                           FieldOffset % TypeSizeInBits, -                                           FieldSize)); +  bool IsSigned = D->getType()->isSignedIntegerType(); +  LLVMBitFields.push_back(LLVMBitFieldInfo( +                            D, CGBitFieldInfo(FieldOffset / TypeSizeInBits, +                                              FieldOffset % TypeSizeInBits, +                                              FieldSize, IsSigned)));    AppendBytes(NumBytesToAppend); @@ -288,7 +280,10 @@ void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) {          continue;        // Add the bit field info. -      LLVMBitFields.push_back(LLVMBitFieldInfo(*Field, 0, 0, FieldSize)); +      bool IsSigned = Field->getType()->isSignedIntegerType(); +      LLVMBitFields.push_back(LLVMBitFieldInfo( +                                *Field, CGBitFieldInfo(0, 0, FieldSize, +                                                       IsSigned)));      } else {        LLVMFields.push_back(LLVMFieldInfo(*Field, 0));      } @@ -494,21 +489,12 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {      new CGRecordLayout(Ty, Builder.ContainsPointerToDataMember);    // Add all the field numbers. -  for (unsigned i = 0, e = Builder.LLVMFields.size(); i != e; ++i) { -    const FieldDecl *FD = Builder.LLVMFields[i].first; -    unsigned FieldNo = Builder.LLVMFields[i].second; - -    RL->FieldInfo.insert(std::make_pair(FD, FieldNo)); -  } +  for (unsigned i = 0, e = Builder.LLVMFields.size(); i != e; ++i) +    RL->FieldInfo.insert(Builder.LLVMFields[i]);    // Add bitfield info. -  for (unsigned i = 0, e = Builder.LLVMBitFields.size(); i != e; ++i) { -    const CGRecordLayoutBuilder::LLVMBitFieldInfo &Info = -      Builder.LLVMBitFields[i]; - -    CGRecordLayout::BitFieldInfo BFI(Info.FieldNo, Info.Start, Info.Size); -    RL->BitFields.insert(std::make_pair(Info.FD, BFI)); -  } +  for (unsigned i = 0, e = Builder.LLVMBitFields.size(); i != e; ++i) +    RL->BitFields.insert(Builder.LLVMBitFields[i]);    return RL;  } diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index fa77471bce0e..91fb714315fc 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -27,6 +27,7 @@ namespace clang {    class ObjCImplicitSetterGetterRefExpr;  namespace CodeGen { +  class CGBitFieldInfo;  /// RValue - This trivial value class is used to represent the result of an  /// expression that is evaluated.  It can be one of three things: either a @@ -128,14 +129,11 @@ class LValue {      llvm::Constant *VectorElts;      // BitField start bit and size -    struct { -      unsigned short StartBit; -      unsigned short Size; -      bool IsSigned; -    } BitfieldData; +    const CGBitFieldInfo *BitFieldInfo;      // Obj-C property reference expression      const ObjCPropertyRefExpr *PropertyRefExpr; +      // ObjC 'implicit' property reference expression      const ObjCImplicitSetterGetterRefExpr *KVCRefExpr;    }; @@ -170,7 +168,7 @@ private:  public:    bool isSimple() const { return LVType == Simple; }    bool isVectorElt() const { return LVType == VectorElt; } -  bool isBitfield() const { return LVType == BitField; } +  bool isBitField() const { return LVType == BitField; }    bool isExtVectorElt() const { return LVType == ExtVectorElt; }    bool isPropertyRef() const { return LVType == PropertyRef; }    bool isKVCRef() const { return LVType == KVCRef; } @@ -209,29 +207,28 @@ public:    // simple lvalue    llvm::Value *getAddress() const { assert(isSimple()); return V; } +    // vector elt lvalue    llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }    llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; } +    // extended vector elements.    llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }    llvm::Constant *getExtVectorElts() const {      assert(isExtVectorElt());      return VectorElts;    } +    // bitfield lvalue -  llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; } -  unsigned short getBitfieldStartBit() const { -    assert(isBitfield()); -    return BitfieldData.StartBit; -  } -  unsigned short getBitfieldSize() const { -    assert(isBitfield()); -    return BitfieldData.Size; +  llvm::Value *getBitFieldAddr() const { +    assert(isBitField()); +    return V;    } -  bool isBitfieldSigned() const { -    assert(isBitfield()); -    return BitfieldData.IsSigned; +  const CGBitFieldInfo &getBitFieldInfo() const { +    assert(isBitField()); +    return *BitFieldInfo;    } +    // property ref lvalue    const ObjCPropertyRefExpr *getPropertyRefExpr() const {      assert(isPropertyRef()); @@ -272,15 +269,12 @@ public:      return R;    } -  static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit, -                             unsigned short Size, bool IsSigned, +  static LValue MakeBitfield(llvm::Value *V, const CGBitFieldInfo &Info,                               unsigned CVR) {      LValue R;      R.LVType = BitField;      R.V = V; -    R.BitfieldData.StartBit = StartBit; -    R.BitfieldData.Size = Size; -    R.BitfieldData.IsSigned = IsSigned; +    R.BitFieldInfo = &Info;      R.SetQualifiers(Qualifiers::fromCVRMask(CVR));      return R;    } diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index b863aff23612..f38d8a132f02 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -495,12 +495,14 @@ void CodeGenFunction::EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty) {    const llvm::Type *IntPtr = llvm::IntegerType::get(VMContext,                                                      LLVMPointerWidth); -  Builder.CreateCall4(CGM.getMemSetFn(), DestPtr, +  Builder.CreateCall5(CGM.getMemSetFn(BP, IntPtr), DestPtr,                   llvm::Constant::getNullValue(llvm::Type::getInt8Ty(VMContext)),                        // TypeInfo.first describes size in bits.                        llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),                        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), -                                             TypeInfo.second/8)); +                                             TypeInfo.second/8), +                      llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), +                                             0));  }  llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) { diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 3c872c8560d2..a2ad31e85a80 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -47,8 +47,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,      Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M),      TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags),      Types(C, M, TD, getTargetCodeGenInfo().getABIInfo()), -    MangleCtx(C), VTables(*this), Runtime(0), -    MemCpyFn(0), MemMoveFn(0), MemSetFn(0), CFConstantStringClassRef(0), +    MangleCtx(C), VTables(*this), Runtime(0), CFConstantStringClassRef(0),      VMContext(M.getContext()) {    if (!Features.ObjC1) @@ -1414,22 +1413,25 @@ llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys,                                           (llvm::Intrinsic::ID)IID, Tys, NumTys);  } -llvm::Function *CodeGenModule::getMemCpyFn() { -  if (MemCpyFn) return MemCpyFn; -  const llvm::Type *IntPtr = TheTargetData.getIntPtrType(VMContext); -  return MemCpyFn = getIntrinsic(llvm::Intrinsic::memcpy, &IntPtr, 1); + +llvm::Function *CodeGenModule::getMemCpyFn(const llvm::Type *DestType, +                                           const llvm::Type *SrcType, +                                           const llvm::Type *SizeType) { +  const llvm::Type *ArgTypes[3] = {DestType, SrcType, SizeType }; +  return getIntrinsic(llvm::Intrinsic::memcpy, ArgTypes, 3);  } -llvm::Function *CodeGenModule::getMemMoveFn() { -  if (MemMoveFn) return MemMoveFn; -  const llvm::Type *IntPtr = TheTargetData.getIntPtrType(VMContext); -  return MemMoveFn = getIntrinsic(llvm::Intrinsic::memmove, &IntPtr, 1); +llvm::Function *CodeGenModule::getMemMoveFn(const llvm::Type *DestType, +                                            const llvm::Type *SrcType, +                                            const llvm::Type *SizeType) { +  const llvm::Type *ArgTypes[3] = {DestType, SrcType, SizeType }; +  return getIntrinsic(llvm::Intrinsic::memmove, ArgTypes, 3);  } -llvm::Function *CodeGenModule::getMemSetFn() { -  if (MemSetFn) return MemSetFn; -  const llvm::Type *IntPtr = TheTargetData.getIntPtrType(VMContext); -  return MemSetFn = getIntrinsic(llvm::Intrinsic::memset, &IntPtr, 1); +llvm::Function *CodeGenModule::getMemSetFn(const llvm::Type *DestType, +                                           const llvm::Type *SizeType) { +  const llvm::Type *ArgTypes[2] = { DestType, SizeType }; +  return getIntrinsic(llvm::Intrinsic::memset, ArgTypes, 2);  }  static llvm::StringMapEntry<llvm::Constant*> & diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 3c57c0b8cbfc..e9f78bcdb0a5 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -97,10 +97,6 @@ class CodeGenModule : public BlockModule {    CGObjCRuntime* Runtime;    CGDebugInfo* DebugInfo; -   -  llvm::Function *MemCpyFn; -  llvm::Function *MemMoveFn; -  llvm::Function *MemSetFn;    // WeakRefReferences - A set of references that have only been seen via    // a weakref so far. This is used to remove the weak of the reference if we ever @@ -290,9 +286,17 @@ public:    llvm::Value *getBuiltinLibFunction(const FunctionDecl *FD,                                       unsigned BuiltinID); -  llvm::Function *getMemCpyFn(); -  llvm::Function *getMemMoveFn(); -  llvm::Function *getMemSetFn(); +  llvm::Function *getMemCpyFn(const llvm::Type *DestType, +                              const llvm::Type *SrcType, +                              const llvm::Type *SizeType); + +  llvm::Function *getMemMoveFn(const llvm::Type *DestType, +                               const llvm::Type *SrcType, +                               const llvm::Type *SizeType); + +  llvm::Function *getMemSetFn(const llvm::Type *DestType, +                              const llvm::Type *SizeType); +    llvm::Function *getIntrinsic(unsigned IID, const llvm::Type **Tys = 0,                                 unsigned NumTys = 0); | 
