diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/ObjCARCInstKind.cpp | 152 | ||||
-rw-r--r-- | llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h | 74 | ||||
-rw-r--r-- | llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp | 2 |
3 files changed, 81 insertions, 147 deletions
diff --git a/llvm/lib/Analysis/ObjCARCInstKind.cpp b/llvm/lib/Analysis/ObjCARCInstKind.cpp index f268e2a9abd..31c43271183 100644 --- a/llvm/lib/Analysis/ObjCARCInstKind.cpp +++ b/llvm/lib/Analysis/ObjCARCInstKind.cpp @@ -85,97 +85,73 @@ raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS, } ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) { - Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); - // No (mandatory) arguments. - if (AI == AE) - return StringSwitch<ARCInstKind>(F->getName()) - .Case("objc_autoreleasePoolPush", ARCInstKind::AutoreleasepoolPush) - .Case("clang.arc.use", ARCInstKind::IntrinsicUser) - .Default(ARCInstKind::CallOrUser); - - // One argument. - const Argument *A0 = &*AI++; - if (AI == AE) { - // Argument is a pointer. - PointerType *PTy = dyn_cast<PointerType>(A0->getType()); - if (!PTy) - return ARCInstKind::CallOrUser; - - Type *ETy = PTy->getElementType(); - // Argument is i8*. - if (ETy->isIntegerTy(8)) - return StringSwitch<ARCInstKind>(F->getName()) - .Case("objc_retain", ARCInstKind::Retain) - .Case("objc_retainAutoreleasedReturnValue", ARCInstKind::RetainRV) - .Case("objc_unsafeClaimAutoreleasedReturnValue", ARCInstKind::ClaimRV) - .Case("objc_retainBlock", ARCInstKind::RetainBlock) - .Case("objc_release", ARCInstKind::Release) - .Case("objc_autorelease", ARCInstKind::Autorelease) - .Case("objc_autoreleaseReturnValue", ARCInstKind::AutoreleaseRV) - .Case("objc_autoreleasePoolPop", ARCInstKind::AutoreleasepoolPop) - .Case("objc_retainedObject", ARCInstKind::NoopCast) - .Case("objc_unretainedObject", ARCInstKind::NoopCast) - .Case("objc_unretainedPointer", ARCInstKind::NoopCast) - .Case("objc_retain_autorelease", ARCInstKind::FusedRetainAutorelease) - .Case("objc_retainAutorelease", ARCInstKind::FusedRetainAutorelease) - .Case("objc_retainAutoreleaseReturnValue", - ARCInstKind::FusedRetainAutoreleaseRV) - .Case("objc_sync_enter", ARCInstKind::User) - .Case("objc_sync_exit", ARCInstKind::User) - .Default(ARCInstKind::CallOrUser); - - // Argument is i8** - if (PointerType *Pte = dyn_cast<PointerType>(ETy)) - if (Pte->getElementType()->isIntegerTy(8)) - return StringSwitch<ARCInstKind>(F->getName()) - .Case("objc_loadWeakRetained", ARCInstKind::LoadWeakRetained) - .Case("objc_loadWeak", ARCInstKind::LoadWeak) - .Case("objc_destroyWeak", ARCInstKind::DestroyWeak) - .Default(ARCInstKind::CallOrUser); - - // Anything else with one argument. + Intrinsic::ID ID = F->getIntrinsicID(); + switch (ID) { + default: return ARCInstKind::CallOrUser; + case Intrinsic::objc_autorelease: + return ARCInstKind::Autorelease; + case Intrinsic::objc_autoreleasePoolPop: + return ARCInstKind::AutoreleasepoolPop; + case Intrinsic::objc_autoreleasePoolPush: + return ARCInstKind::AutoreleasepoolPush; + case Intrinsic::objc_autoreleaseReturnValue: + return ARCInstKind::AutoreleaseRV; + case Intrinsic::objc_copyWeak: + return ARCInstKind::CopyWeak; + case Intrinsic::objc_destroyWeak: + return ARCInstKind::DestroyWeak; + case Intrinsic::objc_initWeak: + return ARCInstKind::InitWeak; + case Intrinsic::objc_loadWeak: + return ARCInstKind::LoadWeak; + case Intrinsic::objc_loadWeakRetained: + return ARCInstKind::LoadWeakRetained; + case Intrinsic::objc_moveWeak: + return ARCInstKind::MoveWeak; + case Intrinsic::objc_release: + return ARCInstKind::Release; + case Intrinsic::objc_retain: + return ARCInstKind::Retain; + case Intrinsic::objc_retainAutorelease: + return ARCInstKind::FusedRetainAutorelease; + case Intrinsic::objc_retainAutoreleaseReturnValue: + return ARCInstKind::FusedRetainAutoreleaseRV; + case Intrinsic::objc_retainAutoreleasedReturnValue: + return ARCInstKind::RetainRV; + case Intrinsic::objc_retainBlock: + return ARCInstKind::RetainBlock; + case Intrinsic::objc_storeStrong: + return ARCInstKind::StoreStrong; + case Intrinsic::objc_storeWeak: + return ARCInstKind::StoreWeak; + case Intrinsic::objc_clang_arc_use: + return ARCInstKind::IntrinsicUser; + case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue: + return ARCInstKind::ClaimRV; + case Intrinsic::objc_retainedObject: + return ARCInstKind::NoopCast; + case Intrinsic::objc_unretainedObject: + return ARCInstKind::NoopCast; + case Intrinsic::objc_unretainedPointer: + return ARCInstKind::NoopCast; + case Intrinsic::objc_retain_autorelease: + return ARCInstKind::FusedRetainAutorelease; + case Intrinsic::objc_sync_enter: + return ARCInstKind::User; + case Intrinsic::objc_sync_exit: + return ARCInstKind::User; + case Intrinsic::objc_arc_annotation_topdown_bbstart: + case Intrinsic::objc_arc_annotation_topdown_bbend: + case Intrinsic::objc_arc_annotation_bottomup_bbstart: + case Intrinsic::objc_arc_annotation_bottomup_bbend: + // Ignore annotation calls. This is important to stop the + // optimizer from treating annotations as uses which would + // make the state of the pointers they are attempting to + // elucidate to be incorrect. + return ARCInstKind::None; } - - // Two arguments, first is i8**. - const Argument *A1 = &*AI++; - if (AI == AE) - if (PointerType *PTy = dyn_cast<PointerType>(A0->getType())) - if (PointerType *Pte = dyn_cast<PointerType>(PTy->getElementType())) - if (Pte->getElementType()->isIntegerTy(8)) - if (PointerType *PTy1 = dyn_cast<PointerType>(A1->getType())) { - Type *ETy1 = PTy1->getElementType(); - // Second argument is i8* - if (ETy1->isIntegerTy(8)) - return StringSwitch<ARCInstKind>(F->getName()) - .Case("objc_storeWeak", ARCInstKind::StoreWeak) - .Case("objc_initWeak", ARCInstKind::InitWeak) - .Case("objc_storeStrong", ARCInstKind::StoreStrong) - .Default(ARCInstKind::CallOrUser); - // Second argument is i8**. - if (PointerType *Pte1 = dyn_cast<PointerType>(ETy1)) - if (Pte1->getElementType()->isIntegerTy(8)) - return StringSwitch<ARCInstKind>(F->getName()) - .Case("objc_moveWeak", ARCInstKind::MoveWeak) - .Case("objc_copyWeak", ARCInstKind::CopyWeak) - // Ignore annotation calls. This is important to stop the - // optimizer from treating annotations as uses which would - // make the state of the pointers they are attempting to - // elucidate to be incorrect. - .Case("llvm.arc.annotation.topdown.bbstart", - ARCInstKind::None) - .Case("llvm.arc.annotation.topdown.bbend", - ARCInstKind::None) - .Case("llvm.arc.annotation.bottomup.bbstart", - ARCInstKind::None) - .Case("llvm.arc.annotation.bottomup.bbend", - ARCInstKind::None) - .Default(ARCInstKind::CallOrUser); - } - - // Anything else. - return ARCInstKind::CallOrUser; } // A whitelist of intrinsics that we know do not use objc pointers or decrement diff --git a/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h b/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h index ba4924c9cb2..7f6b157304a 100644 --- a/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h +++ b/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h @@ -26,6 +26,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" #include "llvm/Support/ErrorHandling.h" @@ -74,27 +75,27 @@ public: switch (kind) { case ARCRuntimeEntryPointKind::AutoreleaseRV: - return getI8XRetI8XEntryPoint(AutoreleaseRV, - "objc_autoreleaseReturnValue", true); + return getIntrinsicEntryPoint(AutoreleaseRV, + Intrinsic::objc_autoreleaseReturnValue); case ARCRuntimeEntryPointKind::Release: - return getVoidRetI8XEntryPoint(Release, "objc_release"); + return getIntrinsicEntryPoint(Release, Intrinsic::objc_release); case ARCRuntimeEntryPointKind::Retain: - return getI8XRetI8XEntryPoint(Retain, "objc_retain", true); + return getIntrinsicEntryPoint(Retain, Intrinsic::objc_retain); case ARCRuntimeEntryPointKind::RetainBlock: - return getI8XRetI8XEntryPoint(RetainBlock, "objc_retainBlock", false); + return getIntrinsicEntryPoint(RetainBlock, Intrinsic::objc_retainBlock); case ARCRuntimeEntryPointKind::Autorelease: - return getI8XRetI8XEntryPoint(Autorelease, "objc_autorelease", true); + return getIntrinsicEntryPoint(Autorelease, Intrinsic::objc_autorelease); case ARCRuntimeEntryPointKind::StoreStrong: - return getI8XRetI8XXI8XEntryPoint(StoreStrong, "objc_storeStrong"); + return getIntrinsicEntryPoint(StoreStrong, Intrinsic::objc_storeStrong); case ARCRuntimeEntryPointKind::RetainRV: - return getI8XRetI8XEntryPoint(RetainRV, - "objc_retainAutoreleasedReturnValue", true); + return getIntrinsicEntryPoint(RetainRV, + Intrinsic::objc_retainAutoreleasedReturnValue); case ARCRuntimeEntryPointKind::RetainAutorelease: - return getI8XRetI8XEntryPoint(RetainAutorelease, "objc_retainAutorelease", - true); + return getIntrinsicEntryPoint(RetainAutorelease, + Intrinsic::objc_retainAutorelease); case ARCRuntimeEntryPointKind::RetainAutoreleaseRV: - return getI8XRetI8XEntryPoint(RetainAutoreleaseRV, - "objc_retainAutoreleaseReturnValue", true); + return getIntrinsicEntryPoint(RetainAutoreleaseRV, + Intrinsic::objc_retainAutoreleaseReturnValue); } llvm_unreachable("Switch should be a covered switch."); @@ -131,54 +132,11 @@ private: /// Declaration for objc_retainAutoreleaseReturnValue(). Constant *RetainAutoreleaseRV = nullptr; - Constant *getVoidRetI8XEntryPoint(Constant *&Decl, StringRef Name) { + Constant *getIntrinsicEntryPoint(Constant *&Decl, Intrinsic::ID IntID) { if (Decl) return Decl; - LLVMContext &C = TheModule->getContext(); - Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) }; - AttributeList Attr = AttributeList().addAttribute( - C, AttributeList::FunctionIndex, Attribute::NoUnwind); - FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params, - /*isVarArg=*/false); - return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); - } - - Constant *getI8XRetI8XEntryPoint(Constant *&Decl, StringRef Name, - bool NoUnwind = false) { - if (Decl) - return Decl; - - LLVMContext &C = TheModule->getContext(); - Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C)); - Type *Params[] = { I8X }; - FunctionType *Fty = FunctionType::get(I8X, Params, /*isVarArg=*/false); - AttributeList Attr = AttributeList(); - - if (NoUnwind) - Attr = Attr.addAttribute(C, AttributeList::FunctionIndex, - Attribute::NoUnwind); - - return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); - } - - Constant *getI8XRetI8XXI8XEntryPoint(Constant *&Decl, StringRef Name) { - if (Decl) - return Decl; - - LLVMContext &C = TheModule->getContext(); - Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C)); - Type *I8XX = PointerType::getUnqual(I8X); - Type *Params[] = { I8XX, I8X }; - - AttributeList Attr = AttributeList().addAttribute( - C, AttributeList::FunctionIndex, Attribute::NoUnwind); - Attr = Attr.addParamAttribute(C, 0, Attribute::NoCapture); - - FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params, - /*isVarArg=*/false); - - return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); + return Decl = Intrinsic::getDeclaration(TheModule, IntID); } }; diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp index 1f1ea9f5873..abe2871c0b8 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp @@ -522,7 +522,7 @@ bool ObjCARCContract::tryToPeepholeInstruction( TailOkForStoreStrongs = false; return true; case ARCInstKind::IntrinsicUser: - // Remove calls to @clang.arc.use(...). + // Remove calls to @llvm.objc.clang.arc.use(...). Inst->eraseFromParent(); return true; default: |