llvm.org GIT mirror llvm / a67a20c
Remove an optimization where we were changing an objc_autorelease into an objc_autoreleaseReturnValue. The semantics of ARC implies that a pointer passed into an objc_autorelease must live until some point (potentially down the stack) where an autorelease pool is popped. On the other hand, an objc_autoreleaseReturnValue just signifies that the object must live until the end of the given function at least. Thus objc_autorelease is stronger than objc_autoreleaseReturnValue in terms of the semantics of ARC* implying that performing the given strength reduction without any knowledge of how this relates to the autorelease pool pop that is further up the stack violates the semantics of ARC. *Even though objc_autoreleaseReturnValue if you know that no RV optimization will occur is more computationally expensive. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178612 91177308-0d34-0410-b5e6-96231b3b80d8 Michael Gottesman 7 years ago
4 changed file(s) with 9 addition(s) and 32 deletion(s). Raw diff Collapse all Expand all
14391439 break;
14401440 }
14411441
1442 // objc_autorelease(x), objc_autoreleaseRV -> objc_release(x) if x is
1443 // otherwise unused.
1442 // objc_autorelease(x) -> objc_release(x) if x is otherwise unused.
14441443 if (IsAutorelease(Class) && Inst->use_empty()) {
14451444 CallInst *Call = cast(Inst);
14461445 const Value *Arg = Call->getArgOperand(0);
28602859 DependingInstructions.clear();
28612860 Visited.clear();
28622861
2863 // Convert the autorelease to an autoreleaseRV, since it's
2864 // returning the value.
2865 if (AutoreleaseClass == IC_Autorelease) {
2866 DEBUG(dbgs() << "ObjCARCOpt::OptimizeReturns: Converting autorelease "
2867 "=> autoreleaseRV since it's returning a value.\n"
2868 " In: " << *Autorelease
2869 << "\n");
2870 Autorelease->setCalledFunction(getAutoreleaseRVCallee(F.getParent()));
2871 DEBUG(dbgs() << " Out: " << *Autorelease
2872 << "\n");
2873 Autorelease->setTailCall(); // Always tail call autoreleaseRV.
2874 AutoreleaseClass = IC_AutoreleaseRV;
2875 }
2876
28772862 // Check that there is nothing that can affect the reference
28782863 // count between the retain and the call.
28792864 // Note that Retain need not be in BB.
427427 ret void
428428 }
429429
430 ; Same as test11 but the value is returned. Do an RV optimization.
430 ; Same as test11 but the value is returned. Do not perform an RV optimization
431 ; since if the frontend emitted code for an __autoreleasing variable, we may
432 ; want it to be in the autorelease pool.
431433
432434 ; CHECK: define i8* @test11b(
433435 ; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]]
434 ; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %0) [[NUW]]
436 ; CHECK: call i8* @objc_autorelease(i8* %0) [[NUW]]
435437 ; CHECK: }
436438 define i8* @test11b(i8* %x) nounwind {
437439 entry:
120120 %p = call i8* @returner()
121121 call i8* @objc_retainAutoreleasedReturnValue(i8* %p)
122122 %t = call i8* @objc_autoreleaseReturnValue(i8* %p)
123 call void @use_pointer(i8* %t)
123 call void @use_pointer(i8* %p)
124124 ret i8* %t
125125 }
126126
132132 call void @use_pointer(i8* %p)
133133 call i8* @objc_retainAutoreleasedReturnValue(i8* %p)
134134 %t = call i8* @objc_autoreleaseReturnValue(i8* %p)
135 ret i8* %t
135 ret i8* %p
136136 }
137137
138138 ; Turn objc_retain into objc_retainAutoreleasedReturnValue if its operand
155155 ret i8* %p
156156 }
157157
158 ; Apply the RV optimization.
158 ; Do not apply the RV optimization.
159159
160160 ; CHECK: define i8* @test10(i8* %p)
161161 ; CHECK: tail call i8* @objc_retain(i8* %p) [[NUW]]
162 ; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %p) [[NUW]]
162 ; CHECK: call i8* @objc_autorelease(i8* %p) [[NUW]]
163163 ; CHECK-NEXT: ret i8* %p
164164 define i8* @test10(i8* %p) {
165165 %1 = call i8* @objc_retain(i8* %p)
7171 ret i8* %tmp0
7272 }
7373
74 ; If we convert a called @objc_autorelease to an @objc_autoreleaseReturnValue,
75 ; ensure that the tail call is added.
76 define i8* @test6(i8* %x) {
77 entry:
78 ; CHECK: %tmp0 = tail call i8* @objc_retain(i8* %x)
79 %tmp0 = tail call i8* @objc_retain(i8* %x)
80 ; CHECK: %tmp1 = tail call i8* @objc_autoreleaseReturnValue(i8* %x)
81 %tmp1 = call i8* @objc_autorelease(i8* %x)
82 ret i8* %x
83 }