From e5b4666d9b86ea30b90b599691e75d380f84ddd6 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Tue, 6 Nov 2012 22:15:52 +0000 Subject: [PATCH] Back out 167431+167437+167487; I didn't realize how incomplete our test coverage of this code is. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167495 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGObjCGNU.cpp | 9 +- lib/CodeGen/CGObjCMac.cpp | 235 +++++++++++++++++----------------- lib/CodeGen/CGObjCRuntime.cpp | 20 +-- lib/CodeGen/CGObjCRuntime.h | 12 +- 4 files changed, 141 insertions(+), 135 deletions(-) diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index c181034d51..99abf0545b 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -2083,7 +2083,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { Context.getObjCEncodingForType(IVD->getType(), TypeStr); IvarTypes.push_back(MakeConstantString(TypeStr)); // Get the offset - uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD).getQuantity(); + uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD); uint64_t Offset = BaseOffset; if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) { Offset = BaseOffset - superInstanceSize; @@ -2655,7 +2655,7 @@ llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable( // description. if (!CGM.getContext().getObjCImplementation( const_cast(ID))) - Offset = ComputeIvarBaseOffset(CGM, ID, Ivar).getQuantity(); + Offset = ComputeIvarBaseOffset(CGM, ID, Ivar); llvm::ConstantInt *OffsetGuess = llvm::ConstantInt::get(Int32Ty, Offset, /*isSigned*/true); @@ -2728,9 +2728,8 @@ llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGenFunction &CGF, Offset = CGF.Builder.CreateZExtOrBitCast(Offset, PtrDiffTy); return Offset; } - CharUnits Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar); - return llvm::ConstantInt::get(PtrDiffTy, Offset.getQuantity(), - /*isSigned*/true); + uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar); + return llvm::ConstantInt::get(PtrDiffTy, Offset, /*isSigned*/true); } CGObjCRuntime * diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 6c0b82bb26..7c9d215a27 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -736,10 +736,9 @@ public: // FIXME - accessibility class GC_IVAR { public: - CharUnits ivar_bytepos; - CharUnits ivar_size; - GC_IVAR(CharUnits bytepos = CharUnits::Zero(), - CharUnits size = CharUnits::Zero()) + unsigned ivar_bytepos; + unsigned ivar_size; + GC_IVAR(unsigned bytepos = 0, unsigned size = 0) : ivar_bytepos(bytepos), ivar_size(size) {} // Allow sorting based on byte pos. @@ -811,11 +810,10 @@ public: class RUN_SKIP { public: enum BLOCK_LAYOUT_OPCODE opcode; - CharUnits block_var_bytepos; - CharUnits block_var_size; + unsigned block_var_bytepos; + unsigned block_var_size; RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR, - CharUnits BytePos = CharUnits::Zero(), - CharUnits Size = CharUnits::Zero()) + unsigned BytePos = 0, unsigned Size = 0) : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {} // Allow sorting based on byte pos. @@ -935,29 +933,29 @@ protected: llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap); void BuildAggrIvarRecordLayout(const RecordType *RT, - CharUnits BytePos, bool ForStrongLayout, + unsigned int BytePos, bool ForStrongLayout, bool &HasUnion); void BuildAggrIvarLayout(const ObjCImplementationDecl *OI, const llvm::StructLayout *Layout, const RecordDecl *RD, ArrayRef RecFields, - CharUnits BytePos, bool ForStrongLayout, + unsigned int BytePos, bool ForStrongLayout, bool &HasUnion); Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT); void UpdateRunSkipBlockVars(bool IsByref, Qualifiers::ObjCLifetime LifeTime, - CharUnits FieldOffset, - CharUnits FieldSize); + unsigned FieldOffset, + unsigned FieldSize); void BuildRCBlockVarRecordLayout(const RecordType *RT, - CharUnits BytePos, bool &HasUnion); + unsigned int BytePos, bool &HasUnion); void BuildRCRecordLayout(const llvm::StructLayout *RecLayout, const RecordDecl *RD, ArrayRef RecFields, - CharUnits BytePos, bool &HasUnion); + unsigned int BytePos, bool &HasUnion); uint64_t InlineLayoutInstruction(SmallVectorImpl &Layout); @@ -1326,7 +1324,7 @@ private: llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, const ObjCIvarDecl *Ivar, - CharUnits offset); + unsigned long int offset); /// GetOrEmitProtocol - Get the protocol object for the given /// declaration, emitting it if necessary. The return value has type @@ -1890,13 +1888,12 @@ llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM, bool hasUnion = false; SkipIvars.clear(); IvarsInfo.clear(); - CharUnits WordSize = - CGM.getContext().toCharUnitsFromBits( - CGM.getContext().getTargetInfo().getPointerWidth(0)); + unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0); + unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth(); // __isa is the first field in block descriptor and must assume by runtime's // convention that it is GC'able. - IvarsInfo.push_back(GC_IVAR(CharUnits::Zero(), WordSize)); + IvarsInfo.push_back(GC_IVAR(0, 1)); const BlockDecl *blockDecl = blockInfo.getBlockDecl(); @@ -1918,12 +1915,11 @@ llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM, // Ignore constant captures. if (capture.isConstant()) continue; - CharUnits fieldOffset = - CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex())); + uint64_t fieldOffset = layout->getElementOffset(capture.getIndex()); // __block variables are passed by their descriptor address. if (ci->isByRef()) { - IvarsInfo.push_back(GC_IVAR(fieldOffset, WordSize)); + IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1)); continue; } @@ -1934,12 +1930,14 @@ llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM, } Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type); - CharUnits fieldSize = CGM.getContext().getTypeSizeInChars(type); + unsigned fieldSize = CGM.getContext().getTypeSize(type); if (GCAttr == Qualifiers::Strong) - IvarsInfo.push_back(GC_IVAR(fieldOffset, fieldSize)); + IvarsInfo.push_back(GC_IVAR(fieldOffset, + fieldSize / WordSizeInBits)); else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak) - SkipIvars.push_back(GC_IVAR(fieldOffset, fieldSize)); + SkipIvars.push_back(GC_IVAR(fieldOffset, + fieldSize / ByteSizeInBits)); } if (IvarsInfo.empty()) @@ -1982,37 +1980,40 @@ Qualifiers::ObjCLifetime CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT) void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref, Qualifiers::ObjCLifetime LifeTime, - CharUnits FieldOffset, - CharUnits FieldSize) { + unsigned FieldOffset, + unsigned FieldSize) { + unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth(); + unsigned FieldSizeInBytes = FieldSize/ByteSizeInBits; + // __block variables are passed by their descriptor address. if (IsByref) RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset, - FieldSize)); + FieldSizeInBytes)); else if (LifeTime == Qualifiers::OCL_Strong) RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset, - FieldSize)); + FieldSizeInBytes)); else if (LifeTime == Qualifiers::OCL_Weak) RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset, - FieldSize)); + FieldSizeInBytes)); else if (LifeTime == Qualifiers::OCL_ExplicitNone) RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset, - FieldSize)); + FieldSizeInBytes)); else RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES, FieldOffset, - FieldSize)); + FieldSizeInBytes)); } void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, const RecordDecl *RD, ArrayRef RecFields, - CharUnits BytePos, bool &HasUnion) { + unsigned int BytePos, bool &HasUnion) { bool IsUnion = (RD && RD->isUnion()); - CharUnits MaxUnionSize = CharUnits::Zero(); + uint64_t MaxUnionSize = 0; const FieldDecl *MaxField = 0; const FieldDecl *LastFieldBitfieldOrUnnamed = 0; - CharUnits MaxFieldOffset = CharUnits::Zero(); - CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero(); + uint64_t MaxFieldOffset = 0; + uint64_t LastBitfieldOrUnnamedOffset = 0; if (RecFields.empty()) return; @@ -2020,11 +2021,11 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { const FieldDecl *Field = RecFields[i]; + uint64_t FieldOffset; // Note that 'i' here is actually the field index inside RD of Field, // although this dependency is hidden. const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); - CharUnits FieldOffset = - CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i)); + FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits); // Skip over unnamed or bitfields if (!Field->getIdentifier() || Field->isBitField()) { @@ -2069,7 +2070,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, // one element is already done. uint64_t ElIx = 1; for (int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) { - CharUnits Size = CGM.getContext().getTypeSizeInChars(RT); + uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits; for (int i = OldIndex+1; i <= FirstIndex; ++i) RunSkipBlockVars.push_back( RUN_SKIP(RunSkipBlockVars[i].opcode, @@ -2079,9 +2080,9 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, continue; } } - CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType()); + unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType()); if (IsUnion) { - CharUnits UnionIvarSize = FieldSize; + uint64_t UnionIvarSize = FieldSize; if (UnionIvarSize > MaxUnionSize) { MaxUnionSize = UnionIvarSize; MaxField = Field; @@ -2100,19 +2101,18 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, // Last field was a bitfield. Must update the info. uint64_t BitFieldSize = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext()); - CharUnits Size = - CharUnits::fromQuantity( - (BitFieldSize + ByteSizeInBits - 1) / ByteSizeInBits); + unsigned Size = (BitFieldSize / ByteSizeInBits) + + ((BitFieldSize % ByteSizeInBits) != 0); Size += LastBitfieldOrUnnamedOffset; UpdateRunSkipBlockVars(false, getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType()), BytePos + LastBitfieldOrUnnamedOffset, - Size); + Size*ByteSizeInBits); } else { assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed"); // Last field was unnamed. Must update skip info. - CharUnits FieldSize - = CGM.getContext().getTypeSizeInChars(LastFieldBitfieldOrUnnamed->getType()); + unsigned FieldSize + = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType()); UpdateRunSkipBlockVars(false, getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType()), BytePos + LastBitfieldOrUnnamedOffset, @@ -2128,7 +2128,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, } void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT, - CharUnits BytePos, + unsigned int BytePos, bool &HasUnion) { const RecordDecl *RD = RT->getDecl(); SmallVector Fields; @@ -2281,19 +2281,15 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM, // Ignore constant captures. if (capture.isConstant()) continue; - CharUnits fieldOffset = - CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex())); + uint64_t fieldOffset = layout->getElementOffset(capture.getIndex()); assert(!type->isArrayType() && "array variable should not be caught"); if (const RecordType *record = type->getAs()) { BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion); continue; } - CharUnits fieldSize; - if (ci->isByRef()) - fieldSize = CharUnits::fromQuantity(WordSizeInBytes); - else - fieldSize = CGM.getContext().getTypeSizeInChars(type); + unsigned fieldSize = ci->isByRef() ? WordSizeInBits + : CGM.getContext().getTypeSize(type); UpdateRunSkipBlockVars(ci->isByRef(), getBlockCaptureLifetime(type), fieldOffset, fieldSize); } @@ -2307,10 +2303,12 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM, SmallVector Layout; unsigned size = RunSkipBlockVars.size(); + unsigned int shift = (WordSizeInBytes == 8) ? 3 : 2; + unsigned int mask = (WordSizeInBytes == 8) ? 0x7 : 0x3; for (unsigned i = 0; i < size; i++) { enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode; - CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos; - CharUnits end_byte_pos = start_byte_pos; + unsigned start_byte_pos = RunSkipBlockVars[i].block_var_bytepos; + unsigned end_byte_pos = start_byte_pos; unsigned j = i+1; while (j < size) { if (opcode == RunSkipBlockVars[j].opcode) { @@ -2320,22 +2318,22 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM, else break; } - CharUnits size_in_bytes = + unsigned size_in_bytes = end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size; if (j < size) { - CharUnits gap = + unsigned gap = RunSkipBlockVars[j].block_var_bytepos - RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size; size_in_bytes += gap; } - CharUnits residue_in_bytes = CharUnits::Zero(); + unsigned residue_in_bytes = 0; if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) { - residue_in_bytes = size_in_bytes % WordSizeInBytes; + residue_in_bytes = size_in_bytes & mask; size_in_bytes -= residue_in_bytes; opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS; } - unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes; + unsigned size_in_words = size_in_bytes >> shift; while (size_in_words >= 16) { // Note that value in imm. is one less that the actual // value. So, 0xf means 16 words follow! @@ -2349,10 +2347,9 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM, unsigned char inst = (opcode << 4) | (size_in_words-1); Layout.push_back(inst); } - if (residue_in_bytes > CharUnits::Zero()) { + if (residue_in_bytes > 0) { unsigned char inst = - (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | - (residue_in_bytes.getQuantity()-1); + (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes-1); Layout.push_back(inst); } } @@ -3229,7 +3226,7 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, GetMethodVarName(IVD->getIdentifier()), GetMethodVarType(IVD), llvm::ConstantInt::get(ObjCTypes.IntTy, - ComputeIvarBaseOffset(CGM, OID, IVD).getQuantity()) + ComputeIvarBaseOffset(CGM, OID, IVD)) }; Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar)); } @@ -4175,8 +4172,10 @@ LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar) { - CharUnits Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar); - return llvm::ConstantInt::get(ObjCTypes.LongTy, Offset.getQuantity()); + uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar); + return llvm::ConstantInt::get( + CGM.getTypes().ConvertType(CGM.getContext().LongTy), + Offset); } /* *** Private Interface *** */ @@ -4398,7 +4397,7 @@ llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident, } void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT, - CharUnits BytePos, + unsigned int BytePos, bool ForStrongLayout, bool &HasUnion) { const RecordDecl *RD = RT->getDecl(); @@ -4419,36 +4418,37 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, const llvm::StructLayout *Layout, const RecordDecl *RD, ArrayRef RecFields, - CharUnits BytePos, bool ForStrongLayout, + unsigned int BytePos, bool ForStrongLayout, bool &HasUnion) { bool IsUnion = (RD && RD->isUnion()); - CharUnits MaxUnionIvarSize = CharUnits::Zero(); - CharUnits MaxSkippedUnionIvarSize = CharUnits::Zero(); + uint64_t MaxUnionIvarSize = 0; + uint64_t MaxSkippedUnionIvarSize = 0; const FieldDecl *MaxField = 0; const FieldDecl *MaxSkippedField = 0; const FieldDecl *LastFieldBitfieldOrUnnamed = 0; - CharUnits MaxFieldOffset = CharUnits::Zero(); - CharUnits MaxSkippedFieldOffset = CharUnits::Zero(); - CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero(); - CharUnits FirstFieldDelta = CharUnits::Zero(); + uint64_t MaxFieldOffset = 0; + uint64_t MaxSkippedFieldOffset = 0; + uint64_t LastBitfieldOrUnnamedOffset = 0; + uint64_t FirstFieldDelta = 0; if (RecFields.empty()) return; + unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0); unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth(); if (!RD && CGM.getLangOpts().ObjCAutoRefCount) { - const ObjCIvarDecl *FirstField = cast(RecFields[0]); - FirstFieldDelta = ComputeIvarBaseOffset(CGM, OI, FirstField); + const FieldDecl *FirstField = RecFields[0]; + FirstFieldDelta = + ComputeIvarBaseOffset(CGM, OI, cast(FirstField)); } for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { const FieldDecl *Field = RecFields[i]; - CharUnits FieldOffset; + uint64_t FieldOffset; if (RD) { // Note that 'i' here is actually the field index inside RD of Field, // although this dependency is hidden. const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); - FieldOffset = CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i)) - - FirstFieldDelta; + FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta; } else FieldOffset = ComputeIvarBaseOffset(CGM, OI, cast(Field)) - FirstFieldDelta; @@ -4500,7 +4500,7 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, uint64_t ElIx = 1; for (int FirstIndex = IvarsInfo.size() - 1, FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) { - CharUnits Size = CGM.getContext().getTypeSizeInChars(RT); + uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits; for (int i = OldIndex+1; i <= FirstIndex; ++i) IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx, IvarsInfo[i].ivar_size)); @@ -4515,31 +4515,36 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, // For other arrays we are down to its element type. Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT); - CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType()); + unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType()); if ((ForStrongLayout && GCAttr == Qualifiers::Strong) || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { if (IsUnion) { - CharUnits UnionIvarSize = FieldSize; + uint64_t UnionIvarSize = FieldSize / WordSizeInBits; if (UnionIvarSize > MaxUnionIvarSize) { MaxUnionIvarSize = UnionIvarSize; MaxField = Field; MaxFieldOffset = FieldOffset; } } else { - IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset, FieldSize)); + IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset, + FieldSize / WordSizeInBits)); } } else if ((ForStrongLayout && (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)) || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) { if (IsUnion) { - CharUnits UnionIvarSize = FieldSize; + // FIXME: Why the asymmetry? We divide by word size in bits on other + // side. + uint64_t UnionIvarSize = FieldSize / ByteSizeInBits; if (UnionIvarSize > MaxSkippedUnionIvarSize) { MaxSkippedUnionIvarSize = UnionIvarSize; MaxSkippedField = Field; MaxSkippedFieldOffset = FieldOffset; } } else { - SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset, FieldSize)); + // FIXME: Why the asymmetry, we divide by byte size in bits here? + SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset, + FieldSize / ByteSizeInBits)); } } } @@ -4551,16 +4556,16 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext()); GC_IVAR skivar; skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset; - skivar.ivar_size = CharUnits::fromQuantity( - (BitFieldSize + ByteSizeInBits - 1) / ByteSizeInBits); + skivar.ivar_size = (BitFieldSize / ByteSizeInBits) + + ((BitFieldSize % ByteSizeInBits) != 0); SkipIvars.push_back(skivar); } else { assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed"); // Last field was unnamed. Must update skip info. - CharUnits FieldSize - = CGM.getContext().getTypeSizeInChars(LastFieldBitfieldOrUnnamed->getType()); + unsigned FieldSize + = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType()); SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset, - FieldSize)); + FieldSize / ByteSizeInBits)); } } @@ -4578,21 +4583,26 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, /// two containers, IvarsInfo and SkipIvars which are assumed to be /// filled already by the caller. llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) { + unsigned int WordsToScan, WordsToSkip; llvm::Type *PtrTy = CGM.Int8PtrTy; // Build the string of skip/scan nibbles SmallVector SkipScanIvars; - CharUnits WordSize = CharUnits::fromQuantity( - CGM.getTypes().getDataLayout().getTypeAllocSize(PtrTy)); - unsigned WordsToSkip = IvarsInfo[0].ivar_bytepos / WordSize; - unsigned WordsToScan = IvarsInfo[0].ivar_size / WordSize; - + unsigned int WordSize = + CGM.getTypes().getDataLayout().getTypeAllocSize(PtrTy); + if (IvarsInfo[0].ivar_bytepos == 0) { + WordsToSkip = 0; + WordsToScan = IvarsInfo[0].ivar_size; + } else { + WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize; + WordsToScan = IvarsInfo[0].ivar_size; + } for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) { - CharUnits TailPrevGCObjC = - IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size; + unsigned int TailPrevGCObjC = + IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize; if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) { // consecutive 'scanned' object pointers. - WordsToScan += IvarsInfo[i].ivar_size / WordSize; + WordsToScan += IvarsInfo[i].ivar_size; } else { // Skip over 'gc'able object pointer which lay over each other. if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos) @@ -4609,7 +4619,7 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) { SkScan.scan = 0; SkipScanIvars.push_back(SkScan); WordsToSkip = 0; - WordsToScan = IvarsInfo[i].ivar_size / WordSize; + WordsToScan = IvarsInfo[i].ivar_size; } } if (WordsToScan > 0) { @@ -4621,19 +4631,17 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) { if (!SkipIvars.empty()) { unsigned int LastIndex = SkipIvars.size()-1; - CharUnits LastByteSkipped = - SkipIvars[LastIndex].ivar_bytepos + - SkipIvars[LastIndex].ivar_size; + int LastByteSkipped = + SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size; LastIndex = IvarsInfo.size()-1; - CharUnits LastByteScanned = - IvarsInfo[LastIndex].ivar_bytepos + - IvarsInfo[LastIndex].ivar_size; + int LastByteScanned = + IvarsInfo[LastIndex].ivar_bytepos + + IvarsInfo[LastIndex].ivar_size * WordSize; // Compute number of bytes to skip at the tail end of the last ivar scanned. if (LastByteSkipped > LastByteScanned) { - unsigned int TotalWords = - (LastByteSkipped + (WordSize - CharUnits::One())) / WordSize; + unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize; SKIP_SCAN SkScan; - SkScan.skip = TotalWords - LastByteScanned / WordSize; + SkScan.skip = TotalWords - (LastByteScanned/WordSize); SkScan.scan = 0; SkipScanIvars.push_back(SkScan); } @@ -4746,8 +4754,7 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayout( SkipIvars.clear(); IvarsInfo.clear(); - BuildAggrIvarLayout(OMD, 0, 0, RecFields, CharUnits::Zero(), - ForStrongLayout, hasUnion); + BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion); if (IvarsInfo.empty()) return llvm::Constant::getNullValue(PtrTy); // Sort on byte position in case we encounterred a union nested in @@ -6015,10 +6022,10 @@ CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, const ObjCIvarDecl *Ivar, - CharUnits Offset) { + unsigned long int Offset) { llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar); IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy, - Offset.getQuantity())); + Offset)); IvarOffsetGV->setAlignment( CGM.getDataLayout().getABITypeAlignment(ObjCTypes.LongTy)); diff --git a/lib/CodeGen/CGObjCRuntime.cpp b/lib/CodeGen/CGObjCRuntime.cpp index 71a3774ff8..9aa68376bc 100644 --- a/lib/CodeGen/CGObjCRuntime.cpp +++ b/lib/CodeGen/CGObjCRuntime.cpp @@ -64,18 +64,18 @@ static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM, return RL->getFieldOffset(Index); } -CharUnits CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, - const ObjCInterfaceDecl *OID, - const ObjCIvarDecl *Ivar) { - return CGM.getContext().toCharUnitsFromBits( - LookupFieldBitOffset(CGM, OID, 0, Ivar)); +uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, + const ObjCInterfaceDecl *OID, + const ObjCIvarDecl *Ivar) { + return LookupFieldBitOffset(CGM, OID, 0, Ivar) / + CGM.getContext().getCharWidth(); } -CharUnits CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, - const ObjCImplementationDecl *OID, - const ObjCIvarDecl *Ivar) { - return CGM.getContext().toCharUnitsFromBits( - LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar)); +uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, + const ObjCImplementationDecl *OID, + const ObjCIvarDecl *Ivar) { + return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) / + CGM.getContext().getCharWidth(); } LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index 2178692854..bc6589dd69 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -76,12 +76,12 @@ protected: /// /// The latter overload is suitable for computing the offset of a /// sythesized ivar. - CharUnits ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, - const ObjCInterfaceDecl *OID, - const ObjCIvarDecl *Ivar); - CharUnits ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, - const ObjCImplementationDecl *OID, - const ObjCIvarDecl *Ivar); + uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, + const ObjCInterfaceDecl *OID, + const ObjCIvarDecl *Ivar); + uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, + const ObjCImplementationDecl *OID, + const ObjCIvarDecl *Ivar); LValue EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *OID, -- 2.40.0