diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2013-01-17 00:25:06 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2013-01-17 00:25:06 +0000 |
commit | 90a2d39d3082518566d5a22409a7bbba0d42f054 (patch) | |
tree | 0946d31f50b2e7456bda324632ec7543f2b3cfc9 /lib/CodeGen/CGBlocks.cpp | |
parent | 1c2397539d1b105eacee2a69ece4775d0af45618 (diff) |
objC block layout: Patch reorders block layout to
produce more inline layout metadata. // rdar://12752901
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172683 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGBlocks.cpp')
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 84d8808bb3..b199e76325 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -182,13 +182,16 @@ namespace { struct BlockLayoutChunk { CharUnits Alignment; CharUnits Size; + Qualifiers::ObjCLifetime Lifetime; const BlockDecl::Capture *Capture; // null for 'this' llvm::Type *Type; BlockLayoutChunk(CharUnits align, CharUnits size, + Qualifiers::ObjCLifetime lifetime, const BlockDecl::Capture *capture, llvm::Type *type) - : Alignment(align), Size(size), Capture(capture), Type(type) {} + : Alignment(align), Size(size), Lifetime(lifetime), + Capture(capture), Type(type) {} /// Tell the block info that this chunk has the given field index. void setIndex(CGBlockInfo &info, unsigned index) { @@ -200,9 +203,35 @@ namespace { } }; - /// Order by descending alignment. + /// Order by 1) all __strong together 2) next, all byfref together 3) next, + /// all __weak together. Preserve descending alignment in all situations. bool operator<(const BlockLayoutChunk &left, const BlockLayoutChunk &right) { - return left.Alignment > right.Alignment; + CharUnits LeftValue, RightValue; + bool LeftByref = left.Capture ? left.Capture->isByRef() : false; + bool RightByref = right.Capture ? right.Capture->isByRef() : false; + + if (left.Lifetime == Qualifiers::OCL_Strong && + left.Alignment >= right.Alignment) + LeftValue = CharUnits::fromQuantity(64); + else if (LeftByref && left.Alignment >= right.Alignment) + LeftValue = CharUnits::fromQuantity(32); + else if (left.Lifetime == Qualifiers::OCL_Weak && + left.Alignment >= right.Alignment) + LeftValue = CharUnits::fromQuantity(16); + else + LeftValue = left.Alignment; + if (right.Lifetime == Qualifiers::OCL_Strong && + right.Alignment >= left.Alignment) + RightValue = CharUnits::fromQuantity(64); + else if (RightByref && right.Alignment >= left.Alignment) + RightValue = CharUnits::fromQuantity(32); + else if (right.Lifetime == Qualifiers::OCL_Weak && + right.Alignment >= left.Alignment) + RightValue = CharUnits::fromQuantity(16); + else + RightValue = right.Alignment; + + return LeftValue > RightValue; } } @@ -337,7 +366,9 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, = CGM.getContext().getTypeInfoInChars(thisType); maxFieldAlign = std::max(maxFieldAlign, tinfo.second); - layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first, 0, llvmType)); + layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first, + Qualifiers::OCL_None, + 0, llvmType)); } // Next, all the block captures. @@ -358,6 +389,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, maxFieldAlign = std::max(maxFieldAlign, tinfo.second); layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first, + Qualifiers::OCL_None, &*ci, llvmType)); continue; } @@ -371,8 +403,9 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, // If we have a lifetime qualifier, honor it for capture purposes. // That includes *not* copying it if it's __unsafe_unretained. - if (Qualifiers::ObjCLifetime lifetime - = variable->getType().getObjCLifetime()) { + Qualifiers::ObjCLifetime lifetime = + variable->getType().getObjCLifetime(); + if (lifetime) { switch (lifetime) { case Qualifiers::OCL_None: llvm_unreachable("impossible"); case Qualifiers::OCL_ExplicitNone: @@ -387,6 +420,8 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, // Block pointers require copy/dispose. So do Objective-C pointers. } else if (variable->getType()->isObjCRetainableType()) { info.NeedsCopyDispose = true; + // used for mrr below. + lifetime = Qualifiers::OCL_Strong; // So do types that require non-trivial copy construction. } else if (ci->hasCopyExpr()) { @@ -413,7 +448,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, llvm::Type *llvmType = CGM.getTypes().ConvertTypeForMem(VT); - layout.push_back(BlockLayoutChunk(align, size, &*ci, llvmType)); + layout.push_back(BlockLayoutChunk(align, size, lifetime, &*ci, llvmType)); } // If that was everything, we're done here. |