diff options
author | Dan Gohman <gohman@apple.com> | 2012-01-19 19:14:36 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2012-01-19 19:14:36 +0000 |
commit | 0cdece438972f4c670973d99d2c7743ab822de1a (patch) | |
tree | 5aa81f67ea92c25ce0f7794326c7c3a8c8c8a060 /lib/Transforms | |
parent | a951f77ca31b43551bd41765504519d6d76e6cbf (diff) | |
download | external_llvm-0cdece438972f4c670973d99d2c7743ab822de1a.zip external_llvm-0cdece438972f4c670973d99d2c7743ab822de1a.tar.gz external_llvm-0cdece438972f4c670973d99d2c7743ab822de1a.tar.bz2 |
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
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/ObjCARC.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/ObjCARC.cpp b/lib/Transforms/Scalar/ObjCARC.cpp index 410f6bc..08bb67e 100644 --- a/lib/Transforms/Scalar/ObjCARC.cpp +++ b/lib/Transforms/Scalar/ObjCARC.cpp @@ -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; } |