diff options
Diffstat (limited to 'llvm/lib/Transforms/ObjCARC/ObjCARC.h')
| -rw-r--r-- | llvm/lib/Transforms/ObjCARC/ObjCARC.h | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARC.h b/llvm/lib/Transforms/ObjCARC/ObjCARC.h new file mode 100644 index 000000000000..d465630800b9 --- /dev/null +++ b/llvm/lib/Transforms/ObjCARC/ObjCARC.h @@ -0,0 +1,107 @@ +//===- ObjCARC.h - ObjC ARC Optimization --------------*- C++ -*-----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file defines common definitions/declarations used by the ObjC ARC +/// Optimizer. ARC stands for Automatic Reference Counting and is a system for +/// managing reference counts for objects in Objective C. +/// +/// WARNING: This file knows about certain library functions. It recognizes them +/// by name, and hardwires knowledge of their semantics. +/// +/// WARNING: This file knows about how certain Objective-C library functions are +/// used. Naive LLVM IR transformations which would otherwise be +/// behavior-preserving may break these assumptions. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H +#define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H + +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/ObjCARCAnalysisUtils.h" +#include "llvm/Analysis/ObjCARCInstKind.h" +#include "llvm/Analysis/Passes.h" +#include "llvm/Transforms/Utils/Local.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/ObjCARC.h" + +namespace llvm { +class raw_ostream; +} + +namespace llvm { +namespace objcarc { + +/// Erase the given instruction. +/// +/// Many ObjC calls return their argument verbatim, +/// so if it's such a call and the return value has users, replace them with the +/// argument value. +/// +static inline void EraseInstruction(Instruction *CI) { + Value *OldArg = cast<CallInst>(CI)->getArgOperand(0); + + bool Unused = CI->use_empty(); + + if (!Unused) { + // Replace the return value with the argument. + assert((IsForwarding(GetBasicARCInstKind(CI)) || + (IsNoopOnNull(GetBasicARCInstKind(CI)) && + IsNullOrUndef(OldArg->stripPointerCasts()))) && + "Can't delete non-forwarding instruction with users!"); + CI->replaceAllUsesWith(OldArg); + } + + CI->eraseFromParent(); + + if (Unused) + RecursivelyDeleteTriviallyDeadInstructions(OldArg); +} + +/// If Inst is a ReturnRV and its operand is a call or invoke, return the +/// operand. Otherwise return null. +static inline const Instruction *getreturnRVOperand(const Instruction &Inst, + ARCInstKind Class) { + if (Class != ARCInstKind::RetainRV) + return nullptr; + + const auto *Opnd = Inst.getOperand(0)->stripPointerCasts(); + if (const auto *C = dyn_cast<CallInst>(Opnd)) + return C; + return dyn_cast<InvokeInst>(Opnd); +} + +/// Return the list of PHI nodes that are equivalent to PN. +template<class PHINodeTy, class VectorTy> +void getEquivalentPHIs(PHINodeTy &PN, VectorTy &PHIList) { + auto *BB = PN.getParent(); + for (auto &P : BB->phis()) { + if (&P == &PN) // Do not add PN to the list. + continue; + unsigned I = 0, E = PN.getNumIncomingValues(); + for (; I < E; ++I) { + auto *BB = PN.getIncomingBlock(I); + auto *PNOpnd = PN.getIncomingValue(I)->stripPointerCasts(); + auto *POpnd = P.getIncomingValueForBlock(BB)->stripPointerCasts(); + if (PNOpnd != POpnd) + break; + } + if (I == E) + PHIList.push_back(&P); + } +} + +} // end namespace objcarc +} // end namespace llvm + +#endif |
