mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Revert "Implement bridgeobject_retain/release merging in LLVMARCContract. rdar://22108790"
This reverts commit r32132. It broke tests: Swift :: 1_stdlib/FloatingPoint.swift.gyb Swift :: 1_stdlib/NSStringAPI.swift Swift :: 1_stdlib/Runtime.swift Swift :: Interpreter/SDK/CoreGraphics_CGFloat.swift Swift SVN r32142
This commit is contained in:
@@ -47,12 +47,9 @@ class ARCEntryPointBuilder {
|
||||
NullablePtr<Constant> ReleaseN;
|
||||
NullablePtr<Constant> UnknownRetainN;
|
||||
NullablePtr<Constant> UnknownReleaseN;
|
||||
NullablePtr<Constant> BridgeRetainN;
|
||||
NullablePtr<Constant> BridgeReleaseN;
|
||||
|
||||
// The type cache.
|
||||
NullablePtr<Type> ObjectPtrTy;
|
||||
NullablePtr<Type> BridgeObjectPtrTy;
|
||||
|
||||
public:
|
||||
ARCEntryPointBuilder(Function &F) : B(F.begin()), Retain(), ObjectPtrTy() {}
|
||||
@@ -141,21 +138,6 @@ public:
|
||||
return CI;
|
||||
}
|
||||
|
||||
CallInst *createBridgeRetainN(Value *V, uint32_t n) {
|
||||
// Cast just to make sure we have the right object type.
|
||||
V = B.CreatePointerCast(V, getBridgeObjectPtrTy());
|
||||
CallInst *CI = B.CreateCall(getBridgeRetainN(), {V, getIntConstant(n)});
|
||||
CI->setTailCall(true);
|
||||
return CI;
|
||||
}
|
||||
|
||||
CallInst *createBridgeReleaseN(Value *V, uint32_t n) {
|
||||
// Cast just to make sure we have the right object type.
|
||||
V = B.CreatePointerCast(V, getBridgeObjectPtrTy());
|
||||
CallInst *CI = B.CreateCall(getBridgeReleaseN(), {V, getIntConstant(n)});
|
||||
CI->setTailCall(true);
|
||||
return CI;
|
||||
}
|
||||
|
||||
private:
|
||||
Module &getModule() {
|
||||
@@ -271,40 +253,6 @@ private:
|
||||
return UnknownReleaseN.get();
|
||||
}
|
||||
|
||||
/// Return a callable function for swift_bridgeRetain_n.
|
||||
Constant *getBridgeRetainN() {
|
||||
if (BridgeRetainN)
|
||||
return BridgeRetainN.get();
|
||||
auto *BridgeObjectPtrTy = getBridgeObjectPtrTy();
|
||||
auto &M = getModule();
|
||||
|
||||
auto *Int32Ty = Type::getInt32Ty(M.getContext());
|
||||
auto AttrList = AttributeSet::get(
|
||||
M.getContext(), AttributeSet::FunctionIndex, Attribute::NoUnwind);
|
||||
BridgeRetainN = M.getOrInsertFunction("swift_bridgeObjectRetain_n",
|
||||
AttrList, BridgeObjectPtrTy,
|
||||
BridgeObjectPtrTy,
|
||||
Int32Ty, nullptr);
|
||||
return BridgeRetainN.get();
|
||||
}
|
||||
|
||||
/// Return a callable function for swift_bridgeRelease_n.
|
||||
Constant *getBridgeReleaseN() {
|
||||
if (BridgeReleaseN)
|
||||
return BridgeReleaseN.get();
|
||||
auto *ObjectPtrTy = getObjectPtrTy();
|
||||
auto &M = getModule();
|
||||
|
||||
auto *Int32Ty = Type::getInt32Ty(M.getContext());
|
||||
auto AttrList = AttributeSet::get(
|
||||
M.getContext(), AttributeSet::FunctionIndex, Attribute::NoUnwind);
|
||||
BridgeReleaseN = M.getOrInsertFunction("swift_bridgeObjectRelease_n",
|
||||
AttrList,
|
||||
Type::getVoidTy(M.getContext()),
|
||||
BridgeObjectPtrTy, Int32Ty,
|
||||
nullptr);
|
||||
return BridgeReleaseN.get();
|
||||
}
|
||||
|
||||
Type *getObjectPtrTy() {
|
||||
if (ObjectPtrTy)
|
||||
@@ -315,15 +263,6 @@ private:
|
||||
return ObjectPtrTy.get();
|
||||
}
|
||||
|
||||
Type *getBridgeObjectPtrTy() {
|
||||
if (BridgeObjectPtrTy)
|
||||
return BridgeObjectPtrTy.get();
|
||||
auto &M = getModule();
|
||||
BridgeObjectPtrTy = M.getTypeByName("swift.bridge")->getPointerTo();
|
||||
assert(BridgeObjectPtrTy && "Could not find the swift bridge object type by name");
|
||||
return BridgeObjectPtrTy.get();
|
||||
}
|
||||
|
||||
Constant *getIntConstant(uint32_t constant) {
|
||||
auto &M = getModule();
|
||||
auto *Int32Ty = Type::getInt32Ty(M.getContext());
|
||||
|
||||
@@ -32,9 +32,6 @@ STATISTIC(NumRetainReleasesEliminatedByMergingIntoRetainReleaseN,
|
||||
STATISTIC(NumUnknownRetainReleasesEliminatedByMergingIntoRetainReleaseN,
|
||||
"Number of retain/release eliminated by merging into "
|
||||
"unknownRetain_n/unknownRelease_n");
|
||||
STATISTIC(NumBridgeRetainReleasesEliminatedByMergingIntoRetainReleaseN,
|
||||
"Number of bridge retain/release eliminated by merging into "
|
||||
"bridgeRetain_n/bridgeRelease_n");
|
||||
|
||||
/// Pimpl implementation of SwiftARCContractPass.
|
||||
namespace {
|
||||
@@ -44,8 +41,6 @@ struct LocalState {
|
||||
TinyPtrVector<CallInst *> ReleaseList;
|
||||
TinyPtrVector<CallInst *> UnknownRetainList;
|
||||
TinyPtrVector<CallInst *> UnknownReleaseList;
|
||||
TinyPtrVector<CallInst *> BridgeRetainList;
|
||||
TinyPtrVector<CallInst *> BridgeReleaseList;
|
||||
};
|
||||
|
||||
/// This implements the very late (just before code generation) lowering
|
||||
@@ -170,45 +165,6 @@ performRRNOptimization(DenseMap<Value *, LocalState> &PtrToLocalStateMap) {
|
||||
}
|
||||
UnknownReleaseList.clear();
|
||||
|
||||
auto &BridgeRetainList = P.second.BridgeRetainList;
|
||||
if (BridgeRetainList.size() > 1) {
|
||||
// Create the releaseN call right by the last release.
|
||||
auto *OldCI = BridgeRetainList[BridgeRetainList.size() - 1];
|
||||
B.setInsertPoint(OldCI);
|
||||
O = OldCI->getArgOperand(0);
|
||||
// Bridge retain may modify the input reference before forwarding it.
|
||||
auto *I = B.createBridgeRetainN(RC->getSwiftRCIdentityRoot(O),
|
||||
BridgeRetainList.size());
|
||||
|
||||
// Remove all old retain instructions.
|
||||
for (auto *Inst : BridgeRetainList) {
|
||||
Inst->replaceAllUsesWith(I);
|
||||
Inst->eraseFromParent();
|
||||
NumBridgeRetainReleasesEliminatedByMergingIntoRetainReleaseN++;
|
||||
}
|
||||
|
||||
NumBridgeRetainReleasesEliminatedByMergingIntoRetainReleaseN--;
|
||||
}
|
||||
BridgeRetainList.clear();
|
||||
|
||||
auto &BridgeReleaseList = P.second.BridgeReleaseList;
|
||||
if (BridgeReleaseList.size() > 1) {
|
||||
// Create the releaseN call right by the last release.
|
||||
auto *OldCI = BridgeReleaseList[BridgeReleaseList.size() - 1];
|
||||
B.setInsertPoint(OldCI);
|
||||
O = OldCI->getArgOperand(0);
|
||||
B.createBridgeReleaseN(RC->getSwiftRCIdentityRoot(O),
|
||||
BridgeReleaseList.size());
|
||||
|
||||
// Remove all old release instructions.
|
||||
for (auto *Inst : BridgeReleaseList) {
|
||||
Inst->eraseFromParent();
|
||||
NumBridgeRetainReleasesEliminatedByMergingIntoRetainReleaseN++;
|
||||
}
|
||||
|
||||
NumBridgeRetainReleasesEliminatedByMergingIntoRetainReleaseN--;
|
||||
}
|
||||
BridgeReleaseList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,25 +228,11 @@ bool SwiftARCContractImpl::run() {
|
||||
LocalEntry.UnknownReleaseList.push_back(CI);
|
||||
continue;
|
||||
}
|
||||
case RT_BridgeRetain: {
|
||||
auto *CI = cast<CallInst>(&Inst);
|
||||
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
|
||||
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
|
||||
LocalEntry.BridgeRetainList.push_back(CI);
|
||||
continue;
|
||||
}
|
||||
case RT_BridgeRelease: {
|
||||
auto *CI = cast<CallInst>(&Inst);
|
||||
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
|
||||
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
|
||||
LocalEntry.BridgeReleaseList.push_back(CI);
|
||||
continue;
|
||||
}
|
||||
case RT_Unknown:
|
||||
case RT_AllocObject:
|
||||
case RT_NoMemoryAccessed:
|
||||
case RT_BridgeRelease:
|
||||
case RT_BridgeRetain:
|
||||
case RT_RetainUnowned:
|
||||
case RT_CheckUnowned:
|
||||
case RT_ObjCRelease:
|
||||
|
||||
@@ -5,11 +5,8 @@ target triple = "x86_64-apple-macosx10.9"
|
||||
|
||||
%swift.refcounted = type { %swift.heapmetadata*, i64 }
|
||||
%swift.heapmetadata = type { i64 (%swift.refcounted*)*, i64 (%swift.refcounted*)* }
|
||||
%swift.bridge = type opaque
|
||||
|
||||
declare %swift.refcounted* @swift_allocObject(%swift.heapmetadata* , i64, i64) nounwind
|
||||
declare %swift.bridge* @swift_bridgeObjectRetain(%swift.bridge*)
|
||||
declare void @swift_bridgeObjectRelease(%swift.bridge* )
|
||||
declare void @swift_release(%swift.refcounted* nocapture)
|
||||
declare void @swift_retain(%swift.refcounted* ) nounwind
|
||||
declare void @swift_unknownRelease(%swift.refcounted* nocapture)
|
||||
@@ -17,8 +14,6 @@ declare void @swift_unknownRetain(%swift.refcounted* ) nounwind
|
||||
declare void @swift_fixLifetime(%swift.refcounted*)
|
||||
declare void @noread_user(%swift.refcounted*) readnone
|
||||
declare void @user(%swift.refcounted*)
|
||||
declare void @noread_user_bridged(%swift.bridge*) readnone
|
||||
declare void @user_bridged(%swift.bridge*)
|
||||
|
||||
; CHECK-LABEL: define void @fixlifetime_removal(i8*) {
|
||||
; CHECK-NOT: call void swift_fixLifetime
|
||||
@@ -501,77 +496,6 @@ bb3:
|
||||
ret %swift.refcounted* %A
|
||||
}
|
||||
|
||||
|
||||
; CHECK-LABEL: define %swift.bridge* @swift_contractBridgeRetainWithBridge(%swift.bridge* %A) {
|
||||
; CHECK: bb1:
|
||||
; CHECK-NEXT: [[RET0:%.+]] = tail call %swift.bridge* @swift_bridgeObjectRetain_n(%swift.bridge* %A, i32 2)
|
||||
; CHECK-NEXT: tail call void @swift_bridgeObjectRelease(%swift.bridge* [[RET0:%.+]])
|
||||
; CHECK-NEXT: tail call void @swift_bridgeObjectRelease(%swift.bridge* %A)
|
||||
; CHECK-NEXT: ret %swift.bridge* %A
|
||||
define %swift.bridge* @swift_contractBridgeRetainWithBridge(%swift.bridge* %A) {
|
||||
bb1:
|
||||
%0 = tail call %swift.bridge* @swift_bridgeObjectRetain(%swift.bridge* %A)
|
||||
%1 = tail call %swift.bridge* @swift_bridgeObjectRetain(%swift.bridge* %A)
|
||||
tail call void @swift_bridgeObjectRelease(%swift.bridge* %1)
|
||||
tail call void @swift_bridgeObjectRelease(%swift.bridge* %A)
|
||||
ret %swift.bridge* %A
|
||||
}
|
||||
|
||||
; CHECK-LABEL: define %swift.bridge* @swift_contractBridgeRetainReleaseNInterleavedWithBridge(%swift.bridge* %A) {
|
||||
; CHECK: bb1:
|
||||
; CHECK-NEXT: [[RET0:%.+]] = tail call %swift.bridge* @swift_bridgeObjectRetain(%swift.bridge* %A)
|
||||
; CHECK-NEXT: call void @user_bridged(%swift.bridge* %A)
|
||||
; CHECK-NEXT: call void @noread_user_bridged(%swift.bridge* %A)
|
||||
; CHECK-NEXT: tail call void @swift_bridgeObjectRelease_n(%swift.bridge* %A, i32 2)
|
||||
; CHECK-NEXT: call void @user_bridged(%swift.bridge* %A)
|
||||
; CHECK-NEXT: [[RET1:%.+]] = tail call %swift.bridge* @swift_bridgeObjectRetain_n(%swift.bridge* %A, i32 2)
|
||||
; CHECK-NEXT: tail call void @swift_bridgeObjectRelease(%swift.bridge* %A)
|
||||
; CHECK-NEXT: call void @user_bridged(%swift.bridge* %A)
|
||||
; CHECK-NEXT: call void @noread_user_bridged(%swift.bridge* %A)
|
||||
; CHECK-NEXT: tail call void @swift_bridgeObjectRelease_n(%swift.bridge* %A, i32 2)
|
||||
; CHECK-NEXT: call void @user_bridged(%swift.bridge* %A)
|
||||
; CHECK-NEXT: br label %bb3
|
||||
; CHECK: bb2:
|
||||
; CHECK-NEXT: call void @user_bridged(%swift.bridge* %A)
|
||||
; CHECK-NEXT: call void @swift_bridgeObjectRelease(%swift.bridge* %A)
|
||||
; CHECK-NEXT: call void @user_bridged(%swift.bridge* %A)
|
||||
; CHECK-NEXT: br label %bb3
|
||||
|
||||
; CHECK: bb3:
|
||||
; CHECK-NEXT: tail call void @swift_bridgeObjectRelease(%swift.bridge* %A)
|
||||
; CHECK-NEXT: ret %swift.bridge* %A
|
||||
define %swift.bridge* @swift_contractBridgeRetainReleaseNInterleavedWithBridge(%swift.bridge* %A) {
|
||||
entry:
|
||||
br i1 undef, label %bb1, label %bb2
|
||||
|
||||
bb1:
|
||||
tail call %swift.bridge* @swift_bridgeObjectRetain(%swift.bridge* %A)
|
||||
call void @user_bridged(%swift.bridge* %A)
|
||||
tail call void @swift_bridgeObjectRelease(%swift.bridge* %A)
|
||||
call void @noread_user_bridged(%swift.bridge* %A)
|
||||
tail call void @swift_bridgeObjectRelease(%swift.bridge* %A)
|
||||
call void @user_bridged(%swift.bridge* %A)
|
||||
tail call %swift.bridge* @swift_bridgeObjectRetain(%swift.bridge* %A)
|
||||
tail call %swift.bridge* @swift_bridgeObjectRetain(%swift.bridge* %A)
|
||||
tail call void @swift_bridgeObjectRelease(%swift.bridge* %A)
|
||||
call void @user_bridged(%swift.bridge* %A)
|
||||
tail call void @swift_bridgeObjectRelease(%swift.bridge* %A)
|
||||
call void @noread_user_bridged(%swift.bridge* %A)
|
||||
tail call void @swift_bridgeObjectRelease(%swift.bridge* %A)
|
||||
call void @user_bridged(%swift.bridge* %A)
|
||||
br label %bb3
|
||||
|
||||
bb2:
|
||||
call void @user_bridged(%swift.bridge* %A)
|
||||
tail call void @swift_bridgeObjectRelease(%swift.bridge* %A)
|
||||
call void @user_bridged(%swift.bridge* %A)
|
||||
br label %bb3
|
||||
|
||||
bb3:
|
||||
tail call void @swift_bridgeObjectRelease(%swift.bridge* %A)
|
||||
ret %swift.bridge* %A
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!1}
|
||||
!llvm.module.flags = !{!4}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user