Skip to content

Commit 0fe0887

Browse files
[AutoUpgrader] Make ArcRuntime Autoupgrader more conservative
Summary: This is a tweak to r368311 and r368646 which auto upgrades the calls to objc runtime functions to objc runtime intrinsics, in order to make sure that the auto upgrader does not trigger with up-to-date bitcode. It is possible for bitcode that is up-to-date to contain direct calls to objc runtime function and those are not inserted by compiler as part of ARC and they should not be upgraded. Now auto upgrader only triggers as when the old style of ARC marker is used so it is guaranteed that it won't trigger on update-to-date bitcode. This also means it won't do this upgrade for bitcode from llvm-8 and llvm-9, which preserves the behavior of those releases. Ideally they should be upgraded as well but it is more important to make sure AutoUpgrader will not trigger on up-to-date bitcode. Reviewers: ahatanak, rjmccall, dexonsmith, pete Reviewed By: dexonsmith Subscribers: hiraditya, jkorous, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66153 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368730 91177308-0d34-0410-b5e6-96231b3b80d8 apple-llvm-split-commit: b47beb8a7084f8feac68176d6fc90687045b87bb apple-llvm-split-dir: llvm/
1 parent f429795 commit 0fe0887

File tree

5 files changed

+48
-48
lines changed

5 files changed

+48
-48
lines changed

llvm/include/llvm/IR/AutoUpgrade.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,9 @@ namespace llvm {
5555
/// module is modified.
5656
bool UpgradeModuleFlags(Module &M);
5757

58-
/// This checks for objc retain release marker which should be upgraded. It
59-
/// returns true if module is modified.
60-
bool UpgradeRetainReleaseMarker(Module &M);
61-
62-
/// Convert calls to ARC runtime functions to intrinsic calls if the bitcode
63-
/// has the arm64 retainAutoreleasedReturnValue marker.
64-
void UpgradeARCRuntimeCalls(Module &M);
58+
/// Convert calls to ARC runtime functions to intrinsic calls and upgrade the
59+
/// old retain release marker to new module flag format.
60+
void UpgradeARCRuntime(Module &M);
6561

6662
void UpgradeSectionAttributes(Module &M);
6763

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4868,8 +4868,7 @@ Error BitcodeReader::materializeModule() {
48684868

48694869
UpgradeModuleFlags(*TheModule);
48704870

4871-
UpgradeRetainReleaseMarker(*TheModule);
4872-
UpgradeARCRuntimeCalls(*TheModule);
4871+
UpgradeARCRuntime(*TheModule);
48734872

48744873
return Error::success();
48754874
}

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3629,7 +3629,9 @@ bool llvm::UpgradeDebugInfo(Module &M) {
36293629
return Modified;
36303630
}
36313631

3632-
bool llvm::UpgradeRetainReleaseMarker(Module &M) {
3632+
/// This checks for objc retain release marker which should be upgraded. It
3633+
/// returns true if module is modified.
3634+
static bool UpgradeRetainReleaseMarker(Module &M) {
36333635
bool Changed = false;
36343636
const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
36353637
NamedMDNode *ModRetainReleaseMarker = M.getNamedMetadata(MarkerKey);
@@ -3653,7 +3655,7 @@ bool llvm::UpgradeRetainReleaseMarker(Module &M) {
36533655
return Changed;
36543656
}
36553657

3656-
void llvm::UpgradeARCRuntimeCalls(Module &M) {
3658+
void llvm::UpgradeARCRuntime(Module &M) {
36573659
// This lambda converts normal function calls to ARC runtime functions to
36583660
// intrinsic calls.
36593661
auto UpgradeToIntrinsic = [&](const char *OldFunc,
@@ -3704,9 +3706,10 @@ void llvm::UpgradeARCRuntimeCalls(Module &M) {
37043706
// "llvm.objc.clang.arc.use".
37053707
UpgradeToIntrinsic("clang.arc.use", llvm::Intrinsic::objc_clang_arc_use);
37063708

3707-
// Return if the bitcode doesn't have the arm64 retainAutoreleasedReturnValue
3708-
// marker. We don't know for sure that it was compiled with ARC in that case.
3709-
if (!M.getModuleFlag("clang.arc.retainAutoreleasedReturnValueMarker"))
3709+
// Upgrade the retain release marker. If there is no need to upgrade
3710+
// the marker, that means either the module is already new enough to contain
3711+
// new intrinsics or it is not ARC. There is no need to upgrade runtime call.
3712+
if (!UpgradeRetainReleaseMarker(M))
37103713
return;
37113714

37123715
std::pair<const char *, llvm::Intrinsic::ID> RuntimeFuncs[] = {
Binary file not shown.

llvm/test/Bitcode/upgrade-arc-runtime-calls.ll

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33

44
; upgrade-arc-runtime-calls.bc and upgrade-mrr-runtime-calls.bc are identical
55
; except that the former has the arm64 retainAutoreleasedReturnValueMarker
6-
; metadata.
6+
; metadata. upgrade-arc-runtime-calls-new.bc has the new module flag format of
7+
; marker, it should not be upgraded.
78

89
; RUN: llvm-dis < %S/upgrade-arc-runtime-calls.bc | FileCheck -check-prefixes=ARC %s
9-
; RUN: llvm-dis < %S/upgrade-mrr-runtime-calls.bc | FileCheck -check-prefixes=MRR %s
10+
; RUN: llvm-dis < %S/upgrade-mrr-runtime-calls.bc | FileCheck -check-prefixes=NOUPGRADE %s
11+
; RUN: llvm-dis < %S/upgrade-arc-runtime-calls-new.bc | FileCheck -check-prefixes=NOUPGRADE %s
1012

1113
define void @testRuntimeCalls(i8* %a, i8** %b, i8** %c, i32* %d, i32** %e) personality i32 (...)* @__gxx_personality_v0 {
1214
entry:
@@ -89,35 +91,35 @@ unwindBlock:
8991
// ARC-NEXT: tail call void @llvm.objc.arc.annotation.bottomup.bbend(i8** %[[B]], i8** %[[C]])
9092
// ARC-NEXT: invoke void @objc_autoreleasePoolPop(i8* %[[A]])
9193

92-
// MRR: define void @testRuntimeCalls(i8* %[[A:.*]], i8** %[[B:.*]], i8** %[[C:.*]], i32* %[[D:.*]], i32** %[[E:.*]]) personality
93-
// MRR: %[[V0:.*]] = tail call i8* @objc_autorelease(i8* %[[A]])
94-
// MRR-NEXT: tail call void @objc_autoreleasePoolPop(i8* %[[A]])
95-
// MRR-NEXT: %[[V1:.*]] = tail call i8* @objc_autoreleasePoolPush()
96-
// MRR-NEXT: %[[V2:.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* %[[A]])
97-
// MRR-NEXT: tail call void @objc_copyWeak(i8** %[[B]], i8** %[[C]])
98-
// MRR-NEXT: tail call void @objc_destroyWeak(i8** %[[B]])
99-
// MRR-NEXT: %[[V3:.*]] = tail call i32* @objc_initWeak(i32** %[[E]], i32* %[[D]])
100-
// MRR-NEXT: %[[V4:.*]] = tail call i8* @objc_loadWeak(i8** %[[B]])
101-
// MRR-NEXT: %[[V5:.*]] = tail call i8* @objc_loadWeakRetained(i8** %[[B]])
102-
// MRR-NEXT: tail call void @objc_moveWeak(i8** %[[B]], i8** %[[C]])
103-
// MRR-NEXT: tail call void @objc_release(i8* %[[A]])
104-
// MRR-NEXT: %[[V6:.*]] = tail call i8* @objc_retain(i8* %[[A]])
105-
// MRR-NEXT: %[[V7:.*]] = tail call i8* @objc_retainAutorelease(i8* %[[A]])
106-
// MRR-NEXT: %[[V8:.*]] = tail call i8* @objc_retainAutoreleaseReturnValue(i8* %[[A]])
107-
// MRR-NEXT: %[[V9:.*]] = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %[[A]])
108-
// MRR-NEXT: %[[V10:.*]] = tail call i8* @objc_retainBlock(i8* %[[A]])
109-
// MRR-NEXT: tail call void @objc_storeStrong(i8** %[[B]], i8* %[[A]])
110-
// MRR-NEXT: %[[V11:.*]] = tail call i8* @objc_storeWeak(i8** %[[B]], i8* %[[A]])
111-
// MRR-NEXT: tail call void (...) @llvm.objc.clang.arc.use(i8* %[[A]])
112-
// MRR-NEXT: %[[V12:.*]] = tail call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* %[[A]])
113-
// MRR-NEXT: %[[V13:.*]] = tail call i8* @objc_retainedObject(i8* %[[A]])
114-
// MRR-NEXT: %[[V14:.*]] = tail call i8* @objc_unretainedObject(i8* %[[A]])
115-
// MRR-NEXT: %[[V15:.*]] = tail call i8* @objc_unretainedPointer(i8* %[[A]])
116-
// MRR-NEXT: %[[V16:.*]] = tail call i8* @objc_retain.autorelease(i8* %[[A]])
117-
// MRR-NEXT: %[[V17:.*]] = tail call i32 @objc_sync.enter(i8* %[[A]])
118-
// MRR-NEXT: %[[V18:.*]] = tail call i32 @objc_sync.exit(i8* %[[A]])
119-
// MRR-NEXT: tail call void @objc_arc_annotation_topdown_bbstart(i8** %[[B]], i8** %[[C]])
120-
// MRR-NEXT: tail call void @objc_arc_annotation_topdown_bbend(i8** %[[B]], i8** %[[C]])
121-
// MRR-NEXT: tail call void @objc_arc_annotation_bottomup_bbstart(i8** %[[B]], i8** %[[C]])
122-
// MRR-NEXT: tail call void @objc_arc_annotation_bottomup_bbend(i8** %[[B]], i8** %[[C]])
123-
// MRR-NEXT: invoke void @objc_autoreleasePoolPop(i8* %[[A]])
94+
// NOUPGRADE: define void @testRuntimeCalls(i8* %[[A:.*]], i8** %[[B:.*]], i8** %[[C:.*]], i32* %[[D:.*]], i32** %[[E:.*]]) personality
95+
// NOUPGRADE: %[[V0:.*]] = tail call i8* @objc_autorelease(i8* %[[A]])
96+
// NOUPGRADE-NEXT: tail call void @objc_autoreleasePoolPop(i8* %[[A]])
97+
// NOUPGRADE-NEXT: %[[V1:.*]] = tail call i8* @objc_autoreleasePoolPush()
98+
// NOUPGRADE-NEXT: %[[V2:.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* %[[A]])
99+
// NOUPGRADE-NEXT: tail call void @objc_copyWeak(i8** %[[B]], i8** %[[C]])
100+
// NOUPGRADE-NEXT: tail call void @objc_destroyWeak(i8** %[[B]])
101+
// NOUPGRADE-NEXT: %[[V3:.*]] = tail call i32* @objc_initWeak(i32** %[[E]], i32* %[[D]])
102+
// NOUPGRADE-NEXT: %[[V4:.*]] = tail call i8* @objc_loadWeak(i8** %[[B]])
103+
// NOUPGRADE-NEXT: %[[V5:.*]] = tail call i8* @objc_loadWeakRetained(i8** %[[B]])
104+
// NOUPGRADE-NEXT: tail call void @objc_moveWeak(i8** %[[B]], i8** %[[C]])
105+
// NOUPGRADE-NEXT: tail call void @objc_release(i8* %[[A]])
106+
// NOUPGRADE-NEXT: %[[V6:.*]] = tail call i8* @objc_retain(i8* %[[A]])
107+
// NOUPGRADE-NEXT: %[[V7:.*]] = tail call i8* @objc_retainAutorelease(i8* %[[A]])
108+
// NOUPGRADE-NEXT: %[[V8:.*]] = tail call i8* @objc_retainAutoreleaseReturnValue(i8* %[[A]])
109+
// NOUPGRADE-NEXT: %[[V9:.*]] = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %[[A]])
110+
// NOUPGRADE-NEXT: %[[V10:.*]] = tail call i8* @objc_retainBlock(i8* %[[A]])
111+
// NOUPGRADE-NEXT: tail call void @objc_storeStrong(i8** %[[B]], i8* %[[A]])
112+
// NOUPGRADE-NEXT: %[[V11:.*]] = tail call i8* @objc_storeWeak(i8** %[[B]], i8* %[[A]])
113+
// NOUPGRADE-NEXT: tail call void (...) @llvm.objc.clang.arc.use(i8* %[[A]])
114+
// NOUPGRADE-NEXT: %[[V12:.*]] = tail call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* %[[A]])
115+
// NOUPGRADE-NEXT: %[[V13:.*]] = tail call i8* @objc_retainedObject(i8* %[[A]])
116+
// NOUPGRADE-NEXT: %[[V14:.*]] = tail call i8* @objc_unretainedObject(i8* %[[A]])
117+
// NOUPGRADE-NEXT: %[[V15:.*]] = tail call i8* @objc_unretainedPointer(i8* %[[A]])
118+
// NOUPGRADE-NEXT: %[[V16:.*]] = tail call i8* @objc_retain.autorelease(i8* %[[A]])
119+
// NOUPGRADE-NEXT: %[[V17:.*]] = tail call i32 @objc_sync.enter(i8* %[[A]])
120+
// NOUPGRADE-NEXT: %[[V18:.*]] = tail call i32 @objc_sync.exit(i8* %[[A]])
121+
// NOUPGRADE-NEXT: tail call void @objc_arc_annotation_topdown_bbstart(i8** %[[B]], i8** %[[C]])
122+
// NOUPGRADE-NEXT: tail call void @objc_arc_annotation_topdown_bbend(i8** %[[B]], i8** %[[C]])
123+
// NOUPGRADE-NEXT: tail call void @objc_arc_annotation_bottomup_bbstart(i8** %[[B]], i8** %[[C]])
124+
// NOUPGRADE-NEXT: tail call void @objc_arc_annotation_bottomup_bbend(i8** %[[B]], i8** %[[C]])
125+
// NOUPGRADE-NEXT: invoke void @objc_autoreleasePoolPop(i8* %[[A]])

0 commit comments

Comments
 (0)