[llvm] r182669 - [objc-arc] Make sure that multiple owners is propogated correctly through the pass via the usage of a global data structure.
Michael Gottesman
mgottesman at apple.com
Fri May 24 13:44:02 PDT 2013
Author: mgottesman
Date: Fri May 24 15:44:02 2013
New Revision: 182669
URL: http://llvm.org/viewvc/llvm-project?rev=182669&view=rev
Log:
[objc-arc] Make sure that multiple owners is propogated correctly through the pass via the usage of a global data structure.
rdar://13750319
Modified:
llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
llvm/trunk/test/Transforms/ObjCARC/allocas.ll
Modified: llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp?rev=182669&r1=182668&r2=182669&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp Fri May 24 15:44:02 2013
@@ -30,6 +30,7 @@
#include "ObjCARCAliasAnalysis.h"
#include "ProvenanceAnalysis.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
@@ -454,18 +455,8 @@ namespace {
/// sequence.
SmallPtrSet<Instruction *, 2> ReverseInsertPts;
- /// Does this pointer have multiple owners?
- ///
- /// In the presence of multiple owners with the same provenance caused by
- /// allocas, we can not assume that the frontend will emit balanced code
- /// since it could put the release on the pointer loaded from the
- /// alloca. This confuses the optimizer so we must be more conservative in
- /// that case.
- bool MultipleOwners;
-
RRInfo() :
- KnownSafe(false), IsTailCallRelease(false), ReleaseMetadata(0),
- MultipleOwners(false) {}
+ KnownSafe(false), IsTailCallRelease(false), ReleaseMetadata(0) {}
void clear();
@@ -478,7 +469,6 @@ namespace {
void RRInfo::clear() {
KnownSafe = false;
IsTailCallRelease = false;
- MultipleOwners = false;
ReleaseMetadata = 0;
Calls.clear();
ReverseInsertPts.clear();
@@ -569,7 +559,6 @@ PtrState::Merge(const PtrState &Other, b
RRI.IsTailCallRelease = RRI.IsTailCallRelease &&
Other.RRI.IsTailCallRelease;
RRI.Calls.insert(Other.RRI.Calls.begin(), Other.RRI.Calls.end());
- RRI.MultipleOwners |= Other.RRI.MultipleOwners;
// Merge the insert point sets. If there are any differences,
// that makes this a partial merge.
@@ -1058,6 +1047,9 @@ namespace {
bool Changed;
ProvenanceAnalysis PA;
+ // This is used to track if a pointer is stored into an alloca.
+ DenseSet<const Value *> MultiOwnersSet;
+
/// A flag indicating whether this optimization pass should run.
bool Run;
@@ -1943,7 +1935,7 @@ ObjCARCOpt::VisitInstructionBottomUp(Ins
BBState::ptr_iterator I = MyStates.findPtrBottomUpState(
StripPointerCastsAndObjCCalls(SI->getValueOperand()));
if (I != MyStates.bottom_up_ptr_end())
- I->second.RRI.MultipleOwners = true;
+ MultiOwnersSet.insert(I->first);
}
}
break;
@@ -2515,7 +2507,8 @@ ObjCARCOpt::ConnectTDBUTraversals(DenseM
assert(It != Retains.end());
const RRInfo &NewRetainRRI = It->second;
KnownSafeTD &= NewRetainRRI.KnownSafe;
- MultipleOwners |= NewRetainRRI.MultipleOwners;
+ MultipleOwners =
+ MultipleOwners || MultiOwnersSet.count(GetObjCArg(NewRetain));
for (SmallPtrSet<Instruction *, 2>::const_iterator
LI = NewRetainRRI.Calls.begin(),
LE = NewRetainRRI.Calls.end(); LI != LE; ++LI) {
@@ -2903,8 +2896,14 @@ bool ObjCARCOpt::OptimizeSequences(Funct
bool NestingDetected = Visit(F, BBStates, Retains, Releases);
// Transform.
- return PerformCodePlacement(BBStates, Retains, Releases, F.getParent()) &&
- NestingDetected;
+ bool AnyPairsCompletelyEliminated = PerformCodePlacement(BBStates, Retains,
+ Releases,
+ F.getParent());
+
+ // Cleanup.
+ MultiOwnersSet.clear();
+
+ return AnyPairsCompletelyEliminated && NestingDetected;
}
/// Check if there is a dependent call earlier that does not have anything in
Modified: llvm/trunk/test/Transforms/ObjCARC/allocas.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ObjCARC/allocas.ll?rev=182669&r1=182668&r2=182669&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/ObjCARC/allocas.ll (original)
+++ llvm/trunk/test/Transforms/ObjCARC/allocas.ll Fri May 24 15:44:02 2013
@@ -197,6 +197,103 @@ entry:
ret void
}
+; Make sure that if a store is in a different basic block we handle known safe
+; conservatively.
+
+
+; CHECK: define void @test2a(i8* %x)
+; CHECK: @objc_retain(i8* %x)
+; CHECK: @objc_retain(i8* %x)
+; CHECK: @objc_release(i8* %y)
+; CHECK: @objc_release(i8* %x)
+; CHECK: ret void
+; CHECK: }
+define void @test2a(i8* %x) {
+entry:
+ %A = alloca i8*
+ store i8* %x, i8** %A, align 8
+ %y = load i8** %A
+ br label %bb1
+
+bb1:
+ br label %bb2
+
+bb2:
+ br label %bb3
+
+bb3:
+ tail call i8* @objc_retain(i8* %x)
+ tail call i8* @objc_retain(i8* %x)
+ call void @use_alloca(i8** %A)
+ call void @objc_release(i8* %y), !clang.imprecise_release !0
+ call void @use_pointer(i8* %x)
+ call void @objc_release(i8* %x), !clang.imprecise_release !0
+ ret void
+}
+
+; CHECK: define void @test2b(i8* %x)
+; CHECK: @objc_retain(i8* %x)
+; CHECK: @objc_retain(i8* %x)
+; CHECK: @objc_release(i8* %y)
+; CHECK: @objc_release(i8* %x)
+; CHECK: ret void
+; CHECK: }
+define void @test2b(i8* %x) {
+entry:
+ %A = alloca i8*
+ %gep1 = getelementptr i8** %A, i32 0
+ store i8* %x, i8** %gep1, align 8
+ %gep2 = getelementptr i8** %A, i32 0
+ %y = load i8** %gep2
+ br label %bb1
+
+bb1:
+ br label %bb2
+
+bb2:
+ br label %bb3
+
+bb3:
+ tail call i8* @objc_retain(i8* %x)
+ tail call i8* @objc_retain(i8* %x)
+ call void @use_alloca(i8** %A)
+ call void @objc_release(i8* %y), !clang.imprecise_release !0
+ call void @use_pointer(i8* %x)
+ call void @objc_release(i8* %x), !clang.imprecise_release !0
+ ret void
+}
+
+; CHECK: define void @test2c(i8* %x)
+; CHECK: @objc_retain(i8* %x)
+; CHECK: @objc_retain(i8* %x)
+; CHECK: @objc_release(i8* %y)
+; CHECK: @objc_release(i8* %x)
+; CHECK: ret void
+; CHECK: }
+define void @test2c(i8* %x) {
+entry:
+ %A = alloca i8*, i32 3
+ %gep1 = getelementptr i8** %A, i32 2
+ store i8* %x, i8** %gep1, align 8
+ %gep2 = getelementptr i8** %A, i32 2
+ %y = load i8** %gep2
+ tail call i8* @objc_retain(i8* %x)
+ br label %bb1
+
+bb1:
+ br label %bb2
+
+bb2:
+ br label %bb3
+
+bb3:
+ tail call i8* @objc_retain(i8* %x)
+ call void @use_alloca(i8** %A)
+ call void @objc_release(i8* %y), !clang.imprecise_release !0
+ call void @use_pointer(i8* %x)
+ call void @objc_release(i8* %x), !clang.imprecise_release !0
+ ret void
+}
!0 = metadata !{}
More information about the llvm-commits
mailing list