| Michael Gottesman | 6eb95dc | 2013-07-10 18:49:00 +0000 | [diff] [blame] | 1 | //===- ObjCARC.h - ObjC ARC Optimization --------------*- C++ -*-----------===// | 
| Michael Gottesman | 08904e3 | 2013-01-28 03:28:38 +0000 | [diff] [blame] | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 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 | 
| Michael Gottesman | 08904e3 | 2013-01-28 03:28:38 +0000 | [diff] [blame] | 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 |  | 
| Benjamin Kramer | a7c40ef | 2014-08-13 16:26:38 +0000 | [diff] [blame] | 22 | #ifndef LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H | 
|  | 23 | #define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H | 
| Michael Gottesman | 08904e3 | 2013-01-28 03:28:38 +0000 | [diff] [blame] | 24 |  | 
|  | 25 | #include "llvm/ADT/StringSwitch.h" | 
|  | 26 | #include "llvm/Analysis/AliasAnalysis.h" | 
| Chandler Carruth | 0f79218 | 2015-08-20 08:06:03 +0000 | [diff] [blame] | 27 | #include "llvm/Analysis/ObjCARCAnalysisUtils.h" | 
|  | 28 | #include "llvm/Analysis/ObjCARCInstKind.h" | 
| Michael Gottesman | 08904e3 | 2013-01-28 03:28:38 +0000 | [diff] [blame] | 29 | #include "llvm/Analysis/Passes.h" | 
| David Blaikie | 31b98d2 | 2018-06-04 21:23:21 +0000 | [diff] [blame] | 30 | #include "llvm/Transforms/Utils/Local.h" | 
| Michael Gottesman | 294e7da | 2013-01-28 05:51:54 +0000 | [diff] [blame] | 31 | #include "llvm/Analysis/ValueTracking.h" | 
| Chandler Carruth | 219b89b | 2014-03-04 11:01:28 +0000 | [diff] [blame] | 32 | #include "llvm/IR/CallSite.h" | 
| Chandler Carruth | 8394857 | 2014-03-04 10:30:26 +0000 | [diff] [blame] | 33 | #include "llvm/IR/InstIterator.h" | 
| Michael Gottesman | 08904e3 | 2013-01-28 03:28:38 +0000 | [diff] [blame] | 34 | #include "llvm/IR/Module.h" | 
|  | 35 | #include "llvm/Pass.h" | 
| Michael Gottesman | 08904e3 | 2013-01-28 03:28:38 +0000 | [diff] [blame] | 36 | #include "llvm/Transforms/ObjCARC.h" | 
|  | 37 |  | 
|  | 38 | namespace llvm { | 
| Michael Gottesman | 13a5f1a | 2013-01-29 04:51:59 +0000 | [diff] [blame] | 39 | class raw_ostream; | 
|  | 40 | } | 
|  | 41 |  | 
|  | 42 | namespace llvm { | 
| Michael Gottesman | 08904e3 | 2013-01-28 03:28:38 +0000 | [diff] [blame] | 43 | namespace objcarc { | 
|  | 44 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 45 | /// Erase the given instruction. | 
| Michael Gottesman | 778138e | 2013-01-29 03:03:03 +0000 | [diff] [blame] | 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. | 
| Michael Gottesman | 6f729fa | 2015-02-19 19:51:32 +0000 | [diff] [blame] | 58 | assert((IsForwarding(GetBasicARCInstKind(CI)) || | 
|  | 59 | (IsNoopOnNull(GetBasicARCInstKind(CI)) && | 
| Pete Cooper | 8d58048 | 2019-01-02 21:00:02 +0000 | [diff] [blame] | 60 | IsNullOrUndef(OldArg->stripPointerCasts()))) && | 
| Michael Gottesman | 778138e | 2013-01-29 03:03:03 +0000 | [diff] [blame] | 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 |  | 
| Akira Hatanaka | 6fdcb3c | 2017-04-29 00:23:11 +0000 | [diff] [blame] | 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 |  | 
| Akira Hatanaka | 73ceb50 | 2018-01-19 23:51:13 +0000 | [diff] [blame] | 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 |  | 
| Michael Gottesman | 08904e3 | 2013-01-28 03:28:38 +0000 | [diff] [blame] | 104 | } // end namespace objcarc | 
|  | 105 | } // end namespace llvm | 
|  | 106 |  | 
| Benjamin Kramer | a7c40ef | 2014-08-13 16:26:38 +0000 | [diff] [blame] | 107 | #endif |