brintos

brintos / llvm-project-archived public Read only

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