forked from OSchip/llvm-project
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:
parent
03eefb3a38
commit
774d2c014e
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue