mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-25 04:39:44 +00:00
Set the "tail" flag on pattern-matched objc_storeStrong calls.
rdar://10531041. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148490 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a951f77ca3
commit
0cdece4389
@ -3600,6 +3600,11 @@ namespace {
|
||||
/// RetainRV calls to make the optimization work on targets which need it.
|
||||
const MDString *RetainRVMarker;
|
||||
|
||||
/// StoreStrongCalls - The set of inserted objc_storeStrong calls. If
|
||||
/// at the end of walking the function we have found no alloca
|
||||
/// instructions, these calls can be marked "tail".
|
||||
DenseSet<CallInst *> StoreStrongCalls;
|
||||
|
||||
Constant *getStoreStrongCallee(Module *M);
|
||||
Constant *getRetainAutoreleaseCallee(Module *M);
|
||||
Constant *getRetainAutoreleaseRVCallee(Module *M);
|
||||
@ -3803,6 +3808,11 @@ void ObjCARCContract::ContractRelease(Instruction *Release,
|
||||
StoreStrong->setDoesNotThrow();
|
||||
StoreStrong->setDebugLoc(Store->getDebugLoc());
|
||||
|
||||
// We can't set the tail flag yet, because we haven't yet determined
|
||||
// whether there are any escaping allocas. Remember this call, so that
|
||||
// we can set the tail flag once we know it's safe.
|
||||
StoreStrongCalls.insert(StoreStrong);
|
||||
|
||||
if (&*Iter == Store) ++Iter;
|
||||
Store->eraseFromParent();
|
||||
Release->eraseFromParent();
|
||||
@ -3849,6 +3859,13 @@ bool ObjCARCContract::runOnFunction(Function &F) {
|
||||
|
||||
PA.setAA(&getAnalysis<AliasAnalysis>());
|
||||
|
||||
// Track whether it's ok to mark objc_storeStrong calls with the "tail"
|
||||
// keyword. Be conservative if the function has variadic arguments.
|
||||
// It seems that functions which "return twice" are also unsafe for the
|
||||
// "tail" argument, because they are setjmp, which could need to
|
||||
// return to an earlier stack state.
|
||||
bool TailOkForStoreStrongs = !F.isVarArg() && !F.callsFunctionThatReturnsTwice();
|
||||
|
||||
// For ObjC library calls which return their argument, replace uses of the
|
||||
// argument with uses of the call return value, if it dominates the use. This
|
||||
// reduces register pressure.
|
||||
@ -3905,6 +3922,13 @@ bool ObjCARCContract::runOnFunction(Function &F) {
|
||||
case IC_Release:
|
||||
ContractRelease(Inst, I);
|
||||
continue;
|
||||
case IC_User:
|
||||
// Be conservative if the function has any alloca instructions.
|
||||
// Technically we only care about escaping alloca instructions,
|
||||
// but this is sufficient to handle some interesting cases.
|
||||
if (isa<AllocaInst>(Inst))
|
||||
TailOkForStoreStrongs = false;
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@ -3969,5 +3993,13 @@ bool ObjCARCContract::runOnFunction(Function &F) {
|
||||
}
|
||||
}
|
||||
|
||||
// If this function has no escaping allocas or suspicious vararg usage,
|
||||
// objc_storeStrong calls can be marked with the "tail" keyword.
|
||||
if (TailOkForStoreStrongs)
|
||||
for (DenseSet<CallInst *>::iterator I = StoreStrongCalls.begin(),
|
||||
E = StoreStrongCalls.end(); I != E; ++I)
|
||||
(*I)->setTailCall();
|
||||
StoreStrongCalls.clear();
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: opt -objc-arc-contract -S < %s | FileCheck %s
|
||||
|
||||
; CHECK: call void @objc_storeStrong(i8**
|
||||
; CHECK: tail call void @objc_storeStrong(i8**
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||
target triple = "x86_64-apple-darwin11.0.0"
|
||||
|
@ -9,7 +9,7 @@ declare void @objc_release(i8*)
|
||||
|
||||
; CHECK: define void @test0(
|
||||
; CHECK: entry:
|
||||
; CHECK-NEXT: call void @objc_storeStrong(i8** @x, i8* %p) nounwind
|
||||
; CHECK-NEXT: tail call void @objc_storeStrong(i8** @x, i8* %p) nounwind
|
||||
; CHECK-NEXT: ret void
|
||||
define void @test0(i8* %p) {
|
||||
entry:
|
||||
|
Loading…
Reference in New Issue
Block a user