diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2019-08-08 16:59:31 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2019-08-08 16:59:31 +0000 |
commit | ecde8c7ad47447c5bd02f4bb084843ae20bdbb34 (patch) | |
tree | eab80b8855da7a87b0c23ef4eb70b15d2cfa4acd /llvm/lib | |
parent | caa0db13181e97b1c62a65168227b80cbdc2ac5e (diff) | |
download | bcm5719-llvm-ecde8c7ad47447c5bd02f4bb084843ae20bdbb34.tar.gz bcm5719-llvm-ecde8c7ad47447c5bd02f4bb084843ae20bdbb34.zip |
[ObjC][ARC] Upgrade calls to ARC runtime functions to intrinsic calls if
the bitcode has the arm64 retainAutoreleasedReturnValue marker
The ARC middle-end passes stopped optimizing or transforming bitcode
that has been compiled with old compilers after we started emitting
calls to ARC runtime functions as intrinsic calls instead of normal
function calls in the front-end and made changes to teach the ARC
middle-end passes about those intrinsics (see r349534). This patch
converts calls to ARC runtime functions that are not intrinsic functions
to intrinsic function calls if the bitcode has the arm64
retainAutoreleasedReturnValue marker. Checking for the presence of the
marker is necessary to make sure we aren't changing ARC function calls
that were originally MRR message sends (see r349952).
rdar://problem/53280660
Differential Revision: https://reviews.llvm.org/D65902
llvm-svn: 368311
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/IR/AutoUpgrade.cpp | 82 |
2 files changed, 69 insertions, 14 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 29dc7f61639..cba9385318c 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -5313,6 +5313,7 @@ Error BitcodeReader::materializeModule() { UpgradeModuleFlags(*TheModule); UpgradeRetainReleaseMarker(*TheModule); + UpgradeARCRuntimeCalls(*TheModule); return Error::success(); } diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 0800fcffcd2..2caadfd8ac1 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -490,12 +490,6 @@ static bool UpgradeX86IntrinsicFunction(Function *F, StringRef Name, static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { assert(F && "Illegal to upgrade a non-existent Function."); - // Upgrade intrinsics "clang.arc.use" which doesn't start with "llvm.". - if (F->getName() == "clang.arc.use") { - NewFn = nullptr; - return true; - } - // Quickly eliminate it, if it's not a candidate. StringRef Name = F->getName(); if (Name.size() <= 8 || !Name.startswith("llvm.")) @@ -1661,14 +1655,6 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { // Get the Function's name. StringRef Name = F->getName(); - // clang.arc.use is an old name for llvm.arc.clang.arc.use. It is dropped - // from upgrader because the optimizer now only recognizes intrinsics for - // ARC runtime calls. - if (Name == "clang.arc.use") { - CI->eraseFromParent(); - return; - } - assert(Name.startswith("llvm.") && "Intrinsic doesn't start with 'llvm.'"); Name = Name.substr(5); @@ -3868,6 +3854,74 @@ bool llvm::UpgradeRetainReleaseMarker(Module &M) { return Changed; } +bool llvm::UpgradeARCRuntimeCalls(Module &M) { + auto UpgradeToIntrinsic = [&](const char *OldFunc, + llvm::Intrinsic::ID IntrinsicFunc) { + Function *Fn = M.getFunction(OldFunc); + + if (!Fn) + return false; + + Function *NewFn = llvm::Intrinsic::getDeclaration(&M, IntrinsicFunc); + Fn->replaceAllUsesWith(NewFn); + Fn->eraseFromParent(); + return true; + }; + + // Unconditionally convert "clang.arc.use" to "llvm.objc.clang.arc.use". + bool Changed = + UpgradeToIntrinsic("clang.arc.use", llvm::Intrinsic::objc_clang_arc_use); + + // Return if the bitcode doesn't have the arm64 retainAutoreleasedReturnValue + // marker. We don't know for sure that it was compiled with ARC in that case. + if (!M.getModuleFlag("clang.arc.retainAutoreleasedReturnValueMarker")) + return false; + + std::pair<const char *, llvm::Intrinsic::ID> RuntimeFuncs[] = { + {"objc_autorelease", llvm::Intrinsic::objc_autorelease}, + {"objc_autoreleasePoolPop", llvm::Intrinsic::objc_autoreleasePoolPop}, + {"objc_autoreleasePoolPush", llvm::Intrinsic::objc_autoreleasePoolPush}, + {"objc_autoreleaseReturnValue", + llvm::Intrinsic::objc_autoreleaseReturnValue}, + {"objc_copyWeak", llvm::Intrinsic::objc_copyWeak}, + {"objc_destroyWeak", llvm::Intrinsic::objc_destroyWeak}, + {"objc_initWeak", llvm::Intrinsic::objc_initWeak}, + {"objc_loadWeak", llvm::Intrinsic::objc_loadWeak}, + {"objc_loadWeakRetained", llvm::Intrinsic::objc_loadWeakRetained}, + {"objc_moveWeak", llvm::Intrinsic::objc_moveWeak}, + {"objc_release", llvm::Intrinsic::objc_release}, + {"objc_retain", llvm::Intrinsic::objc_retain}, + {"objc_retainAutorelease", llvm::Intrinsic::objc_retainAutorelease}, + {"objc_retainAutoreleaseReturnValue", + llvm::Intrinsic::objc_retainAutoreleaseReturnValue}, + {"objc_retainAutoreleasedReturnValue", + llvm::Intrinsic::objc_retainAutoreleasedReturnValue}, + {"objc_retainBlock", llvm::Intrinsic::objc_retainBlock}, + {"objc_storeStrong", llvm::Intrinsic::objc_storeStrong}, + {"objc_storeWeak", llvm::Intrinsic::objc_storeWeak}, + {"objc_unsafeClaimAutoreleasedReturnValue", + llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue}, + {"objc_retainedObject", llvm::Intrinsic::objc_retainedObject}, + {"objc_unretainedObject", llvm::Intrinsic::objc_unretainedObject}, + {"objc_unretainedPointer", llvm::Intrinsic::objc_unretainedPointer}, + {"objc_retain_autorelease", llvm::Intrinsic::objc_retain_autorelease}, + {"objc_sync_enter", llvm::Intrinsic::objc_sync_enter}, + {"objc_sync_exit", llvm::Intrinsic::objc_sync_exit}, + {"objc_arc_annotation_topdown_bbstart", + llvm::Intrinsic::objc_arc_annotation_topdown_bbstart}, + {"objc_arc_annotation_topdown_bbend", + llvm::Intrinsic::objc_arc_annotation_topdown_bbend}, + {"objc_arc_annotation_bottomup_bbstart", + llvm::Intrinsic::objc_arc_annotation_bottomup_bbstart}, + {"objc_arc_annotation_bottomup_bbend", + llvm::Intrinsic::objc_arc_annotation_bottomup_bbend}}; + + for (auto &I : RuntimeFuncs) + Changed |= UpgradeToIntrinsic(I.first, I.second); + + return Changed; +} + bool llvm::UpgradeModuleFlags(Module &M) { NamedMDNode *ModFlags = M.getModuleFlagsMetadata(); if (!ModFlags) |