1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[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

llvm-svn: 368730
This commit is contained in:
Steven Wu 2019-08-13 17:52:21 +00:00
parent dc08001f42
commit a25e636ce4
5 changed files with 48 additions and 48 deletions

View File

@ -54,13 +54,9 @@ namespace llvm {
/// module is modified. /// module is modified.
bool UpgradeModuleFlags(Module &M); bool UpgradeModuleFlags(Module &M);
/// This checks for objc retain release marker which should be upgraded. It /// Convert calls to ARC runtime functions to intrinsic calls and upgrade the
/// returns true if module is modified. /// old retain release marker to new module flag format.
bool UpgradeRetainReleaseMarker(Module &M); void UpgradeARCRuntime(Module &M);
/// Convert calls to ARC runtime functions to intrinsic calls if the bitcode
/// has the arm64 retainAutoreleasedReturnValue marker.
void UpgradeARCRuntimeCalls(Module &M);
void UpgradeSectionAttributes(Module &M); void UpgradeSectionAttributes(Module &M);

View File

@ -5312,8 +5312,7 @@ Error BitcodeReader::materializeModule() {
UpgradeModuleFlags(*TheModule); UpgradeModuleFlags(*TheModule);
UpgradeRetainReleaseMarker(*TheModule); UpgradeARCRuntime(*TheModule);
UpgradeARCRuntimeCalls(*TheModule);
return Error::success(); return Error::success();
} }

View File

@ -3830,7 +3830,9 @@ bool llvm::UpgradeDebugInfo(Module &M) {
return Modified; return Modified;
} }
bool llvm::UpgradeRetainReleaseMarker(Module &M) { /// This checks for objc retain release marker which should be upgraded. It
/// returns true if module is modified.
static bool UpgradeRetainReleaseMarker(Module &M) {
bool Changed = false; bool Changed = false;
const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker"; const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
NamedMDNode *ModRetainReleaseMarker = M.getNamedMetadata(MarkerKey); NamedMDNode *ModRetainReleaseMarker = M.getNamedMetadata(MarkerKey);
@ -3854,7 +3856,7 @@ bool llvm::UpgradeRetainReleaseMarker(Module &M) {
return Changed; return Changed;
} }
void llvm::UpgradeARCRuntimeCalls(Module &M) { void llvm::UpgradeARCRuntime(Module &M) {
// This lambda converts normal function calls to ARC runtime functions to // This lambda converts normal function calls to ARC runtime functions to
// intrinsic calls. // intrinsic calls.
auto UpgradeToIntrinsic = [&](const char *OldFunc, auto UpgradeToIntrinsic = [&](const char *OldFunc,
@ -3905,9 +3907,10 @@ void llvm::UpgradeARCRuntimeCalls(Module &M) {
// "llvm.objc.clang.arc.use". // "llvm.objc.clang.arc.use".
UpgradeToIntrinsic("clang.arc.use", llvm::Intrinsic::objc_clang_arc_use); UpgradeToIntrinsic("clang.arc.use", llvm::Intrinsic::objc_clang_arc_use);
// Return if the bitcode doesn't have the arm64 retainAutoreleasedReturnValue // Upgrade the retain release marker. If there is no need to upgrade
// marker. We don't know for sure that it was compiled with ARC in that case. // the marker, that means either the module is already new enough to contain
if (!M.getModuleFlag("clang.arc.retainAutoreleasedReturnValueMarker")) // new intrinsics or it is not ARC. There is no need to upgrade runtime call.
if (!UpgradeRetainReleaseMarker(M))
return; return;
std::pair<const char *, llvm::Intrinsic::ID> RuntimeFuncs[] = { std::pair<const char *, llvm::Intrinsic::ID> RuntimeFuncs[] = {

Binary file not shown.

View File

@ -3,10 +3,12 @@
; upgrade-arc-runtime-calls.bc and upgrade-mrr-runtime-calls.bc are identical ; upgrade-arc-runtime-calls.bc and upgrade-mrr-runtime-calls.bc are identical
; except that the former has the arm64 retainAutoreleasedReturnValueMarker ; except that the former has the arm64 retainAutoreleasedReturnValueMarker
; metadata. ; metadata. upgrade-arc-runtime-calls-new.bc has the new module flag format of
; marker, it should not be upgraded.
; RUN: llvm-dis < %S/upgrade-arc-runtime-calls.bc | FileCheck -check-prefixes=ARC %s ; RUN: llvm-dis < %S/upgrade-arc-runtime-calls.bc | FileCheck -check-prefixes=ARC %s
; RUN: llvm-dis < %S/upgrade-mrr-runtime-calls.bc | FileCheck -check-prefixes=MRR %s ; RUN: llvm-dis < %S/upgrade-mrr-runtime-calls.bc | FileCheck -check-prefixes=NOUPGRADE %s
; RUN: llvm-dis < %S/upgrade-arc-runtime-calls-new.bc | FileCheck -check-prefixes=NOUPGRADE %s
define void @testRuntimeCalls(i8* %a, i8** %b, i8** %c, i32* %d, i32** %e) personality i32 (...)* @__gxx_personality_v0 { define void @testRuntimeCalls(i8* %a, i8** %b, i8** %c, i32* %d, i32** %e) personality i32 (...)* @__gxx_personality_v0 {
entry: entry:
@ -89,35 +91,35 @@ unwindBlock:
// ARC-NEXT: tail call void @llvm.objc.arc.annotation.bottomup.bbend(i8** %[[B]], i8** %[[C]]) // ARC-NEXT: tail call void @llvm.objc.arc.annotation.bottomup.bbend(i8** %[[B]], i8** %[[C]])
// ARC-NEXT: invoke void @objc_autoreleasePoolPop(i8* %[[A]]) // ARC-NEXT: invoke void @objc_autoreleasePoolPop(i8* %[[A]])
// MRR: define void @testRuntimeCalls(i8* %[[A:.*]], i8** %[[B:.*]], i8** %[[C:.*]], i32* %[[D:.*]], i32** %[[E:.*]]) personality // NOUPGRADE: define void @testRuntimeCalls(i8* %[[A:.*]], i8** %[[B:.*]], i8** %[[C:.*]], i32* %[[D:.*]], i32** %[[E:.*]]) personality
// MRR: %[[V0:.*]] = tail call i8* @objc_autorelease(i8* %[[A]]) // NOUPGRADE: %[[V0:.*]] = tail call i8* @objc_autorelease(i8* %[[A]])
// MRR-NEXT: tail call void @objc_autoreleasePoolPop(i8* %[[A]]) // NOUPGRADE-NEXT: tail call void @objc_autoreleasePoolPop(i8* %[[A]])
// MRR-NEXT: %[[V1:.*]] = tail call i8* @objc_autoreleasePoolPush() // NOUPGRADE-NEXT: %[[V1:.*]] = tail call i8* @objc_autoreleasePoolPush()
// MRR-NEXT: %[[V2:.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* %[[A]]) // NOUPGRADE-NEXT: %[[V2:.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* %[[A]])
// MRR-NEXT: tail call void @objc_copyWeak(i8** %[[B]], i8** %[[C]]) // NOUPGRADE-NEXT: tail call void @objc_copyWeak(i8** %[[B]], i8** %[[C]])
// MRR-NEXT: tail call void @objc_destroyWeak(i8** %[[B]]) // NOUPGRADE-NEXT: tail call void @objc_destroyWeak(i8** %[[B]])
// MRR-NEXT: %[[V3:.*]] = tail call i32* @objc_initWeak(i32** %[[E]], i32* %[[D]]) // NOUPGRADE-NEXT: %[[V3:.*]] = tail call i32* @objc_initWeak(i32** %[[E]], i32* %[[D]])
// MRR-NEXT: %[[V4:.*]] = tail call i8* @objc_loadWeak(i8** %[[B]]) // NOUPGRADE-NEXT: %[[V4:.*]] = tail call i8* @objc_loadWeak(i8** %[[B]])
// MRR-NEXT: %[[V5:.*]] = tail call i8* @objc_loadWeakRetained(i8** %[[B]]) // NOUPGRADE-NEXT: %[[V5:.*]] = tail call i8* @objc_loadWeakRetained(i8** %[[B]])
// MRR-NEXT: tail call void @objc_moveWeak(i8** %[[B]], i8** %[[C]]) // NOUPGRADE-NEXT: tail call void @objc_moveWeak(i8** %[[B]], i8** %[[C]])
// MRR-NEXT: tail call void @objc_release(i8* %[[A]]) // NOUPGRADE-NEXT: tail call void @objc_release(i8* %[[A]])
// MRR-NEXT: %[[V6:.*]] = tail call i8* @objc_retain(i8* %[[A]]) // NOUPGRADE-NEXT: %[[V6:.*]] = tail call i8* @objc_retain(i8* %[[A]])
// MRR-NEXT: %[[V7:.*]] = tail call i8* @objc_retainAutorelease(i8* %[[A]]) // NOUPGRADE-NEXT: %[[V7:.*]] = tail call i8* @objc_retainAutorelease(i8* %[[A]])
// MRR-NEXT: %[[V8:.*]] = tail call i8* @objc_retainAutoreleaseReturnValue(i8* %[[A]]) // NOUPGRADE-NEXT: %[[V8:.*]] = tail call i8* @objc_retainAutoreleaseReturnValue(i8* %[[A]])
// MRR-NEXT: %[[V9:.*]] = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %[[A]]) // NOUPGRADE-NEXT: %[[V9:.*]] = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %[[A]])
// MRR-NEXT: %[[V10:.*]] = tail call i8* @objc_retainBlock(i8* %[[A]]) // NOUPGRADE-NEXT: %[[V10:.*]] = tail call i8* @objc_retainBlock(i8* %[[A]])
// MRR-NEXT: tail call void @objc_storeStrong(i8** %[[B]], i8* %[[A]]) // NOUPGRADE-NEXT: tail call void @objc_storeStrong(i8** %[[B]], i8* %[[A]])
// MRR-NEXT: %[[V11:.*]] = tail call i8* @objc_storeWeak(i8** %[[B]], i8* %[[A]]) // NOUPGRADE-NEXT: %[[V11:.*]] = tail call i8* @objc_storeWeak(i8** %[[B]], i8* %[[A]])
// MRR-NEXT: tail call void (...) @llvm.objc.clang.arc.use(i8* %[[A]]) // NOUPGRADE-NEXT: tail call void (...) @llvm.objc.clang.arc.use(i8* %[[A]])
// MRR-NEXT: %[[V12:.*]] = tail call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* %[[A]]) // NOUPGRADE-NEXT: %[[V12:.*]] = tail call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* %[[A]])
// MRR-NEXT: %[[V13:.*]] = tail call i8* @objc_retainedObject(i8* %[[A]]) // NOUPGRADE-NEXT: %[[V13:.*]] = tail call i8* @objc_retainedObject(i8* %[[A]])
// MRR-NEXT: %[[V14:.*]] = tail call i8* @objc_unretainedObject(i8* %[[A]]) // NOUPGRADE-NEXT: %[[V14:.*]] = tail call i8* @objc_unretainedObject(i8* %[[A]])
// MRR-NEXT: %[[V15:.*]] = tail call i8* @objc_unretainedPointer(i8* %[[A]]) // NOUPGRADE-NEXT: %[[V15:.*]] = tail call i8* @objc_unretainedPointer(i8* %[[A]])
// MRR-NEXT: %[[V16:.*]] = tail call i8* @objc_retain.autorelease(i8* %[[A]]) // NOUPGRADE-NEXT: %[[V16:.*]] = tail call i8* @objc_retain.autorelease(i8* %[[A]])
// MRR-NEXT: %[[V17:.*]] = tail call i32 @objc_sync.enter(i8* %[[A]]) // NOUPGRADE-NEXT: %[[V17:.*]] = tail call i32 @objc_sync.enter(i8* %[[A]])
// MRR-NEXT: %[[V18:.*]] = tail call i32 @objc_sync.exit(i8* %[[A]]) // NOUPGRADE-NEXT: %[[V18:.*]] = tail call i32 @objc_sync.exit(i8* %[[A]])
// MRR-NEXT: tail call void @objc_arc_annotation_topdown_bbstart(i8** %[[B]], i8** %[[C]]) // NOUPGRADE-NEXT: tail call void @objc_arc_annotation_topdown_bbstart(i8** %[[B]], i8** %[[C]])
// MRR-NEXT: tail call void @objc_arc_annotation_topdown_bbend(i8** %[[B]], i8** %[[C]]) // NOUPGRADE-NEXT: tail call void @objc_arc_annotation_topdown_bbend(i8** %[[B]], i8** %[[C]])
// MRR-NEXT: tail call void @objc_arc_annotation_bottomup_bbstart(i8** %[[B]], i8** %[[C]]) // NOUPGRADE-NEXT: tail call void @objc_arc_annotation_bottomup_bbstart(i8** %[[B]], i8** %[[C]])
// MRR-NEXT: tail call void @objc_arc_annotation_bottomup_bbend(i8** %[[B]], i8** %[[C]]) // NOUPGRADE-NEXT: tail call void @objc_arc_annotation_bottomup_bbend(i8** %[[B]], i8** %[[C]])
// MRR-NEXT: invoke void @objc_autoreleasePoolPop(i8* %[[A]]) // NOUPGRADE-NEXT: invoke void @objc_autoreleasePoolPop(i8* %[[A]])