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  | 
