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/ADT/StringSwitch.h" 26 #include "llvm/Analysis/AliasAnalysis.h" 27 #include "llvm/Analysis/ObjCARCAnalysisUtils.h" 28 #include "llvm/Analysis/ObjCARCInstKind.h" 29 #include "llvm/Analysis/Passes.h" 30 #include "llvm/Transforms/Utils/Local.h" 31 #include "llvm/Analysis/ValueTracking.h" 32 #include "llvm/IR/CallSite.h" 33 #include "llvm/IR/InstIterator.h" 34 #include "llvm/IR/Module.h" 35 #include "llvm/Pass.h" 36 #include "llvm/Transforms/ObjCARC.h" 37 38 namespace llvm { 39 class raw_ostream; 40 } 41 42 namespace llvm { 43 namespace objcarc { 44 45 /// Erase the given instruction. 46 /// 47 /// Many ObjC calls return their argument verbatim, 48 /// so if it's such a call and the return value has users, replace them with the 49 /// argument value. 50 /// 51 static inline void EraseInstruction(Instruction *CI) { 52 Value *OldArg = cast<CallInst>(CI)->getArgOperand(0); 53 54 bool Unused = CI->use_empty(); 55 56 if (!Unused) { 57 // Replace the return value with the argument. 58 assert((IsForwarding(GetBasicARCInstKind(CI)) || 59 (IsNoopOnNull(GetBasicARCInstKind(CI)) && 60 IsNullOrUndef(OldArg->stripPointerCasts()))) && 61 "Can't delete non-forwarding instruction with users!"); 62 CI->replaceAllUsesWith(OldArg); 63 } 64 65 CI->eraseFromParent(); 66 67 if (Unused) 68 RecursivelyDeleteTriviallyDeadInstructions(OldArg); 69 } 70 71 /// If Inst is a ReturnRV and its operand is a call or invoke, return the 72 /// operand. Otherwise return null. 73 static inline const Instruction *getreturnRVOperand(const Instruction &Inst, 74 ARCInstKind Class) { 75 if (Class != ARCInstKind::RetainRV) 76 return nullptr; 77 78 const auto *Opnd = Inst.getOperand(0)->stripPointerCasts(); 79 if (const auto *C = dyn_cast<CallInst>(Opnd)) 80 return C; 81 return dyn_cast<InvokeInst>(Opnd); 82 } 83 84 /// Return the list of PHI nodes that are equivalent to PN. 85 template<class PHINodeTy, class VectorTy> 86 void getEquivalentPHIs(PHINodeTy &PN, VectorTy &PHIList) { 87 auto *BB = PN.getParent(); 88 for (auto &P : BB->phis()) { 89 if (&P == &PN) // Do not add PN to the list. 90 continue; 91 unsigned I = 0, E = PN.getNumIncomingValues(); 92 for (; I < E; ++I) { 93 auto *BB = PN.getIncomingBlock(I); 94 auto *PNOpnd = PN.getIncomingValue(I)->stripPointerCasts(); 95 auto *POpnd = P.getIncomingValueForBlock(BB)->stripPointerCasts(); 96 if (PNOpnd != POpnd) 97 break; 98 } 99 if (I == E) 100 PHIList.push_back(&P); 101 } 102 } 103 104 } // end namespace objcarc 105 } // end namespace llvm 106 107 #endif 108