1 //===- ObjCARC.h - ObjC ARC Optimization --------------*- C++ -*-----------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file defines common definitions/declarations used by the ObjC ARC 10 /// Optimizer. ARC stands for Automatic Reference Counting and is a system for 11 /// managing reference counts for objects in Objective C. 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 #ifndef LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H 23 #define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H 24 25 #include "llvm/Analysis/ObjCARCAnalysisUtils.h" 26 #include "llvm/Transforms/Utils/Local.h" 27 28 namespace llvm { 29 namespace objcarc { 30 31 /// Erase the given instruction. 32 /// 33 /// Many ObjC calls return their argument verbatim, 34 /// so if it's such a call and the return value has users, replace them with the 35 /// argument value. 36 /// 37 static inline void EraseInstruction(Instruction *CI) { 38 Value *OldArg = cast<CallInst>(CI)->getArgOperand(0); 39 40 bool Unused = CI->use_empty(); 41 42 if (!Unused) { 43 // Replace the return value with the argument. 44 assert((IsForwarding(GetBasicARCInstKind(CI)) || 45 (IsNoopOnNull(GetBasicARCInstKind(CI)) && 46 IsNullOrUndef(OldArg->stripPointerCasts()))) && 47 "Can't delete non-forwarding instruction with users!"); 48 CI->replaceAllUsesWith(OldArg); 49 } 50 51 CI->eraseFromParent(); 52 53 if (Unused) 54 RecursivelyDeleteTriviallyDeadInstructions(OldArg); 55 } 56 57 /// If Inst is a ReturnRV and its operand is a call or invoke, return the 58 /// operand. Otherwise return null. 59 static inline const Instruction *getreturnRVOperand(const Instruction &Inst, 60 ARCInstKind Class) { 61 if (Class != ARCInstKind::RetainRV) 62 return nullptr; 63 64 const auto *Opnd = Inst.getOperand(0)->stripPointerCasts(); 65 if (const auto *C = dyn_cast<CallInst>(Opnd)) 66 return C; 67 return dyn_cast<InvokeInst>(Opnd); 68 } 69 70 /// Return the list of PHI nodes that are equivalent to PN. 71 template<class PHINodeTy, class VectorTy> 72 void getEquivalentPHIs(PHINodeTy &PN, VectorTy &PHIList) { 73 auto *BB = PN.getParent(); 74 for (auto &P : BB->phis()) { 75 if (&P == &PN) // Do not add PN to the list. 76 continue; 77 unsigned I = 0, E = PN.getNumIncomingValues(); 78 for (; I < E; ++I) { 79 auto *BB = PN.getIncomingBlock(I); 80 auto *PNOpnd = PN.getIncomingValue(I)->stripPointerCasts(); 81 auto *POpnd = P.getIncomingValueForBlock(BB)->stripPointerCasts(); 82 if (PNOpnd != POpnd) 83 break; 84 } 85 if (I == E) 86 PHIList.push_back(&P); 87 } 88 } 89 90 } // end namespace objcarc 91 } // end namespace llvm 92 93 #endif 94