Changed DoesObjCBlockEscape => DoesRetainableObjPtrEscape so I can use it to perform escape analysis of other retainable object pointers in other locations.

llvm-svn: 173829
This commit is contained in:
Michael Gottesman 2013-01-29 21:00:52 +00:00
parent 03eefb3a38
commit 774d2c014e
1 changed files with 17 additions and 14 deletions

View File

@ -171,33 +171,36 @@ static const Value *FindSingleUseIdentifiedObject(const Value *Arg) {
return 0; return 0;
} }
/// \brief Test whether the given pointer, which is an Objective C block /// \brief Test whether the given retainable object pointer escapes.
/// pointer, does not "escape".
/// ///
/// This differs from regular escape analysis in that a use as an /// This differs from regular escape analysis in that a use as an
/// argument to a call is not considered an escape. /// argument to a call is not considered an escape.
/// ///
static bool DoesObjCBlockEscape(const Value *BlockPtr) { static bool DoesRetainableObjPtrEscape(const User *Ptr) {
DEBUG(dbgs() << "DoesObjCBlockEscape: Target: " << *BlockPtr << "\n"); DEBUG(dbgs() << "DoesRetainableObjPtrEscape: Target: " << *Ptr << "\n");
// Walk the def-use chains. // Walk the def-use chains.
SmallVector<const Value *, 4> Worklist; SmallVector<const Value *, 4> Worklist;
Worklist.push_back(BlockPtr); Worklist.push_back(Ptr);
// If Ptr has any operands add them as well.
for (User::const_op_iterator I = Ptr->op_begin(), E = Ptr->op_end(); I != E; ++I) {
Worklist.push_back(*I);
}
// Ensure we do not visit any value twice. // Ensure we do not visit any value twice.
SmallPtrSet<const Value *, 4> VisitedSet; SmallPtrSet<const Value *, 8> VisitedSet;
do { do {
const Value *V = Worklist.pop_back_val(); const Value *V = Worklist.pop_back_val();
DEBUG(dbgs() << "DoesObjCBlockEscape: Visiting: " << *V << "\n"); DEBUG(dbgs() << "DoesRetainableObjPtrEscape: Visiting: " << *V << "\n");
for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end(); for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end();
UI != UE; ++UI) { UI != UE; ++UI) {
const User *UUser = *UI; const User *UUser = *UI;
DEBUG(dbgs() << "DoesObjCBlockEscape: User: " << *UUser << "\n"); DEBUG(dbgs() << "DoesRetainableObjPtrEscape: User: " << *UUser << "\n");
// Special - Use by a call (callee or argument) is not considered // Special - Use by a call (callee or argument) is not considered
// to be an escape. // to be an escape.
@ -207,7 +210,7 @@ static bool DoesObjCBlockEscape(const Value *BlockPtr) {
case IC_StoreStrong: case IC_StoreStrong:
case IC_Autorelease: case IC_Autorelease:
case IC_AutoreleaseRV: { case IC_AutoreleaseRV: {
DEBUG(dbgs() << "DoesObjCBlockEscape: User copies pointer arguments. " DEBUG(dbgs() << "DoesRetainableObjPtrEscape: User copies pointer arguments. "
"Block Escapes!\n"); "Block Escapes!\n");
// These special functions make copies of their pointer arguments. // These special functions make copies of their pointer arguments.
return true; return true;
@ -220,11 +223,11 @@ static bool DoesObjCBlockEscape(const Value *BlockPtr) {
isa<PHINode>(UUser) || isa<SelectInst>(UUser)) { isa<PHINode>(UUser) || isa<SelectInst>(UUser)) {
if (!VisitedSet.insert(UUser)) { if (!VisitedSet.insert(UUser)) {
DEBUG(dbgs() << "DoesObjCBlockEscape: User copies value. Escapes " DEBUG(dbgs() << "DoesRetainableObjPtrEscape: User copies value. Escapes "
"if result escapes. Adding to list.\n"); "if result escapes. Adding to list.\n");
Worklist.push_back(UUser); Worklist.push_back(UUser);
} else { } else {
DEBUG(dbgs() << "DoesObjCBlockEscape: Already visited node.\n"); DEBUG(dbgs() << "DoesRetainableObjPtrEscape: Already visited node.\n");
} }
continue; continue;
} }
@ -241,13 +244,13 @@ static bool DoesObjCBlockEscape(const Value *BlockPtr) {
continue; continue;
} }
// Otherwise, conservatively assume an escape. // Otherwise, conservatively assume an escape.
DEBUG(dbgs() << "DoesObjCBlockEscape: Assuming block escapes.\n"); DEBUG(dbgs() << "DoesRetainableObjPtrEscape: Assuming block escapes.\n");
return true; return true;
} }
} while (!Worklist.empty()); } while (!Worklist.empty());
// No escapes found. // No escapes found.
DEBUG(dbgs() << "DoesObjCBlockEscape: Block does not escape.\n"); DEBUG(dbgs() << "DoesRetainableObjPtrEscape: Block does not escape.\n");
return false; return false;
} }
@ -822,7 +825,7 @@ bool ObjCARCOpt::IsRetainBlockOptimizable(const Instruction *Inst) {
// If the pointer "escapes" (not including being used in a call), // If the pointer "escapes" (not including being used in a call),
// the copy may be needed. // the copy may be needed.
if (DoesObjCBlockEscape(Inst)) if (DoesRetainableObjPtrEscape(Inst))
return false; return false;
// Otherwise, it's not needed. // Otherwise, it's not needed.