summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp')
-rw-r--r--contrib/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/contrib/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/contrib/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
index a6907b5..136d54a 100644
--- a/contrib/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
+++ b/contrib/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
@@ -53,6 +53,11 @@ using namespace llvm::objcarc;
/// \brief This is similar to GetRCIdentityRoot but it stops as soon
/// as it finds a value with multiple uses.
static const Value *FindSingleUseIdentifiedObject(const Value *Arg) {
+ // ConstantData (like ConstantPointerNull and UndefValue) is used across
+ // modules. It's never a single-use value.
+ if (isa<ConstantData>(Arg))
+ return nullptr;
+
if (Arg->hasOneUse()) {
if (const BitCastInst *BC = dyn_cast<BitCastInst>(Arg))
return FindSingleUseIdentifiedObject(BC->getOperand(0));
@@ -644,6 +649,12 @@ void ObjCARCOpt::OptimizeAutoreleaseRVCall(Function &F,
ARCInstKind &Class) {
// Check for a return of the pointer value.
const Value *Ptr = GetArgRCIdentityRoot(AutoreleaseRV);
+
+ // If the argument is ConstantPointerNull or UndefValue, its other users
+ // aren't actually interesting to look at.
+ if (isa<ConstantData>(Ptr))
+ return;
+
SmallVector<const Value *, 2> Users;
Users.push_back(Ptr);
do {
@@ -2075,12 +2086,11 @@ void ObjCARCOpt::OptimizeReturns(Function &F) {
SmallPtrSet<const BasicBlock *, 4> Visited;
for (BasicBlock &BB: F) {
ReturnInst *Ret = dyn_cast<ReturnInst>(&BB.back());
-
- DEBUG(dbgs() << "Visiting: " << *Ret << "\n");
-
if (!Ret)
continue;
+ DEBUG(dbgs() << "Visiting: " << *Ret << "\n");
+
const Value *Arg = GetRCIdentityRoot(Ret->getOperand(0));
// Look for an ``autorelease'' instruction that is a predecessor of Ret and
OpenPOWER on IntegriCloud