LCOV - code coverage report
Current view: top level - lib/Analysis - ObjCARCInstKind.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 100 163 61.3 %
Date: 2017-09-14 15:23:50 Functions: 13 14 92.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- ARCInstKind.cpp - ObjC ARC Optimization ----------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : /// \file
      10             : /// This file defines several utility functions used by various ARC
      11             : /// optimizations which are IMHO too big to be in a header file.
      12             : ///
      13             : /// WARNING: This file knows about certain library functions. It recognizes them
      14             : /// by name, and hardwires knowledge of their semantics.
      15             : ///
      16             : /// WARNING: This file knows about how certain Objective-C library functions are
      17             : /// used. Naive LLVM IR transformations which would otherwise be
      18             : /// behavior-preserving may break these assumptions.
      19             : ///
      20             : //===----------------------------------------------------------------------===//
      21             : 
      22             : #include "llvm/Analysis/ObjCARCInstKind.h"
      23             : #include "llvm/ADT/StringSwitch.h"
      24             : #include "llvm/Analysis/ObjCARCAnalysisUtils.h"
      25             : #include "llvm/IR/Intrinsics.h"
      26             : 
      27             : using namespace llvm;
      28             : using namespace llvm::objcarc;
      29             : 
      30           0 : raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS,
      31             :                                        const ARCInstKind Class) {
      32           0 :   switch (Class) {
      33           0 :   case ARCInstKind::Retain:
      34           0 :     return OS << "ARCInstKind::Retain";
      35           0 :   case ARCInstKind::RetainRV:
      36           0 :     return OS << "ARCInstKind::RetainRV";
      37           0 :   case ARCInstKind::ClaimRV:
      38           0 :     return OS << "ARCInstKind::ClaimRV";
      39           0 :   case ARCInstKind::RetainBlock:
      40           0 :     return OS << "ARCInstKind::RetainBlock";
      41           0 :   case ARCInstKind::Release:
      42           0 :     return OS << "ARCInstKind::Release";
      43           0 :   case ARCInstKind::Autorelease:
      44           0 :     return OS << "ARCInstKind::Autorelease";
      45           0 :   case ARCInstKind::AutoreleaseRV:
      46           0 :     return OS << "ARCInstKind::AutoreleaseRV";
      47           0 :   case ARCInstKind::AutoreleasepoolPush:
      48           0 :     return OS << "ARCInstKind::AutoreleasepoolPush";
      49           0 :   case ARCInstKind::AutoreleasepoolPop:
      50           0 :     return OS << "ARCInstKind::AutoreleasepoolPop";
      51           0 :   case ARCInstKind::NoopCast:
      52           0 :     return OS << "ARCInstKind::NoopCast";
      53           0 :   case ARCInstKind::FusedRetainAutorelease:
      54           0 :     return OS << "ARCInstKind::FusedRetainAutorelease";
      55           0 :   case ARCInstKind::FusedRetainAutoreleaseRV:
      56           0 :     return OS << "ARCInstKind::FusedRetainAutoreleaseRV";
      57           0 :   case ARCInstKind::LoadWeakRetained:
      58           0 :     return OS << "ARCInstKind::LoadWeakRetained";
      59           0 :   case ARCInstKind::StoreWeak:
      60           0 :     return OS << "ARCInstKind::StoreWeak";
      61           0 :   case ARCInstKind::InitWeak:
      62           0 :     return OS << "ARCInstKind::InitWeak";
      63           0 :   case ARCInstKind::LoadWeak:
      64           0 :     return OS << "ARCInstKind::LoadWeak";
      65           0 :   case ARCInstKind::MoveWeak:
      66           0 :     return OS << "ARCInstKind::MoveWeak";
      67           0 :   case ARCInstKind::CopyWeak:
      68           0 :     return OS << "ARCInstKind::CopyWeak";
      69           0 :   case ARCInstKind::DestroyWeak:
      70           0 :     return OS << "ARCInstKind::DestroyWeak";
      71           0 :   case ARCInstKind::StoreStrong:
      72           0 :     return OS << "ARCInstKind::StoreStrong";
      73           0 :   case ARCInstKind::CallOrUser:
      74           0 :     return OS << "ARCInstKind::CallOrUser";
      75           0 :   case ARCInstKind::Call:
      76           0 :     return OS << "ARCInstKind::Call";
      77           0 :   case ARCInstKind::User:
      78           0 :     return OS << "ARCInstKind::User";
      79           0 :   case ARCInstKind::IntrinsicUser:
      80           0 :     return OS << "ARCInstKind::IntrinsicUser";
      81           0 :   case ARCInstKind::None:
      82           0 :     return OS << "ARCInstKind::None";
      83             :   }
      84           0 :   llvm_unreachable("Unknown instruction class!");
      85             : }
      86             : 
      87        9487 : ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) {
      88       18974 :   Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
      89             : 
      90             :   // No (mandatory) arguments.
      91        9487 :   if (AI == AE)
      92        1597 :     return StringSwitch<ARCInstKind>(F->getName())
      93        4791 :         .Case("objc_autoreleasePoolPush", ARCInstKind::AutoreleasepoolPush)
      94        4791 :         .Case("clang.arc.use", ARCInstKind::IntrinsicUser)
      95        3194 :         .Default(ARCInstKind::CallOrUser);
      96             : 
      97             :   // One argument.
      98        7890 :   const Argument *A0 = &*AI++;
      99        7890 :   if (AI == AE) {
     100             :     // Argument is a pointer.
     101       10643 :     PointerType *PTy = dyn_cast<PointerType>(A0->getType());
     102             :     if (!PTy)
     103             :       return ARCInstKind::CallOrUser;
     104             : 
     105        5313 :     Type *ETy = PTy->getElementType();
     106             :     // Argument is i8*.
     107        5313 :     if (ETy->isIntegerTy(8))
     108        4987 :       return StringSwitch<ARCInstKind>(F->getName())
     109       14961 :           .Case("objc_retain", ARCInstKind::Retain)
     110       14961 :           .Case("objc_retainAutoreleasedReturnValue", ARCInstKind::RetainRV)
     111       14961 :           .Case("objc_unsafeClaimAutoreleasedReturnValue", ARCInstKind::ClaimRV)
     112       14961 :           .Case("objc_retainBlock", ARCInstKind::RetainBlock)
     113       14961 :           .Case("objc_release", ARCInstKind::Release)
     114       14961 :           .Case("objc_autorelease", ARCInstKind::Autorelease)
     115       14961 :           .Case("objc_autoreleaseReturnValue", ARCInstKind::AutoreleaseRV)
     116       14961 :           .Case("objc_autoreleasePoolPop", ARCInstKind::AutoreleasepoolPop)
     117       14961 :           .Case("objc_retainedObject", ARCInstKind::NoopCast)
     118       14961 :           .Case("objc_unretainedObject", ARCInstKind::NoopCast)
     119       14961 :           .Case("objc_unretainedPointer", ARCInstKind::NoopCast)
     120       14961 :           .Case("objc_retain_autorelease", ARCInstKind::FusedRetainAutorelease)
     121       14961 :           .Case("objc_retainAutorelease", ARCInstKind::FusedRetainAutorelease)
     122             :           .Case("objc_retainAutoreleaseReturnValue",
     123       14961 :                 ARCInstKind::FusedRetainAutoreleaseRV)
     124       14961 :           .Case("objc_sync_enter", ARCInstKind::User)
     125       14961 :           .Case("objc_sync_exit", ARCInstKind::User)
     126        9974 :           .Default(ARCInstKind::CallOrUser);
     127             : 
     128             :     // Argument is i8**
     129         235 :     if (PointerType *Pte = dyn_cast<PointerType>(ETy))
     130         235 :       if (Pte->getElementType()->isIntegerTy(8))
     131         221 :         return StringSwitch<ARCInstKind>(F->getName())
     132         663 :             .Case("objc_loadWeakRetained", ARCInstKind::LoadWeakRetained)
     133         663 :             .Case("objc_loadWeak", ARCInstKind::LoadWeak)
     134         663 :             .Case("objc_destroyWeak", ARCInstKind::DestroyWeak)
     135         442 :             .Default(ARCInstKind::CallOrUser);
     136             : 
     137             :     // Anything else with one argument.
     138             :     return ARCInstKind::CallOrUser;
     139             :   }
     140             : 
     141             :   // Two arguments, first is i8**.
     142        2560 :   const Argument *A1 = &*AI++;
     143        2560 :   if (AI == AE)
     144        4716 :     if (PointerType *PTy = dyn_cast<PointerType>(A0->getType()))
     145        2497 :       if (PointerType *Pte = dyn_cast<PointerType>(PTy->getElementType()))
     146         163 :         if (Pte->getElementType()->isIntegerTy(8))
     147         326 :           if (PointerType *PTy1 = dyn_cast<PointerType>(A1->getType())) {
     148         163 :             Type *ETy1 = PTy1->getElementType();
     149             :             // Second argument is i8*
     150         163 :             if (ETy1->isIntegerTy(8))
     151         125 :               return StringSwitch<ARCInstKind>(F->getName())
     152         375 :                   .Case("objc_storeWeak", ARCInstKind::StoreWeak)
     153         375 :                   .Case("objc_initWeak", ARCInstKind::InitWeak)
     154         375 :                   .Case("objc_storeStrong", ARCInstKind::StoreStrong)
     155         250 :                   .Default(ARCInstKind::CallOrUser);
     156             :             // Second argument is i8**.
     157          38 :             if (PointerType *Pte1 = dyn_cast<PointerType>(ETy1))
     158          38 :               if (Pte1->getElementType()->isIntegerTy(8))
     159          38 :                 return StringSwitch<ARCInstKind>(F->getName())
     160         114 :                     .Case("objc_moveWeak", ARCInstKind::MoveWeak)
     161         114 :                     .Case("objc_copyWeak", ARCInstKind::CopyWeak)
     162             :                     // Ignore annotation calls. This is important to stop the
     163             :                     // optimizer from treating annotations as uses which would
     164             :                     // make the state of the pointers they are attempting to
     165             :                     // elucidate to be incorrect.
     166             :                     .Case("llvm.arc.annotation.topdown.bbstart",
     167         114 :                           ARCInstKind::None)
     168             :                     .Case("llvm.arc.annotation.topdown.bbend",
     169         114 :                           ARCInstKind::None)
     170             :                     .Case("llvm.arc.annotation.bottomup.bbstart",
     171         114 :                           ARCInstKind::None)
     172             :                     .Case("llvm.arc.annotation.bottomup.bbend",
     173         114 :                           ARCInstKind::None)
     174          76 :                     .Default(ARCInstKind::CallOrUser);
     175             :           }
     176             : 
     177             :   // Anything else.
     178             :   return ARCInstKind::CallOrUser;
     179             : }
     180             : 
     181             : // A whitelist of intrinsics that we know do not use objc pointers or decrement
     182             : // ref counts.
     183         649 : static bool isInertIntrinsic(unsigned ID) {
     184             :   // TODO: Make this into a covered switch.
     185         649 :   switch (ID) {
     186             :   case Intrinsic::returnaddress:
     187             :   case Intrinsic::addressofreturnaddress:
     188             :   case Intrinsic::frameaddress:
     189             :   case Intrinsic::stacksave:
     190             :   case Intrinsic::stackrestore:
     191             :   case Intrinsic::vastart:
     192             :   case Intrinsic::vacopy:
     193             :   case Intrinsic::vaend:
     194             :   case Intrinsic::objectsize:
     195             :   case Intrinsic::prefetch:
     196             :   case Intrinsic::stackprotector:
     197             :   case Intrinsic::eh_return_i32:
     198             :   case Intrinsic::eh_return_i64:
     199             :   case Intrinsic::eh_typeid_for:
     200             :   case Intrinsic::eh_dwarf_cfa:
     201             :   case Intrinsic::eh_sjlj_lsda:
     202             :   case Intrinsic::eh_sjlj_functioncontext:
     203             :   case Intrinsic::init_trampoline:
     204             :   case Intrinsic::adjust_trampoline:
     205             :   case Intrinsic::lifetime_start:
     206             :   case Intrinsic::lifetime_end:
     207             :   case Intrinsic::invariant_start:
     208             :   case Intrinsic::invariant_end:
     209             :   // Don't let dbg info affect our results.
     210             :   case Intrinsic::dbg_declare:
     211             :   case Intrinsic::dbg_value:
     212             :     // Short cut: Some intrinsics obviously don't use ObjC pointers.
     213             :     return true;
     214         629 :   default:
     215         629 :     return false;
     216             :   }
     217             : }
     218             : 
     219             : // A whitelist of intrinsics that we know do not use objc pointers or decrement
     220             : // ref counts.
     221             : static bool isUseOnlyIntrinsic(unsigned ID) {
     222             :   // We are conservative and even though intrinsics are unlikely to touch
     223             :   // reference counts, we white list them for safety.
     224             :   //
     225             :   // TODO: Expand this into a covered switch. There is a lot more here.
     226             :   switch (ID) {
     227             :   case Intrinsic::memcpy:
     228             :   case Intrinsic::memmove:
     229             :   case Intrinsic::memset:
     230             :     return true;
     231             :   default:
     232             :     return false;
     233             :   }
     234             : }
     235             : 
     236             : /// \brief Determine what kind of construct V is.
     237        7542 : ARCInstKind llvm::objcarc::GetARCInstKind(const Value *V) {
     238        7542 :   if (const Instruction *I = dyn_cast<Instruction>(V)) {
     239             :     // Any instruction other than bitcast and gep with a pointer operand have a
     240             :     // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer
     241             :     // to a subsequent use, rather than using it themselves, in this sense.
     242             :     // As a short cut, several other opcodes are known to have no pointer
     243             :     // operands of interest. And ret is never followed by a release, so it's
     244             :     // not interesting to examine.
     245        7542 :     switch (I->getOpcode()) {
     246        2183 :     case Instruction::Call: {
     247        2183 :       const CallInst *CI = cast<CallInst>(I);
     248             :       // See if we have a function that we know something about.
     249        2059 :       if (const Function *F = CI->getCalledFunction()) {
     250        2059 :         ARCInstKind Class = GetFunctionClass(F);
     251        2059 :         if (Class != ARCInstKind::CallOrUser)
     252             :           return Class;
     253         649 :         Intrinsic::ID ID = F->getIntrinsicID();
     254         649 :         if (isInertIntrinsic(ID))
     255             :           return ARCInstKind::None;
     256             :         if (isUseOnlyIntrinsic(ID))
     257             :           return ARCInstKind::User;
     258             :       }
     259             : 
     260             :       // Otherwise, be conservative.
     261         711 :       return GetCallSiteClass(CI);
     262             :     }
     263         363 :     case Instruction::Invoke:
     264             :       // Otherwise, be conservative.
     265         726 :       return GetCallSiteClass(cast<InvokeInst>(I));
     266             :     case Instruction::BitCast:
     267             :     case Instruction::GetElementPtr:
     268             :     case Instruction::Select:
     269             :     case Instruction::PHI:
     270             :     case Instruction::Ret:
     271             :     case Instruction::Br:
     272             :     case Instruction::Switch:
     273             :     case Instruction::IndirectBr:
     274             :     case Instruction::Alloca:
     275             :     case Instruction::VAArg:
     276             :     case Instruction::Add:
     277             :     case Instruction::FAdd:
     278             :     case Instruction::Sub:
     279             :     case Instruction::FSub:
     280             :     case Instruction::Mul:
     281             :     case Instruction::FMul:
     282             :     case Instruction::SDiv:
     283             :     case Instruction::UDiv:
     284             :     case Instruction::FDiv:
     285             :     case Instruction::SRem:
     286             :     case Instruction::URem:
     287             :     case Instruction::FRem:
     288             :     case Instruction::Shl:
     289             :     case Instruction::LShr:
     290             :     case Instruction::AShr:
     291             :     case Instruction::And:
     292             :     case Instruction::Or:
     293             :     case Instruction::Xor:
     294             :     case Instruction::SExt:
     295             :     case Instruction::ZExt:
     296             :     case Instruction::Trunc:
     297             :     case Instruction::IntToPtr:
     298             :     case Instruction::FCmp:
     299             :     case Instruction::FPTrunc:
     300             :     case Instruction::FPExt:
     301             :     case Instruction::FPToUI:
     302             :     case Instruction::FPToSI:
     303             :     case Instruction::UIToFP:
     304             :     case Instruction::SIToFP:
     305             :     case Instruction::InsertElement:
     306             :     case Instruction::ExtractElement:
     307             :     case Instruction::ShuffleVector:
     308             :     case Instruction::ExtractValue:
     309             :       break;
     310         263 :     case Instruction::ICmp:
     311             :       // Comparing a pointer with null, or any other constant, isn't an
     312             :       // interesting use, because we don't care what the pointer points to, or
     313             :       // about the values of any other dynamic reference-counted pointers.
     314         526 :       if (IsPotentialRetainableObjPtr(I->getOperand(1)))
     315             :         return ARCInstKind::User;
     316             :       break;
     317        1311 :     default:
     318             :       // For anything else, check all the operands.
     319             :       // Note that this includes both operands of a Store: while the first
     320             :       // operand isn't actually being dereferenced, it is being stored to
     321             :       // memory where we can no longer track who might read it and dereference
     322             :       // it, so we have to consider it potentially used.
     323        4475 :       for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end();
     324        1853 :            OI != OE; ++OI)
     325        1249 :         if (IsPotentialRetainableObjPtr(*OI))
     326         604 :           return ARCInstKind::User;
     327             :     }
     328             :   }
     329             : 
     330             :   // Otherwise, it's totally inert for ARC purposes.
     331             :   return ARCInstKind::None;
     332             : }
     333             : 
     334             : /// \brief Test if the given class is a kind of user.
     335          43 : bool llvm::objcarc::IsUser(ARCInstKind Class) {
     336             :   switch (Class) {
     337             :   case ARCInstKind::User:
     338             :   case ARCInstKind::CallOrUser:
     339             :   case ARCInstKind::IntrinsicUser:
     340             :     return true;
     341             :   case ARCInstKind::Retain:
     342             :   case ARCInstKind::RetainRV:
     343             :   case ARCInstKind::RetainBlock:
     344             :   case ARCInstKind::Release:
     345             :   case ARCInstKind::Autorelease:
     346             :   case ARCInstKind::AutoreleaseRV:
     347             :   case ARCInstKind::AutoreleasepoolPush:
     348             :   case ARCInstKind::AutoreleasepoolPop:
     349             :   case ARCInstKind::NoopCast:
     350             :   case ARCInstKind::FusedRetainAutorelease:
     351             :   case ARCInstKind::FusedRetainAutoreleaseRV:
     352             :   case ARCInstKind::LoadWeakRetained:
     353             :   case ARCInstKind::StoreWeak:
     354             :   case ARCInstKind::InitWeak:
     355             :   case ARCInstKind::LoadWeak:
     356             :   case ARCInstKind::MoveWeak:
     357             :   case ARCInstKind::CopyWeak:
     358             :   case ARCInstKind::DestroyWeak:
     359             :   case ARCInstKind::StoreStrong:
     360             :   case ARCInstKind::Call:
     361             :   case ARCInstKind::None:
     362             :   case ARCInstKind::ClaimRV:
     363             :     return false;
     364             :   }
     365           0 :   llvm_unreachable("covered switch isn't covered?");
     366             : }
     367             : 
     368             : /// \brief Test if the given class is objc_retain or equivalent.
     369          43 : bool llvm::objcarc::IsRetain(ARCInstKind Class) {
     370          43 :   switch (Class) {
     371             :   case ARCInstKind::Retain:
     372             :   case ARCInstKind::RetainRV:
     373             :     return true;
     374             :   // I believe we treat retain block as not a retain since it can copy its
     375             :   // block.
     376          30 :   case ARCInstKind::RetainBlock:
     377             :   case ARCInstKind::Release:
     378             :   case ARCInstKind::Autorelease:
     379             :   case ARCInstKind::AutoreleaseRV:
     380             :   case ARCInstKind::AutoreleasepoolPush:
     381             :   case ARCInstKind::AutoreleasepoolPop:
     382             :   case ARCInstKind::NoopCast:
     383             :   case ARCInstKind::FusedRetainAutorelease:
     384             :   case ARCInstKind::FusedRetainAutoreleaseRV:
     385             :   case ARCInstKind::LoadWeakRetained:
     386             :   case ARCInstKind::StoreWeak:
     387             :   case ARCInstKind::InitWeak:
     388             :   case ARCInstKind::LoadWeak:
     389             :   case ARCInstKind::MoveWeak:
     390             :   case ARCInstKind::CopyWeak:
     391             :   case ARCInstKind::DestroyWeak:
     392             :   case ARCInstKind::StoreStrong:
     393             :   case ARCInstKind::IntrinsicUser:
     394             :   case ARCInstKind::CallOrUser:
     395             :   case ARCInstKind::Call:
     396             :   case ARCInstKind::User:
     397             :   case ARCInstKind::None:
     398             :   case ARCInstKind::ClaimRV:
     399          30 :     return false;
     400             :   }
     401           0 :   llvm_unreachable("covered switch isn't covered?");
     402             : }
     403             : 
     404             : /// \brief Test if the given class is objc_autorelease or equivalent.
     405        3691 : bool llvm::objcarc::IsAutorelease(ARCInstKind Class) {
     406             :   switch (Class) {
     407             :   case ARCInstKind::Autorelease:
     408             :   case ARCInstKind::AutoreleaseRV:
     409             :     return true;
     410             :   case ARCInstKind::Retain:
     411             :   case ARCInstKind::RetainRV:
     412             :   case ARCInstKind::ClaimRV:
     413             :   case ARCInstKind::RetainBlock:
     414             :   case ARCInstKind::Release:
     415             :   case ARCInstKind::AutoreleasepoolPush:
     416             :   case ARCInstKind::AutoreleasepoolPop:
     417             :   case ARCInstKind::NoopCast:
     418             :   case ARCInstKind::FusedRetainAutorelease:
     419             :   case ARCInstKind::FusedRetainAutoreleaseRV:
     420             :   case ARCInstKind::LoadWeakRetained:
     421             :   case ARCInstKind::StoreWeak:
     422             :   case ARCInstKind::InitWeak:
     423             :   case ARCInstKind::LoadWeak:
     424             :   case ARCInstKind::MoveWeak:
     425             :   case ARCInstKind::CopyWeak:
     426             :   case ARCInstKind::DestroyWeak:
     427             :   case ARCInstKind::StoreStrong:
     428             :   case ARCInstKind::IntrinsicUser:
     429             :   case ARCInstKind::CallOrUser:
     430             :   case ARCInstKind::Call:
     431             :   case ARCInstKind::User:
     432             :   case ARCInstKind::None:
     433             :     return false;
     434             :   }
     435           0 :   llvm_unreachable("covered switch isn't covered?");
     436             : }
     437             : 
     438             : /// \brief Test if the given class represents instructions which return their
     439             : /// argument verbatim.
     440       13442 : bool llvm::objcarc::IsForwarding(ARCInstKind Class) {
     441             :   switch (Class) {
     442             :   case ARCInstKind::Retain:
     443             :   case ARCInstKind::RetainRV:
     444             :   case ARCInstKind::ClaimRV:
     445             :   case ARCInstKind::Autorelease:
     446             :   case ARCInstKind::AutoreleaseRV:
     447             :   case ARCInstKind::NoopCast:
     448             :     return true;
     449             :   case ARCInstKind::RetainBlock:
     450             :   case ARCInstKind::Release:
     451             :   case ARCInstKind::AutoreleasepoolPush:
     452             :   case ARCInstKind::AutoreleasepoolPop:
     453             :   case ARCInstKind::FusedRetainAutorelease:
     454             :   case ARCInstKind::FusedRetainAutoreleaseRV:
     455             :   case ARCInstKind::LoadWeakRetained:
     456             :   case ARCInstKind::StoreWeak:
     457             :   case ARCInstKind::InitWeak:
     458             :   case ARCInstKind::LoadWeak:
     459             :   case ARCInstKind::MoveWeak:
     460             :   case ARCInstKind::CopyWeak:
     461             :   case ARCInstKind::DestroyWeak:
     462             :   case ARCInstKind::StoreStrong:
     463             :   case ARCInstKind::IntrinsicUser:
     464             :   case ARCInstKind::CallOrUser:
     465             :   case ARCInstKind::Call:
     466             :   case ARCInstKind::User:
     467             :   case ARCInstKind::None:
     468             :     return false;
     469             :   }
     470           0 :   llvm_unreachable("covered switch isn't covered?");
     471             : }
     472             : 
     473             : /// \brief Test if the given class represents instructions which do nothing if
     474             : /// passed a null pointer.
     475        3664 : bool llvm::objcarc::IsNoopOnNull(ARCInstKind Class) {
     476        3664 :   switch (Class) {
     477             :   case ARCInstKind::Retain:
     478             :   case ARCInstKind::RetainRV:
     479             :   case ARCInstKind::ClaimRV:
     480             :   case ARCInstKind::Release:
     481             :   case ARCInstKind::Autorelease:
     482             :   case ARCInstKind::AutoreleaseRV:
     483             :   case ARCInstKind::RetainBlock:
     484             :     return true;
     485        2977 :   case ARCInstKind::AutoreleasepoolPush:
     486             :   case ARCInstKind::AutoreleasepoolPop:
     487             :   case ARCInstKind::FusedRetainAutorelease:
     488             :   case ARCInstKind::FusedRetainAutoreleaseRV:
     489             :   case ARCInstKind::LoadWeakRetained:
     490             :   case ARCInstKind::StoreWeak:
     491             :   case ARCInstKind::InitWeak:
     492             :   case ARCInstKind::LoadWeak:
     493             :   case ARCInstKind::MoveWeak:
     494             :   case ARCInstKind::CopyWeak:
     495             :   case ARCInstKind::DestroyWeak:
     496             :   case ARCInstKind::StoreStrong:
     497             :   case ARCInstKind::IntrinsicUser:
     498             :   case ARCInstKind::CallOrUser:
     499             :   case ARCInstKind::Call:
     500             :   case ARCInstKind::User:
     501             :   case ARCInstKind::None:
     502             :   case ARCInstKind::NoopCast:
     503        2977 :     return false;
     504             :   }
     505           0 :   llvm_unreachable("covered switch isn't covered?");
     506             : }
     507             : 
     508             : /// \brief Test if the given class represents instructions which are always safe
     509             : /// to mark with the "tail" keyword.
     510        3664 : bool llvm::objcarc::IsAlwaysTail(ARCInstKind Class) {
     511             :   // ARCInstKind::RetainBlock may be given a stack argument.
     512             :   switch (Class) {
     513             :   case ARCInstKind::Retain:
     514             :   case ARCInstKind::RetainRV:
     515             :   case ARCInstKind::ClaimRV:
     516             :   case ARCInstKind::AutoreleaseRV:
     517             :     return true;
     518             :   case ARCInstKind::Release:
     519             :   case ARCInstKind::Autorelease:
     520             :   case ARCInstKind::RetainBlock:
     521             :   case ARCInstKind::AutoreleasepoolPush:
     522             :   case ARCInstKind::AutoreleasepoolPop:
     523             :   case ARCInstKind::FusedRetainAutorelease:
     524             :   case ARCInstKind::FusedRetainAutoreleaseRV:
     525             :   case ARCInstKind::LoadWeakRetained:
     526             :   case ARCInstKind::StoreWeak:
     527             :   case ARCInstKind::InitWeak:
     528             :   case ARCInstKind::LoadWeak:
     529             :   case ARCInstKind::MoveWeak:
     530             :   case ARCInstKind::CopyWeak:
     531             :   case ARCInstKind::DestroyWeak:
     532             :   case ARCInstKind::StoreStrong:
     533             :   case ARCInstKind::IntrinsicUser:
     534             :   case ARCInstKind::CallOrUser:
     535             :   case ARCInstKind::Call:
     536             :   case ARCInstKind::User:
     537             :   case ARCInstKind::None:
     538             :   case ARCInstKind::NoopCast:
     539             :     return false;
     540             :   }
     541           0 :   llvm_unreachable("covered switch isn't covered?");
     542             : }
     543             : 
     544             : /// \brief Test if the given class represents instructions which are never safe
     545             : /// to mark with the "tail" keyword.
     546        3664 : bool llvm::objcarc::IsNeverTail(ARCInstKind Class) {
     547             :   /// It is never safe to tail call objc_autorelease since by tail calling
     548             :   /// objc_autorelease: fast autoreleasing causing our object to be potentially
     549             :   /// reclaimed from the autorelease pool which violates the semantics of
     550             :   /// __autoreleasing types in ARC.
     551             :   switch (Class) {
     552             :   case ARCInstKind::Autorelease:
     553             :     return true;
     554             :   case ARCInstKind::Retain:
     555             :   case ARCInstKind::RetainRV:
     556             :   case ARCInstKind::ClaimRV:
     557             :   case ARCInstKind::AutoreleaseRV:
     558             :   case ARCInstKind::Release:
     559             :   case ARCInstKind::RetainBlock:
     560             :   case ARCInstKind::AutoreleasepoolPush:
     561             :   case ARCInstKind::AutoreleasepoolPop:
     562             :   case ARCInstKind::FusedRetainAutorelease:
     563             :   case ARCInstKind::FusedRetainAutoreleaseRV:
     564             :   case ARCInstKind::LoadWeakRetained:
     565             :   case ARCInstKind::StoreWeak:
     566             :   case ARCInstKind::InitWeak:
     567             :   case ARCInstKind::LoadWeak:
     568             :   case ARCInstKind::MoveWeak:
     569             :   case ARCInstKind::CopyWeak:
     570             :   case ARCInstKind::DestroyWeak:
     571             :   case ARCInstKind::StoreStrong:
     572             :   case ARCInstKind::IntrinsicUser:
     573             :   case ARCInstKind::CallOrUser:
     574             :   case ARCInstKind::Call:
     575             :   case ARCInstKind::User:
     576             :   case ARCInstKind::None:
     577             :   case ARCInstKind::NoopCast:
     578             :     return false;
     579             :   }
     580           0 :   llvm_unreachable("covered switch isn't covered?");
     581             : }
     582             : 
     583             : /// \brief Test if the given class represents instructions which are always safe
     584             : /// to mark with the nounwind attribute.
     585        3664 : bool llvm::objcarc::IsNoThrow(ARCInstKind Class) {
     586             :   // objc_retainBlock is not nounwind because it calls user copy constructors
     587             :   // which could theoretically throw.
     588             :   switch (Class) {
     589             :   case ARCInstKind::Retain:
     590             :   case ARCInstKind::RetainRV:
     591             :   case ARCInstKind::ClaimRV:
     592             :   case ARCInstKind::Release:
     593             :   case ARCInstKind::Autorelease:
     594             :   case ARCInstKind::AutoreleaseRV:
     595             :   case ARCInstKind::AutoreleasepoolPush:
     596             :   case ARCInstKind::AutoreleasepoolPop:
     597             :     return true;
     598             :   case ARCInstKind::RetainBlock:
     599             :   case ARCInstKind::FusedRetainAutorelease:
     600             :   case ARCInstKind::FusedRetainAutoreleaseRV:
     601             :   case ARCInstKind::LoadWeakRetained:
     602             :   case ARCInstKind::StoreWeak:
     603             :   case ARCInstKind::InitWeak:
     604             :   case ARCInstKind::LoadWeak:
     605             :   case ARCInstKind::MoveWeak:
     606             :   case ARCInstKind::CopyWeak:
     607             :   case ARCInstKind::DestroyWeak:
     608             :   case ARCInstKind::StoreStrong:
     609             :   case ARCInstKind::IntrinsicUser:
     610             :   case ARCInstKind::CallOrUser:
     611             :   case ARCInstKind::Call:
     612             :   case ARCInstKind::User:
     613             :   case ARCInstKind::None:
     614             :   case ARCInstKind::NoopCast:
     615             :     return false;
     616             :   }
     617           0 :   llvm_unreachable("covered switch isn't covered?");
     618             : }
     619             : 
     620             : /// Test whether the given instruction can autorelease any pointer or cause an
     621             : /// autoreleasepool pop.
     622             : ///
     623             : /// This means that it *could* interrupt the RV optimization.
     624           3 : bool llvm::objcarc::CanInterruptRV(ARCInstKind Class) {
     625             :   switch (Class) {
     626             :   case ARCInstKind::AutoreleasepoolPop:
     627             :   case ARCInstKind::CallOrUser:
     628             :   case ARCInstKind::Call:
     629             :   case ARCInstKind::Autorelease:
     630             :   case ARCInstKind::AutoreleaseRV:
     631             :   case ARCInstKind::FusedRetainAutorelease:
     632             :   case ARCInstKind::FusedRetainAutoreleaseRV:
     633             :     return true;
     634             :   case ARCInstKind::Retain:
     635             :   case ARCInstKind::RetainRV:
     636             :   case ARCInstKind::ClaimRV:
     637             :   case ARCInstKind::Release:
     638             :   case ARCInstKind::AutoreleasepoolPush:
     639             :   case ARCInstKind::RetainBlock:
     640             :   case ARCInstKind::LoadWeakRetained:
     641             :   case ARCInstKind::StoreWeak:
     642             :   case ARCInstKind::InitWeak:
     643             :   case ARCInstKind::LoadWeak:
     644             :   case ARCInstKind::MoveWeak:
     645             :   case ARCInstKind::CopyWeak:
     646             :   case ARCInstKind::DestroyWeak:
     647             :   case ARCInstKind::StoreStrong:
     648             :   case ARCInstKind::IntrinsicUser:
     649             :   case ARCInstKind::User:
     650             :   case ARCInstKind::None:
     651             :   case ARCInstKind::NoopCast:
     652             :     return false;
     653             :   }
     654           0 :   llvm_unreachable("covered switch isn't covered?");
     655             : }
     656             : 
     657          35 : bool llvm::objcarc::CanDecrementRefCount(ARCInstKind Kind) {
     658             :   switch (Kind) {
     659             :   case ARCInstKind::Retain:
     660             :   case ARCInstKind::RetainRV:
     661             :   case ARCInstKind::Autorelease:
     662             :   case ARCInstKind::AutoreleaseRV:
     663             :   case ARCInstKind::NoopCast:
     664             :   case ARCInstKind::FusedRetainAutorelease:
     665             :   case ARCInstKind::FusedRetainAutoreleaseRV:
     666             :   case ARCInstKind::IntrinsicUser:
     667             :   case ARCInstKind::User:
     668             :   case ARCInstKind::None:
     669             :     return false;
     670             : 
     671             :   // The cases below are conservative.
     672             : 
     673             :   // RetainBlock can result in user defined copy constructors being called
     674             :   // implying releases may occur.
     675             :   case ARCInstKind::RetainBlock:
     676             :   case ARCInstKind::Release:
     677             :   case ARCInstKind::AutoreleasepoolPush:
     678             :   case ARCInstKind::AutoreleasepoolPop:
     679             :   case ARCInstKind::LoadWeakRetained:
     680             :   case ARCInstKind::StoreWeak:
     681             :   case ARCInstKind::InitWeak:
     682             :   case ARCInstKind::LoadWeak:
     683             :   case ARCInstKind::MoveWeak:
     684             :   case ARCInstKind::CopyWeak:
     685             :   case ARCInstKind::DestroyWeak:
     686             :   case ARCInstKind::StoreStrong:
     687             :   case ARCInstKind::CallOrUser:
     688             :   case ARCInstKind::Call:
     689             :   case ARCInstKind::ClaimRV:
     690             :     return true;
     691             :   }
     692             : 
     693           0 :   llvm_unreachable("covered switch isn't covered?");
     694             : }

Generated by: LCOV version 1.13