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 38namespace llvm { 39class raw_ostream; 40} 41 42namespace llvm { 43namespace 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/// 51static 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. 73static 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. 85template<class PHINodeTy, class VectorTy> 86void 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