From 70459fc5b6f00c897f93f12bb8326e50fa3068f7 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Tue, 6 Nov 2012 03:41:04 +0000 Subject: [PATCH] Propagate CharUnits through CGObjCMac.cpp. llvm-svn: 167437 --- clang/lib/CodeGen/CGObjCMac.cpp | 162 +++++++++++++++++++--------------------- 1 file changed, 78 insertions(+), 84 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 9d06fbd..3b188ec 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -737,8 +737,9 @@ public: class GC_IVAR { public: CharUnits ivar_bytepos; - unsigned ivar_size; - GC_IVAR(CharUnits bytepos = CharUnits::Zero(), unsigned size = 0) + CharUnits ivar_size; + GC_IVAR(CharUnits bytepos = CharUnits::Zero(), + CharUnits size = CharUnits::Zero()) : ivar_bytepos(bytepos), ivar_size(size) {} // Allow sorting based on byte pos. @@ -810,10 +811,11 @@ public: class RUN_SKIP { public: enum BLOCK_LAYOUT_OPCODE opcode; - unsigned block_var_bytepos; - unsigned block_var_size; + CharUnits block_var_bytepos; + CharUnits block_var_size; RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR, - unsigned BytePos = 0, unsigned Size = 0) + CharUnits BytePos = CharUnits::Zero(), + CharUnits Size = CharUnits::Zero()) : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {} // Allow sorting based on byte pos. @@ -946,16 +948,16 @@ protected: void UpdateRunSkipBlockVars(bool IsByref, Qualifiers::ObjCLifetime LifeTime, - unsigned FieldOffset, - unsigned FieldSize); + CharUnits FieldOffset, + CharUnits FieldSize); void BuildRCBlockVarRecordLayout(const RecordType *RT, - unsigned int BytePos, bool &HasUnion); + CharUnits BytePos, bool &HasUnion); void BuildRCRecordLayout(const llvm::StructLayout *RecLayout, const RecordDecl *RD, ArrayRef RecFields, - unsigned int BytePos, bool &HasUnion); + CharUnits BytePos, bool &HasUnion); uint64_t InlineLayoutInstruction(SmallVectorImpl &Layout); @@ -1888,12 +1890,13 @@ llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM, bool hasUnion = false; SkipIvars.clear(); IvarsInfo.clear(); - unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0); - unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth(); + CharUnits WordSize = + CGM.getContext().toCharUnitsFromBits( + CGM.getContext().getTargetInfo().getPointerWidth(0)); // __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(), 1)); + IvarsInfo.push_back(GC_IVAR(CharUnits::Zero(), WordSize)); const BlockDecl *blockDecl = blockInfo.getBlockDecl(); @@ -1920,7 +1923,7 @@ llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM, // __block variables are passed by their descriptor address. if (ci->isByRef()) { - IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1)); + IvarsInfo.push_back(GC_IVAR(fieldOffset, WordSize)); continue; } @@ -1931,14 +1934,12 @@ llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM, } Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type); - unsigned fieldSize = CGM.getContext().getTypeSize(type); + CharUnits fieldSize = CGM.getContext().getTypeSizeInChars(type); if (GCAttr == Qualifiers::Strong) - IvarsInfo.push_back(GC_IVAR(fieldOffset, - fieldSize / WordSizeInBits)); + IvarsInfo.push_back(GC_IVAR(fieldOffset, fieldSize)); else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak) - SkipIvars.push_back(GC_IVAR(fieldOffset, - fieldSize / ByteSizeInBits)); + SkipIvars.push_back(GC_IVAR(fieldOffset, fieldSize)); } if (IvarsInfo.empty()) @@ -1981,40 +1982,37 @@ Qualifiers::ObjCLifetime CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT) void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref, Qualifiers::ObjCLifetime LifeTime, - unsigned FieldOffset, - unsigned FieldSize) { - unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth(); - unsigned FieldSizeInBytes = FieldSize/ByteSizeInBits; - + CharUnits FieldOffset, + CharUnits FieldSize) { // __block variables are passed by their descriptor address. if (IsByref) RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset, - FieldSizeInBytes)); + FieldSize)); else if (LifeTime == Qualifiers::OCL_Strong) RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset, - FieldSizeInBytes)); + FieldSize)); else if (LifeTime == Qualifiers::OCL_Weak) RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset, - FieldSizeInBytes)); + FieldSize)); else if (LifeTime == Qualifiers::OCL_ExplicitNone) RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset, - FieldSizeInBytes)); + FieldSize)); else RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES, FieldOffset, - FieldSizeInBytes)); + FieldSize)); } void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, const RecordDecl *RD, ArrayRef RecFields, - unsigned int BytePos, bool &HasUnion) { + CharUnits BytePos, bool &HasUnion) { bool IsUnion = (RD && RD->isUnion()); - uint64_t MaxUnionSize = 0; + CharUnits MaxUnionSize = CharUnits::Zero(); const FieldDecl *MaxField = 0; const FieldDecl *LastFieldBitfieldOrUnnamed = 0; - uint64_t MaxFieldOffset = 0; - uint64_t LastBitfieldOrUnnamedOffset = 0; + CharUnits MaxFieldOffset = CharUnits::Zero(); + CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero(); if (RecFields.empty()) return; @@ -2022,11 +2020,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); - FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits); + CharUnits FieldOffset = + CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i)); // Skip over unnamed or bitfields if (!Field->getIdentifier() || Field->isBitField()) { @@ -2071,7 +2069,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++) { - uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits; + CharUnits Size = CGM.getContext().getTypeSizeInChars(RT); for (int i = OldIndex+1; i <= FirstIndex; ++i) RunSkipBlockVars.push_back( RUN_SKIP(RunSkipBlockVars[i].opcode, @@ -2081,9 +2079,9 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, continue; } } - unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType()); + CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType()); if (IsUnion) { - uint64_t UnionIvarSize = FieldSize; + CharUnits UnionIvarSize = FieldSize; if (UnionIvarSize > MaxUnionSize) { MaxUnionSize = UnionIvarSize; MaxField = Field; @@ -2102,18 +2100,19 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, // Last field was a bitfield. Must update the info. uint64_t BitFieldSize = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext()); - unsigned Size = (BitFieldSize / ByteSizeInBits) + - ((BitFieldSize % ByteSizeInBits) != 0); + CharUnits Size = + CharUnits::fromQuantity( + (BitFieldSize + ByteSizeInBits) / ByteSizeInBits); Size += LastBitfieldOrUnnamedOffset; UpdateRunSkipBlockVars(false, getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType()), BytePos + LastBitfieldOrUnnamedOffset, - Size*ByteSizeInBits); + Size); } else { assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed"); // Last field was unnamed. Must update skip info. - unsigned FieldSize - = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType()); + CharUnits FieldSize + = CGM.getContext().getTypeSizeInChars(LastFieldBitfieldOrUnnamed->getType()); UpdateRunSkipBlockVars(false, getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType()), BytePos + LastBitfieldOrUnnamedOffset, @@ -2129,7 +2128,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, } void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT, - unsigned int BytePos, + CharUnits BytePos, bool &HasUnion) { const RecordDecl *RD = RT->getDecl(); SmallVector Fields; @@ -2282,15 +2281,19 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM, // Ignore constant captures. if (capture.isConstant()) continue; - uint64_t fieldOffset = layout->getElementOffset(capture.getIndex()); + CharUnits fieldOffset = + CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex())); assert(!type->isArrayType() && "array variable should not be caught"); if (const RecordType *record = type->getAs()) { BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion); continue; } - unsigned fieldSize = ci->isByRef() ? WordSizeInBits - : CGM.getContext().getTypeSize(type); + CharUnits fieldSize; + if (ci->isByRef()) + fieldSize = CharUnits::fromQuantity(WordSizeInBytes); + else + fieldSize = CGM.getContext().getTypeSizeInChars(type); UpdateRunSkipBlockVars(ci->isByRef(), getBlockCaptureLifetime(type), fieldOffset, fieldSize); } @@ -2304,12 +2307,10 @@ 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; - unsigned start_byte_pos = RunSkipBlockVars[i].block_var_bytepos; - unsigned end_byte_pos = start_byte_pos; + CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos; + CharUnits end_byte_pos = start_byte_pos; unsigned j = i+1; while (j < size) { if (opcode == RunSkipBlockVars[j].opcode) { @@ -2319,22 +2320,22 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM, else break; } - unsigned size_in_bytes = + CharUnits size_in_bytes = end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size; if (j < size) { - unsigned gap = + CharUnits gap = RunSkipBlockVars[j].block_var_bytepos - RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size; size_in_bytes += gap; } - unsigned residue_in_bytes = 0; + CharUnits residue_in_bytes = CharUnits::Zero(); if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) { - residue_in_bytes = size_in_bytes & mask; + residue_in_bytes = size_in_bytes % WordSizeInBytes; size_in_bytes -= residue_in_bytes; opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS; } - unsigned size_in_words = size_in_bytes >> shift; + unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes; while (size_in_words >= 16) { // Note that value in imm. is one less that the actual // value. So, 0xf means 16 words follow! @@ -2348,9 +2349,10 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM, unsigned char inst = (opcode << 4) | (size_in_words-1); Layout.push_back(inst); } - if (residue_in_bytes > 0) { + if (residue_in_bytes > CharUnits::Zero()) { unsigned char inst = - (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes-1); + (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | + (residue_in_bytes.getQuantity()-1); Layout.push_back(inst); } } @@ -4420,8 +4422,8 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, CharUnits BytePos, bool ForStrongLayout, bool &HasUnion) { bool IsUnion = (RD && RD->isUnion()); - uint64_t MaxUnionIvarSize = 0; - uint64_t MaxSkippedUnionIvarSize = 0; + CharUnits MaxUnionIvarSize = CharUnits::Zero(); + CharUnits MaxSkippedUnionIvarSize = CharUnits::Zero(); const FieldDecl *MaxField = 0; const FieldDecl *MaxSkippedField = 0; const FieldDecl *LastFieldBitfieldOrUnnamed = 0; @@ -4432,7 +4434,6 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, 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]); @@ -4514,36 +4515,31 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, // For other arrays we are down to its element type. Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT); - unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType()); + CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType()); if ((ForStrongLayout && GCAttr == Qualifiers::Strong) || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { if (IsUnion) { - uint64_t UnionIvarSize = FieldSize / WordSizeInBits; + CharUnits UnionIvarSize = FieldSize; if (UnionIvarSize > MaxUnionIvarSize) { MaxUnionIvarSize = UnionIvarSize; MaxField = Field; MaxFieldOffset = FieldOffset; } } else { - IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset, - FieldSize / WordSizeInBits)); + IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset, FieldSize)); } } else if ((ForStrongLayout && (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)) || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) { if (IsUnion) { - // FIXME: Why the asymmetry? We divide by word size in bits on other - // side. - uint64_t UnionIvarSize = FieldSize / ByteSizeInBits; + CharUnits UnionIvarSize = FieldSize; if (UnionIvarSize > MaxSkippedUnionIvarSize) { MaxSkippedUnionIvarSize = UnionIvarSize; MaxSkippedField = Field; MaxSkippedFieldOffset = FieldOffset; } } else { - // FIXME: Why the asymmetry, we divide by byte size in bits here? - SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset, - FieldSize / ByteSizeInBits)); + SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset, FieldSize)); } } } @@ -4555,16 +4551,16 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext()); GC_IVAR skivar; skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset; - skivar.ivar_size = (BitFieldSize / ByteSizeInBits) - + ((BitFieldSize % ByteSizeInBits) != 0); + skivar.ivar_size = CharUnits::fromQuantity( + (BitFieldSize + ByteSizeInBits) / ByteSizeInBits); SkipIvars.push_back(skivar); } else { assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed"); // Last field was unnamed. Must update skip info. - unsigned FieldSize - = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType()); + CharUnits FieldSize + = CGM.getContext().getTypeSizeInChars(LastFieldBitfieldOrUnnamed->getType()); SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset, - FieldSize / ByteSizeInBits)); + FieldSize)); } } @@ -4588,15 +4584,15 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) { SmallVector SkipScanIvars; CharUnits WordSize = CharUnits::fromQuantity( CGM.getTypes().getDataLayout().getTypeAllocSize(PtrTy)); - unsigned WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize; - unsigned WordsToScan = IvarsInfo[0].ivar_size; + unsigned WordsToSkip = IvarsInfo[0].ivar_bytepos / WordSize; + unsigned WordsToScan = IvarsInfo[0].ivar_size / WordSize; for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) { CharUnits TailPrevGCObjC = - IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize; + IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size; if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) { // consecutive 'scanned' object pointers. - WordsToScan += IvarsInfo[i].ivar_size; + WordsToScan += IvarsInfo[i].ivar_size / WordSize; } else { // Skip over 'gc'able object pointer which lay over each other. if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos) @@ -4613,7 +4609,7 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) { SkScan.scan = 0; SkipScanIvars.push_back(SkScan); WordsToSkip = 0; - WordsToScan = IvarsInfo[i].ivar_size; + WordsToScan = IvarsInfo[i].ivar_size / WordSize; } } if (WordsToScan > 0) { @@ -4625,15 +4621,13 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) { if (!SkipIvars.empty()) { unsigned int LastIndex = SkipIvars.size()-1; - // FIXME: Shouldn't be using CharUnits::One here; what are the units of - // ivar_size? CharUnits LastByteSkipped = SkipIvars[LastIndex].ivar_bytepos + - SkipIvars[LastIndex].ivar_size * CharUnits::One(); + SkipIvars[LastIndex].ivar_size; LastIndex = IvarsInfo.size()-1; CharUnits LastByteScanned = IvarsInfo[LastIndex].ivar_bytepos + - IvarsInfo[LastIndex].ivar_size * WordSize; + IvarsInfo[LastIndex].ivar_size; // Compute number of bytes to skip at the tail end of the last ivar scanned. if (LastByteSkipped > LastByteScanned) { unsigned int TotalWords = -- 2.7.4