aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2011-08-22 17:29:11 +0000
committerDan Gohman <gohman@apple.com>2011-08-22 17:29:11 +0000
commit1b31ea8f935d4b643abf100c4943180c9ed8ba1a (patch)
tree8bb82696cb508e2560a25e690512fc278350cedd
parent986b865c03b04e9d65bd100c7254c58547fc89e7 (diff)
Constant pointers to objects don't need reference counting.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138242 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/ObjCARC.cpp13
-rw-r--r--test/Transforms/ObjCARC/basic.ll33
2 files changed, 46 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/ObjCARC.cpp b/lib/Transforms/Scalar/ObjCARC.cpp
index fea03b5f5b..9654b1ecd3 100644
--- a/lib/Transforms/Scalar/ObjCARC.cpp
+++ b/lib/Transforms/Scalar/ObjCARC.cpp
@@ -515,6 +515,10 @@ static bool IsObjCIdentifiedObject(const Value *V) {
const Value *Pointer =
StripPointerCastsAndObjCCalls(LI->getPointerOperand());
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Pointer)) {
+ // A constant pointer can't be pointing to an object on the heap. It may
+ // be reference-counted, but it won't be deleted.
+ if (GV->isConstant())
+ return true;
StringRef Name = GV->getName();
// These special variables are known to hold values which are not
// reference-counted pointers.
@@ -2744,6 +2748,15 @@ ObjCARCOpt::PerformCodePlacement(DenseMap<const BasicBlock *, BBState>
// regardless of what possible decrements or uses lie between them.
bool KnownSafe = isa<Constant>(Arg) || isa<AllocaInst>(Arg);
+ // A constant pointer can't be pointing to an object on the heap. It may
+ // be reference-counted, but it won't be deleted.
+ if (const LoadInst *LI = dyn_cast<LoadInst>(Arg))
+ if (const GlobalVariable *GV =
+ dyn_cast<GlobalVariable>(
+ StripPointerCastsAndObjCCalls(LI->getPointerOperand())))
+ if (GV->isConstant())
+ KnownSafe = true;
+
// If a pair happens in a region where it is known that the reference count
// is already incremented, we can similarly ignore possible decrements.
bool KnownSafeTD = true, KnownSafeBU = true;
diff --git a/test/Transforms/ObjCARC/basic.ll b/test/Transforms/ObjCARC/basic.ll
index def703910c..72f05ffaac 100644
--- a/test/Transforms/ObjCARC/basic.ll
+++ b/test/Transforms/ObjCARC/basic.ll
@@ -1638,6 +1638,39 @@ entry:
ret void
}
+; Constant pointers to objects don't need reference counting.
+
+@constptr = external constant i8*
+@something = external global i8*
+
+; CHECK: define void @test60(
+; CHECK-NOT: @objc_
+; CHECK: }
+define void @test60() {
+ %t = load i8** @constptr
+ %s = load i8** @something
+ call i8* @objc_retain(i8* %s)
+ call void @callee()
+ call void @use_pointer(i8* %t)
+ call void @objc_release(i8* %s)
+ ret void
+}
+
+; Constant pointers to objects don't need to be considered related to other
+; pointers.
+
+; CHECK: define void @test61(
+; CHECK-NOT: @objc_
+; CHECK: }
+define void @test61() {
+ %t = load i8** @constptr
+ call i8* @objc_retain(i8* %t)
+ call void @callee()
+ call void @use_pointer(i8* %t)
+ call void @objc_release(i8* %t)
+ ret void
+}
+
declare void @bar(i32 ()*)
; A few real-world testcases.